3e4ffde414ba9877e5883a785de6a0bf5764526e
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / InternalNamingConventions.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core;
12
13 import java.util.Map;
14
15 import net.sourceforge.phpdt.core.Flags;
16 import net.sourceforge.phpdt.core.IJavaProject;
17 import net.sourceforge.phpdt.core.JavaConventions;
18 import net.sourceforge.phpdt.core.compiler.CharOperation;
19 import net.sourceforge.phpdt.internal.codeassist.impl.AssistOptions;
20 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
21 import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
22
23 public class InternalNamingConventions {
24         private static final char[] DEFAULT_NAME = "name".toCharArray(); //$NON-NLS-1$
25
26         private static Scanner getNameScanner(CompilerOptions compilerOptions) {
27                 return new Scanner(false /* comment */, false /* whitespace */,
28                                 false /* nls */,
29                                 // compilerOptions.sourceLevel /*sourceLevel*/,
30                                 false, false, null /* taskTags */, null/* taskPriorities */,
31                                 false);
32
33         }
34
35         public static void suggestArgumentNames(IJavaProject javaProject,
36                         char[] packageName, char[] qualifiedTypeName, int dim,
37                         char[][] excludedNames, INamingRequestor requestor) {
38                 Map options = javaProject.getOptions(true);
39                 CompilerOptions compilerOptions = new CompilerOptions(options);
40                 AssistOptions assistOptions = new AssistOptions(options);
41
42                 suggestNames(packageName, qualifiedTypeName, dim,
43                                 assistOptions.argumentPrefixes, assistOptions.argumentSuffixes,
44                                 excludedNames, getNameScanner(compilerOptions), requestor);
45         }
46
47         public static void suggestFieldNames(IJavaProject javaProject,
48                         char[] packageName, char[] qualifiedTypeName, int dim,
49                         int modifiers, char[][] excludedNames, INamingRequestor requestor) {
50                 boolean isStatic = Flags.isStatic(modifiers);
51
52                 Map options = javaProject.getOptions(true);
53                 CompilerOptions compilerOptions = new CompilerOptions(options);
54                 AssistOptions assistOptions = new AssistOptions(options);
55
56                 suggestNames(packageName, qualifiedTypeName, dim,
57                                 isStatic ? assistOptions.staticFieldPrefixes
58                                                 : assistOptions.fieldPrefixes,
59                                 isStatic ? assistOptions.staticFieldSuffixes
60                                                 : assistOptions.fieldSuffixes, excludedNames,
61                                 getNameScanner(compilerOptions), requestor);
62         }
63
64         public static void suggestLocalVariableNames(IJavaProject javaProject,
65                         char[] packageName, char[] qualifiedTypeName, int dim,
66                         char[][] excludedNames, INamingRequestor requestor) {
67                 Map options = javaProject.getOptions(true);
68                 CompilerOptions compilerOptions = new CompilerOptions(options);
69                 AssistOptions assistOptions = new AssistOptions(options);
70
71                 suggestNames(packageName, qualifiedTypeName, dim,
72                                 assistOptions.localPrefixes, assistOptions.localSuffixes,
73                                 excludedNames, getNameScanner(compilerOptions), requestor);
74         }
75
76         private static void suggestNames(char[] packageName,
77                         char[] qualifiedTypeName, int dim, char[][] prefixes,
78                         char[][] suffixes, char[][] excludedNames, Scanner nameScanner,
79                         INamingRequestor requestor) {
80
81                 if (qualifiedTypeName == null || qualifiedTypeName.length == 0)
82                         return;
83
84                 char[] typeName = CharOperation.lastSegment(qualifiedTypeName, '.');
85
86                 if (prefixes == null || prefixes.length == 0) {
87                         prefixes = new char[1][0];
88                 } else {
89                         int length = prefixes.length;
90                         System.arraycopy(prefixes, 0, prefixes = new char[length + 1][], 0,
91                                         length);
92                         prefixes[length] = CharOperation.NO_CHAR;
93                 }
94
95                 if (suffixes == null || suffixes.length == 0) {
96                         suffixes = new char[1][0];
97                 } else {
98                         int length = suffixes.length;
99                         System.arraycopy(suffixes, 0, suffixes = new char[length + 1][], 0,
100                                         length);
101                         suffixes[length] = CharOperation.NO_CHAR;
102                 }
103
104                 char[][] tempNames = null;
105
106                 // compute variable name for base type
107                 // try{
108                 // nameScanner.setSource(typeName);
109                 // switch (nameScanner.getNextToken()) {
110                 // case TerminalTokens.TokenNameint :
111                 // case TerminalTokens.TokenNamebyte :
112                 // case TerminalTokens.TokenNameshort :
113                 // case TerminalTokens.TokenNamechar :
114                 // case TerminalTokens.TokenNamelong :
115                 // case TerminalTokens.TokenNamefloat :
116                 // case TerminalTokens.TokenNamedouble :
117                 // case TerminalTokens.TokenNameboolean :
118                 // char[] name = computeBaseTypeNames(typeName[0], excludedNames);
119                 // if(name != null) {
120                 // tempNames = new char[][]{name};
121                 // }
122                 // break;
123                 // }
124                 // } catch(InvalidInputException e){
125                 // // ignore
126                 // }
127
128                 // compute variable name for non base type
129                 if (tempNames == null) {
130                         tempNames = computeNames(typeName);
131                 }
132
133                 boolean acceptDefaultName = true;
134
135                 for (int i = 0; i < tempNames.length; i++) {
136                         char[] tempName = tempNames[i];
137                         if (dim > 0) {
138                                 int length = tempName.length;
139                                 if (tempName[length - 1] == 's') {
140                                         if (tempName.length > 1 && tempName[length - 2] == 's') {
141                                                 System.arraycopy(tempName, 0,
142                                                                 tempName = new char[length + 2], 0, length);
143                                                 tempName[length] = 'e';
144                                                 tempName[length + 1] = 's';
145                                         }
146                                 } else if (tempName[length - 1] == 'y') {
147                                         System.arraycopy(tempName, 0,
148                                                         tempName = new char[length + 2], 0, length);
149                                         tempName[length - 1] = 'i';
150                                         tempName[length] = 'e';
151                                         tempName[length + 1] = 's';
152                                 } else {
153                                         System.arraycopy(tempName, 0,
154                                                         tempName = new char[length + 1], 0, length);
155                                         tempName[length] = 's';
156                                 }
157                         }
158
159                         for (int j = 0; j < prefixes.length; j++) {
160                                 if (prefixes[j].length > 0
161                                                 && Character
162                                                                 .isLetterOrDigit(prefixes[j][prefixes[j].length - 1])) {
163                                         tempName[0] = Character.toUpperCase(tempName[0]);
164                                 } else {
165                                         tempName[0] = Character.toLowerCase(tempName[0]);
166                                 }
167                                 char[] prefixName = CharOperation.concat(prefixes[j], tempName);
168                                 for (int k = 0; k < suffixes.length; k++) {
169                                         char[] suffixName = CharOperation.concat(prefixName,
170                                                         suffixes[k]);
171                                         suffixName = excludeNames(suffixName, prefixName,
172                                                         suffixes[k], excludedNames);
173                                         if (JavaConventions.validateFieldName(
174                                                         new String(suffixName)).isOK()) {
175                                                 acceptName(suffixName, prefixes[j], suffixes[k],
176                                                                 j == 0, k == 0, requestor);
177                                                 acceptDefaultName = false;
178                                         } else {
179                                                 suffixName = CharOperation.concat(prefixName, String
180                                                                 .valueOf(1).toCharArray(), suffixes[k]);
181                                                 suffixName = excludeNames(suffixName, prefixName,
182                                                                 suffixes[k], excludedNames);
183                                                 if (JavaConventions.validateFieldName(
184                                                                 new String(suffixName)).isOK()) {
185                                                         acceptName(suffixName, prefixes[j], suffixes[k],
186                                                                         j == 0, k == 0, requestor);
187                                                         acceptDefaultName = false;
188                                                 }
189                                         }
190                                 }
191
192                         }
193                 }
194                 // if no names were found
195                 if (acceptDefaultName) {
196                         char[] name = excludeNames(DEFAULT_NAME, DEFAULT_NAME,
197                                         CharOperation.NO_CHAR, excludedNames);
198                         requestor.acceptNameWithoutPrefixAndSuffix(name);
199                 }
200         }
201
202         private static void acceptName(char[] name, char[] prefix, char[] suffix,
203                         boolean isFirstPrefix, boolean isFirstSuffix,
204                         INamingRequestor requestor) {
205                 if (prefix.length > 0 && suffix.length > 0) {
206                         requestor.acceptNameWithPrefixAndSuffix(name, isFirstPrefix,
207                                         isFirstSuffix);
208                 } else if (prefix.length > 0) {
209                         requestor.acceptNameWithPrefix(name, isFirstPrefix);
210                 } else if (suffix.length > 0) {
211                         requestor.acceptNameWithSuffix(name, isFirstSuffix);
212                 } else {
213                         requestor.acceptNameWithoutPrefixAndSuffix(name);
214                 }
215         }
216
217         private static char[] computeBaseTypeNames(char firstName,
218                         char[][] excludedNames) {
219                 char[] name = new char[] { firstName };
220
221                 for (int i = 0; i < excludedNames.length; i++) {
222                         if (CharOperation.equals(name, excludedNames[i], false)) {
223                                 name[0]++;
224                                 if (name[0] > 'z')
225                                         name[0] = 'a';
226                                 if (name[0] == firstName)
227                                         return null;
228                                 i = 0;
229                         }
230                 }
231
232                 return name;
233         }
234
235         private static char[][] computeNames(char[] sourceName) {
236                 char[][] names = new char[5][];
237                 int nameCount = 0;
238                 boolean previousIsUpperCase = false;
239                 boolean previousIsLetter = true;
240                 for (int i = sourceName.length - 1; i >= 0; i--) {
241                         boolean isUpperCase = Character.isUpperCase(sourceName[i]);
242                         boolean isLetter = Character.isLetter(sourceName[i]);
243                         if (isUpperCase && !previousIsUpperCase && previousIsLetter) {
244                                 char[] name = CharOperation.subarray(sourceName, i,
245                                                 sourceName.length);
246                                 if (name.length > 1) {
247                                         if (nameCount == names.length) {
248                                                 System
249                                                                 .arraycopy(names, 0,
250                                                                                 names = new char[nameCount * 2][], 0,
251                                                                                 nameCount);
252                                         }
253                                         name[0] = Character.toLowerCase(name[0]);
254                                         names[nameCount++] = name;
255                                 }
256                         }
257                         previousIsUpperCase = isUpperCase;
258                         previousIsLetter = isLetter;
259                 }
260                 if (nameCount == 0) {
261                         names[nameCount++] = CharOperation.toLowerCase(sourceName);
262                 }
263                 System.arraycopy(names, 0, names = new char[nameCount][], 0, nameCount);
264                 return names;
265         }
266
267         private static char[] excludeNames(char[] suffixName, char[] prefixName,
268                         char[] suffix, char[][] excludedNames) {
269                 int count = 2;
270                 int m = 0;
271                 while (m < excludedNames.length) {
272                         if (CharOperation.equals(suffixName, excludedNames[m], false)) {
273                                 suffixName = CharOperation.concat(prefixName, String.valueOf(
274                                                 count++).toCharArray(), suffix);
275                                 m = 0;
276                         } else {
277                                 m++;
278                         }
279                 }
280                 return suffixName;
281         }
282 }