improved PHP parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / NamingConventions.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.core;
12
13 import net.sourceforge.phpdt.core.compiler.CharOperation;
14 import net.sourceforge.phpdt.internal.codeassist.impl.AssistOptions;
15 import net.sourceforge.phpdt.internal.core.INamingRequestor;
16 import net.sourceforge.phpdt.internal.core.InternalNamingConventions;
17
18
19 /**
20  * Provides methods for computing Java-specific names.
21  * <p>
22  * The behavior of the methods is dependent of several JavaCore options.
23  * <p>
24  * The possible options are :
25  * <ul>
26  * <li>CODEASSIST_FIELD_PREFIXES : Define the Prefixes for Field Name.</li>
27  * <li>CODEASSIST_STATIC_FIELD_PREFIXES : Define the Prefixes for Static Field Name.</li>
28  * <li>CODEASSIST_LOCAL_PREFIXES : Define the Prefixes for Local Variable Name.</li>
29  * <li>CODEASSIST_ARGUMENT_PREFIXES : Define the Prefixes for Argument Name.</li>
30  * <li>CODEASSIST_FIELD_SUFFIXES : Define the Suffixes for Field Name.</li>
31  * <li>CODEASSIST_STATIC_FIELD_SUFFIXES : Define the Suffixes for Static Field Name.</li>
32  * <li>CODEASSIST_LOCAL_SUFFIXES : Define the Suffixes for Local Variable Name.</li>
33  * <li>CODEASSIST_ARGUMENT_SUFFIXES : Define the Suffixes for Argument Name.</li>
34  * </ul>
35  * </p>
36  * <p>
37  * For a complete description of the configurable options, see <code>getDefaultOptions</code>.
38  * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
39  * </p>
40  * <p>
41  * This class provides static methods and constants only; it is not intended to be
42  * instantiated or subclassed by clients.
43  * </p>
44  * 
45  * @see JavaCore#setOptions(java.util.Hashtable)
46  * @see JavaCore#getDefaultOptions()
47  * @since 2.1
48  */
49 public final class NamingConventions {
50         private static final char[] GETTER_BOOL_NAME = "is".toCharArray(); //$NON-NLS-1$
51         private static final char[] GETTER_NAME = "get".toCharArray(); //$NON-NLS-1$
52         private static final char[] SETTER_NAME = "set".toCharArray(); //$NON-NLS-1$
53         
54         private static class NamingRequestor implements INamingRequestor {
55                 private final static int SIZE = 10;
56                 
57                 // for acceptNameWithPrefixAndSuffix
58                 private char[][] firstPrefixAndFirstSuffixResults = new char[SIZE][];
59                 private int firstPrefixAndFirstSuffixResultsCount = 0;
60                 private char[][] firstPrefixAndSuffixResults = new char[SIZE][];
61                 private int firstPrefixAndSuffixResultsCount = 0;
62                 private char[][] prefixAndFirstSuffixResults = new char[SIZE][];
63                 private int prefixAndFirstSuffixResultsCount = 0;
64                 private char[][] prefixAndSuffixResults = new char[SIZE][];
65                 private int prefixAndSuffixResultsCount = 0;
66                 
67                 // for acceptNameWithPrefix
68                 private char[][] firstPrefixResults = new char[SIZE][];
69                 private int firstPrefixResultsCount = 0;
70                 private char[][] prefixResults = new char[SIZE][];
71                 private int prefixResultsCount = 0;
72                 
73                 // for acceptNameWithSuffix
74                 private char[][] firstSuffixResults = new char[SIZE][];
75                 private int firstSuffixResultsCount = 0;
76                 private char[][] suffixResults = new char[SIZE][];
77                 private int suffixResultsCount = 0;
78                 
79                 // for acceptNameWithoutPrefixAndSuffix
80                 private char[][] otherResults = new char[SIZE][];
81                 private int otherResultsCount = 0;
82                 public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix) {
83                         if(isFirstPrefix && isFirstSuffix) {
84                                 int length = this.firstPrefixAndFirstSuffixResults.length;
85                                 if(length == this.firstPrefixAndFirstSuffixResultsCount) {
86                                         System.arraycopy(
87                                                 this.firstPrefixAndFirstSuffixResults,
88                                                 0,
89                                                 this.firstPrefixAndFirstSuffixResults = new char[length * 2][],
90                                                 0,
91                                                 length);
92                                 }
93                                 this.firstPrefixAndFirstSuffixResults[this.firstPrefixAndFirstSuffixResultsCount++] = name;                     
94                         } else if (isFirstPrefix) {
95                                 int length = this.firstPrefixAndSuffixResults.length;
96                                 if(length == this.firstPrefixAndSuffixResultsCount) {
97                                         System.arraycopy(
98                                                 this.firstPrefixAndSuffixResults,
99                                                 0,
100                                                 this.firstPrefixAndSuffixResults = new char[length * 2][],
101                                                 0,
102                                                 length);
103                                 }
104                                 this.firstPrefixAndSuffixResults[this.firstPrefixAndSuffixResultsCount++] = name;
105                         } else if(isFirstSuffix) {
106                                 int length = this.prefixAndFirstSuffixResults.length;
107                                 if(length == this.prefixAndFirstSuffixResultsCount) {
108                                         System.arraycopy(
109                                                 this.prefixAndFirstSuffixResults,
110                                                 0,
111                                                 this.prefixAndFirstSuffixResults = new char[length * 2][],
112                                                 0,
113                                                 length);
114                                 }
115                                 this.prefixAndFirstSuffixResults[this.prefixAndFirstSuffixResultsCount++] = name;
116                         } else {
117                                 int length = this.prefixAndSuffixResults.length;
118                                 if(length == this.prefixAndSuffixResultsCount) {
119                                         System.arraycopy(
120                                                 this.prefixAndSuffixResults,
121                                                 0,
122                                                 this.prefixAndSuffixResults = new char[length * 2][],
123                                                 0,
124                                                 length);
125                                 }
126                                 this.prefixAndSuffixResults[this.prefixAndSuffixResultsCount++] = name;
127                         }
128                 }
129
130                 public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix) {
131                         if(isFirstPrefix) {
132                                 int length = this.firstPrefixResults.length;
133                                 if(length == this.firstPrefixResultsCount) {
134                                         System.arraycopy(
135                                                 this.firstPrefixResults,
136                                                 0,
137                                                 this.firstPrefixResults = new char[length * 2][],
138                                                 0,
139                                                 length);
140                                 }
141                                 this.firstPrefixResults[this.firstPrefixResultsCount++] = name;
142                         } else{
143                                 int length = this.prefixResults.length;
144                                 if(length == this.prefixResultsCount) {
145                                         System.arraycopy(
146                                                 this.prefixResults,
147                                                 0,
148                                                 this.prefixResults = new char[length * 2][],
149                                                 0,
150                                                 length);
151                                 }
152                                 this.prefixResults[this.prefixResultsCount++] = name;
153                         }
154                 }
155
156                 public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix) {
157                         if(isFirstSuffix) {
158                                 int length = this.firstSuffixResults.length;
159                                 if(length == this.firstSuffixResultsCount) {
160                                         System.arraycopy(
161                                                 this.firstSuffixResults,
162                                                 0,
163                                                 this.firstSuffixResults = new char[length * 2][],
164                                                 0,
165                                                 length);
166                                 }
167                                 this.firstSuffixResults[this.firstSuffixResultsCount++] = name;
168                         } else {
169                                 int length = this.suffixResults.length;
170                                 if(length == this.suffixResultsCount) {
171                                         System.arraycopy(
172                                                 this.suffixResults,
173                                                 0,
174                                                 this.suffixResults = new char[length * 2][],
175                                                 0,
176                                                 length);
177                                 }
178                                 this.suffixResults[this.suffixResultsCount++] = name;
179                         }
180                 }
181
182                 public void acceptNameWithoutPrefixAndSuffix(char[] name) {
183                         int length = this.otherResults.length;
184                         if(length == this.otherResultsCount) {
185                                 System.arraycopy(
186                                         this.otherResults,
187                                         0,
188                                         this.otherResults = new char[length * 2][],
189                                         0,
190                                         length);
191                         }
192                         this.otherResults[this.otherResultsCount++] = name;
193                 }
194                 public char[][] getResults(){
195                         int count = 
196                                 this.firstPrefixAndFirstSuffixResultsCount
197                                 + this.firstPrefixAndSuffixResultsCount
198                                 + this.prefixAndFirstSuffixResultsCount
199                                 + this.prefixAndSuffixResultsCount
200                                 + this.firstPrefixResultsCount
201                                 + this.prefixResultsCount
202                                 + this.firstSuffixResultsCount
203                                 + this.suffixResultsCount
204                                 + this.otherResultsCount;
205                                 
206                         char[][] results = new char[count][];
207                         
208                         int index = 0;
209                         System.arraycopy(this.firstPrefixAndFirstSuffixResults, 0, results, index, this.firstPrefixAndFirstSuffixResultsCount);
210                         index += this.firstPrefixAndFirstSuffixResultsCount;
211                         System.arraycopy(this.firstPrefixAndSuffixResults, 0, results, index, this.firstPrefixAndSuffixResultsCount);
212                         index += this.firstPrefixAndSuffixResultsCount;
213                         System.arraycopy(this.prefixAndFirstSuffixResults, 0, results, index, this.prefixAndFirstSuffixResultsCount);
214                         index += this.prefixAndFirstSuffixResultsCount;         
215                         System.arraycopy(this.prefixAndSuffixResults, 0, results, index, this.prefixAndSuffixResultsCount);
216                         index += this.prefixAndSuffixResultsCount;
217                         System.arraycopy(this.firstPrefixResults, 0, results, index, this.firstPrefixResultsCount);
218                         index += this.firstPrefixResultsCount;
219                         System.arraycopy(this.prefixResults, 0, results, index, this.prefixResultsCount);
220                         index += this.prefixResultsCount;
221                         System.arraycopy(this.firstSuffixResults, 0, results, index, this.firstSuffixResultsCount);
222                         index += this.firstSuffixResultsCount;
223                         System.arraycopy(this.suffixResults, 0, results, index, this.suffixResultsCount);
224                         index += this.suffixResultsCount;
225                         System.arraycopy(this.otherResults, 0, results, index, this.otherResultsCount);
226                         
227                         return results;
228                 }
229         }
230
231         
232         private NamingConventions() {
233                 // Not instantiable
234         }
235
236         private static char[] removePrefixAndSuffix(char[] name, char[][] prefixes, char[][] suffixes) {
237                 // remove longer prefix
238                 char[] withoutPrefixName = name;
239                 if (prefixes != null) {
240                         int bestLength = 0;
241                         for (int i= 0; i < prefixes.length; i++) {
242                                 char[] prefix = prefixes[i];
243                                 if (CharOperation.prefixEquals(prefix, name)) {
244                                         int currLen = prefix.length;
245                                         boolean lastCharIsLetter = Character.isLetter(prefix[currLen - 1]);
246                                         if(!lastCharIsLetter || (lastCharIsLetter && name.length > currLen && Character.isUpperCase(name[currLen]))) {
247                                                 if (bestLength < currLen && name.length != currLen) {
248                                                         withoutPrefixName = CharOperation.subarray(name, currLen, name.length);
249                                                         bestLength = currLen;
250                                                 }
251                                         }
252                                 }
253                         }
254                 }
255                 
256                 // remove longer suffix
257                 char[] withoutSuffixName = withoutPrefixName;
258                 if(suffixes != null) {
259                         int bestLength = 0;
260                         for (int i = 0; i < suffixes.length; i++) {
261                                 char[] suffix = suffixes[i];
262                                 if(CharOperation.endsWith(withoutPrefixName, suffix)) {
263                                         int currLen = suffix.length;
264                                         if(bestLength < currLen && withoutPrefixName.length != currLen) {
265                                                 withoutSuffixName = CharOperation.subarray(withoutPrefixName, 0, withoutPrefixName.length - currLen);
266                                                 bestLength = currLen;
267                                         }
268                                 }
269                         }
270                 }
271                 
272                 withoutSuffixName[0] = Character.toLowerCase(withoutSuffixName[0]);
273                 return withoutSuffixName;
274         }
275
276         /**
277          * Remove prefix and suffix from an argument name.
278          * <p>
279          * If argument name prefix is <code>pre</code> and argument name suffix is <code>suf</code>
280          * then for an argument named <code>preArgsuf</code> the result of this method is <code>arg</code>.
281          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
282          * name <code>preArgsuf</code>.
283          * </p>
284          * <p>
285          * This method is affected by the following JavaCore options : CODEASSIST_ARGUMENT_PREFIXES and
286          * CODEASSIST_ARGUMENT_SUFFIXES.
287          * </p>
288          * <p>
289          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
290          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
291          * </p>
292          * 
293          * @param javaProject project which contains the argument.
294          * @param argumentName argument's name.
295          * @return char[] the name without prefix and suffix.
296          * @see JavaCore#setOptions(java.util.Hashtable)
297          * @see JavaCore#getDefaultOptions()
298          */
299         public static char[] removePrefixAndSuffixForArgumentName(IJavaProject javaProject, char[] argumentName) {
300                 AssistOptions assistOptions = new AssistOptions(javaProject.getOptions(true));
301                 return  removePrefixAndSuffix(
302                         argumentName,
303                         assistOptions.argumentPrefixes,
304                         assistOptions.argumentSuffixes);
305         }
306         
307         /**
308          * Remove prefix and suffix from an argument name.
309          * <p>
310          * If argument name prefix is <code>pre</code> and argument name suffix is <code>suf</code>
311          * then for an argument named <code>preArgsuf</code> the result of this method is <code>arg</code>.
312          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
313          * name <code>preArgsuf</code>.
314          * </p>
315          * <p>
316          * This method is affected by the following JavaCore options : CODEASSIST_ARGUMENT_PREFIXES and
317          * CODEASSIST_ARGUMENT_SUFFIXES.
318          * </p>
319          * <p>
320          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
321          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
322          * </p>
323          * 
324          * @param javaProject project which contains the argument.
325          * @param argumentName argument's name.
326          * @return char[] the name without prefix and suffix.
327          * @see JavaCore#setOptions(java.util.Hashtable)
328          * @see JavaCore#getDefaultOptions()
329          */
330         public static String removePrefixAndSuffixForArgumentName(IJavaProject javaProject, String argumentName) {
331                 return String.valueOf(removePrefixAndSuffixForArgumentName(javaProject, argumentName.toCharArray()));
332         }
333
334         /**
335          * Remove prefix and suffix from a field name.
336          * <p>
337          * If field name prefix is <code>pre</code> and field name suffix is <code>suf</code>
338          * then for a field named <code>preFieldsuf</code> the result of this method is <code>field</code>.
339          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
340          * name <code>preFieldsuf</code>.
341          * </p>
342          * <p>
343          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
344          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
345          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
346          * </p>
347          * <p>
348          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
349          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
350          * </p>
351          * 
352          * @param javaProject project which contains the field.
353          * @param fieldName field's name.
354          * @param modifiers field's modifiers as defined by the class
355          * <code>Flags</code>.
356          * @return char[] the name without prefix and suffix.
357          * @see Flags
358          * @see JavaCore#setOptions(java.util.Hashtable)
359          * @see JavaCore#getDefaultOptions()
360          */
361         public static char[] removePrefixAndSuffixForFieldName(IJavaProject javaProject, char[] fieldName, int modifiers) {
362                 boolean isStatic = Flags.isStatic(modifiers);
363                 AssistOptions assistOptions = new AssistOptions(javaProject.getOptions(true));
364                 return  removePrefixAndSuffix(
365                         fieldName,
366                         isStatic ? assistOptions.staticFieldPrefixes : assistOptions.fieldPrefixes,
367                         isStatic ? assistOptions.staticFieldSuffixes : assistOptions.fieldSuffixes);
368         }
369
370         /**
371          * Remove prefix and suffix from a field name.
372          * <p>
373          * If field name prefix is <code>pre</code> and field name suffix is <code>suf</code>
374          * then for a field named <code>preFieldsuf</code> the result of this method is <code>field</code>.
375          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
376          * name <code>preFieldsuf</code>.
377          * </p>
378          * <p>
379          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
380          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
381          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
382          * </p>
383          * <p>
384          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
385          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
386          * </p>
387          * 
388          * @param javaProject project which contains the field.
389          * @param fieldName field's name.
390          * @param modifiers field's modifiers as defined by the class
391          * <code>Flags</code>.
392          * @return char[] the name without prefix and suffix.
393          * @see Flags
394          * @see JavaCore#setOptions(java.util.Hashtable)
395          * @see JavaCore#getDefaultOptions()
396          */
397         public static String removePrefixAndSuffixForFieldName(IJavaProject javaProject, String fieldName, int modifiers) {
398                 return String.valueOf(removePrefixAndSuffixForFieldName(javaProject, fieldName.toCharArray(), modifiers));
399         }
400         /**
401          * Remove prefix and suffix from a local variable name.
402          * <p>
403          * If local variable name prefix is <code>pre</code> and local variable name suffix is <code>suf</code>
404          * then for a local variable named <code>preLocalsuf</code> the result of this method is <code>local</code>.
405          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
406          * name <code>preLocalsuf</code>.
407          * </p>
408          * <p>
409          * This method is affected by the following JavaCore options : CODEASSIST_LOCAL_PREFIXES and 
410          * CODEASSIST_LOCAL_SUFFIXES.
411          * </p>
412          * <p>
413          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
414          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
415          * </p>
416          * 
417          * @param javaProject project which contains the variable.
418          * @param localName variable's name.
419          * @return char[] the name without prefix and suffix.
420          * @see JavaCore#setOptions(java.util.Hashtable)
421          * @see JavaCore#getDefaultOptions()
422          */
423         public static char[] removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, char[] localName) {
424                 AssistOptions assistOptions = new AssistOptions(javaProject.getOptions(true));
425                 return  removePrefixAndSuffix(
426                         localName,
427                         assistOptions.argumentPrefixes,
428                         assistOptions.argumentSuffixes);
429         }
430         
431         /**
432          * Remove prefix and suffix from a local variable name.
433          * <p>
434          * If local variable name prefix is <code>pre</code> and local variable name suffix is <code>suf</code>
435          * then for a local variable named <code>preLocalsuf</code> the result of this method is <code>local</code>.
436          * If there is no prefix or suffix defined in JavaCore options the result is the unchanged
437          * name <code>preLocalsuf</code>.
438          * </p>
439          * <p>
440          * This method is affected by the following JavaCore options : CODEASSIST_LOCAL_PREFIXES and 
441          * CODEASSIST_LOCAL_SUFFIXES.
442          * </p>
443          * <p>
444          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
445          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
446          * </p>
447          * 
448          * @param javaProject project which contains the variable.
449          * @param localName variable's name.
450          * @return char[] the name without prefix and suffix.
451          * @see JavaCore#setOptions(java.util.Hashtable)
452          * @see JavaCore#getDefaultOptions()
453          */
454         public static String removePrefixAndSuffixForLocalVariableName(IJavaProject javaProject, String localName) {
455                 return String.valueOf(removePrefixAndSuffixForLocalVariableName(javaProject, localName.toCharArray()));
456         }
457
458         /**
459          * Suggest names for an argument. The name is computed from argument's type
460          * and possible prefixes or suffixes are added.
461          * <p>
462          * If the type of the argument is <code>TypeName</code>, the prefix for argument is <code>pre</code>
463          * and the suffix for argument is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
464          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
465          * and <code>name</code>.
466          * </p>
467          * <p>
468          * This method is affected by the following JavaCore options : CODEASSIST_ARGUMENT_PREFIXES and 
469          * CODEASSIST_ARGUMENT_SUFFIXES.
470          * </p>
471          * <p>
472          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
473          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
474          * </p>
475          * 
476          * @param javaProject project which contains the argument.
477          * @param packageName package of the argument's type.
478          * @param qualifiedTypeName argument's type.
479          * @param dim argument's dimension (0 if the argument is not an array).
480          * @param excludedNames a list of names which cannot be suggested (already used names).
481          *         Can be <code>null</code> if there is no excluded names.
482          * @return char[][] an array of names.
483          * @see JavaCore#setOptions(java.util.Hashtable)
484          * @see JavaCore#getDefaultOptions()
485          */
486         public static char[][] suggestArgumentNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {
487                 NamingRequestor requestor = new NamingRequestor();
488                 InternalNamingConventions.suggestArgumentNames(
489                         javaProject,
490                         packageName,
491                         qualifiedTypeName,
492                         dim,
493                         excludedNames,
494                         requestor);
495
496                 return requestor.getResults();
497         }
498         
499         /**
500          * Suggest names for an argument. The name is computed from argument's type
501          * and possible prefixes or suffixes are added.
502          * <p>
503          * If the type of the argument is <code>TypeName</code>, the prefix for argument is <code>pre</code>
504          * and the suffix for argument is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
505          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
506          * and <code>name</code>.
507          * </p>
508          * <p>
509          * This method is affected by the following JavaCore options : CODEASSIST_ARGUMENT_PREFIXES and 
510          * CODEASSIST_ARGUMENT_SUFFIXES.
511          * </p>
512          * <p>
513          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
514          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
515          * </p>
516          * 
517          * @param javaProject project which contains the argument.
518          * @param packageName package of the argument's type.
519          * @param qualifiedTypeName argument's type.
520          * @param dim argument's dimension (0 if the argument is not an array).
521          * @param excludedNames a list of names which cannot be suggested (already used names).
522          *         Can be <code>null</code> if there is no excluded names.
523          * @return char[][] an array of names.
524          * @see JavaCore#setOptions(java.util.Hashtable)
525          * @see JavaCore#getDefaultOptions()
526          */
527         public static String[] suggestArgumentNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {
528                 return convertCharsToString(
529                         suggestArgumentNames(
530                                 javaProject,
531                                 packageName.toCharArray(),
532                                 qualifiedTypeName.toCharArray(),
533                                 dim,
534                                 convertStringToChars(excludedNames)));
535         }
536         /**
537          * Suggest names for a field. The name is computed from field's type
538          * and possible prefixes or suffixes are added.
539          * <p>
540          * If the type of the field is <code>TypeName</code>, the prefix for field is <code>pre</code>
541          * and the suffix for field is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
542          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
543          * and <code>name</code>.
544          * </p>
545          * <p>
546          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
547          * CODEASSIST_FIELD_SUFFIXES and for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
548          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
549          * </p>
550          * <p>
551          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
552          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
553          * </p>
554          * 
555          * @param javaProject project which contains the field.
556          * @param packageName package of the field's type.
557          * @param qualifiedTypeName field's type.
558          * @param dim field's dimension (0 if the field is not an array).
559          * @param modifiers field's modifiers as defined by the class
560          * <code>Flags</code>.
561          * @param excludedNames a list of names which cannot be suggested (already used names).
562          *         Can be <code>null</code> if there is no excluded names.
563          * @return char[][] an array of names.
564          * @see Flags
565          * @see JavaCore#setOptions(java.util.Hashtable)
566          * @see JavaCore#getDefaultOptions()
567          */
568         public static char[][] suggestFieldNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, int modifiers, char[][] excludedNames) {
569                 NamingRequestor requestor = new NamingRequestor();
570                 InternalNamingConventions.suggestFieldNames(
571                         javaProject,
572                         packageName,
573                         qualifiedTypeName,
574                         dim,
575                         modifiers,
576                         excludedNames,
577                         requestor);
578
579                 return requestor.getResults();
580         }
581         
582         /**
583          * Suggest names for a field. The name is computed from field's type
584          * and possible prefixes or suffixes are added.
585          * <p>
586          * If the type of the field is <code>TypeName</code>, the prefix for field is <code>pre</code>
587          * and the suffix for field is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
588          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
589          * and <code>name</code>.
590          * </p>
591          * <p>
592          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
593          * CODEASSIST_FIELD_SUFFIXES and for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
594          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
595          * </p>
596          * <p>
597          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
598          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
599          * </p>
600          * 
601          * @param javaProject project which contains the field.
602          * @param packageName package of the field's type.
603          * @param qualifiedTypeName field's type.
604          * @param dim field's dimension (0 if the field is not an array).
605          * @param modifiers field's modifiers as defined by the class
606          * <code>Flags</code>.
607          * @param excludedNames a list of names which cannot be suggested (already used names).
608          *         Can be <code>null</code> if there is no excluded names.
609          * @return char[][] an array of names.
610          * @see Flags
611          * @see JavaCore#setOptions(java.util.Hashtable)
612          * @see JavaCore#getDefaultOptions()
613          */
614         public static String[] suggestFieldNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, int modifiers, String[] excludedNames) {
615                 return convertCharsToString(
616                         suggestFieldNames(
617                                 javaProject,
618                                 packageName.toCharArray(),
619                                 qualifiedTypeName.toCharArray(),
620                                 dim,
621                                 modifiers,
622                                 convertStringToChars(excludedNames)));
623         }
624         
625         /**
626          * Suggest names for a local variable. The name is computed from variable's type
627          * and possible prefixes or suffixes are added.
628          * <p>
629          * If the type of the local variable is <code>TypeName</code>, the prefix for local variable is <code>pre</code>
630          * and the suffix for local variable is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
631          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
632          * and <code>name</code>.
633          * </p>
634          * <p>
635          * This method is affected by the following JavaCore options : CODEASSIST_LOCAL_PREFIXES and
636          * CODEASSIST_LOCAL_SUFFIXES.
637          * </p>
638          * <p>
639          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
640          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
641          * </p>
642          * 
643          * @param javaProject project which contains the variable.
644          * @param packageName package of the variable's type.
645          * @param qualifiedTypeName variable's type.
646          * @param dim variable's dimension (0 if the variable is not an array).
647          * @param excludedNames a list of names which cannot be suggested (already used names).
648          *         Can be <code>null</code> if there is no excluded names.
649          * @return char[][] an array of names.
650          * @see JavaCore#setOptions(java.util.Hashtable)
651          * @see JavaCore#getDefaultOptions()
652          */
653         public static char[][] suggestLocalVariableNames(IJavaProject javaProject, char[] packageName, char[] qualifiedTypeName, int dim, char[][] excludedNames) {
654                 NamingRequestor requestor = new NamingRequestor();
655                 InternalNamingConventions.suggestLocalVariableNames(
656                         javaProject,
657                         packageName,
658                         qualifiedTypeName,
659                         dim,
660                         excludedNames,
661                         requestor);
662
663                 return requestor.getResults();
664         }
665         
666         /**
667          * Suggest names for a local variable. The name is computed from variable's type
668          * and possible prefixes or suffixes are added.
669          * <p>
670          * If the type of the local variable is <code>TypeName</code>, the prefix for local variable is <code>pre</code>
671          * and the suffix for local variable is <code>suf</code> then the proposed names are <code>preTypeNamesuf</code>
672          * and <code>preNamesuf</code>. If there is no prefix or suffix the proposals are <code>typeName</code>
673          * and <code>name</code>.
674          * </p>
675          * <p>
676          * This method is affected by the following JavaCore options : CODEASSIST_LOCAL_PREFIXES and
677          * CODEASSIST_LOCAL_SUFFIXES.
678          * </p>
679          * <p>
680          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
681          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
682          * </p>
683          * 
684          * @param javaProject project which contains the variable.
685          * @param packageName package of the variable's type.
686          * @param qualifiedTypeName variable's type.
687          * @param dim variable's dimension (0 if the variable is not an array).
688          * @param excludedNames a list of names which cannot be suggested (already used names).
689          *         Can be <code>null</code> if there is no excluded names.
690          * @return char[][] an array of names.
691          * @see JavaCore#setOptions(java.util.Hashtable)
692          * @see JavaCore#getDefaultOptions()
693          */
694         public static String[] suggestLocalVariableNames(IJavaProject javaProject, String packageName, String qualifiedTypeName, int dim, String[] excludedNames) {
695                 return convertCharsToString(
696                         suggestLocalVariableNames(
697                                 javaProject,
698                                 packageName.toCharArray(),
699                                 qualifiedTypeName.toCharArray(),
700                                 dim,
701                                 convertStringToChars(excludedNames)));
702         }
703         
704         /**
705          * Suggest name for a getter method. The name is computed from field's name
706          * and possible prefixes or suffixes are removed.
707          * <p>
708          * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
709          * the suffix for field is <code>suf</code> then the prosposed name is <code>isFieldName</code> for boolean field or
710          * <code>getFieldName</code> for others. If there is no prefix and suffix the proposal is <code>isPreFieldNamesuf</code>
711          * for boolean field or <code>getPreFieldNamesuf</code> for others.
712          * </p>
713          * <p>
714          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
715          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
716          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
717          * </p>
718          * <p>
719          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
720          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
721          * </p>
722          * 
723          * @param project project which contains the field.
724          * @param fieldName field's name's.
725          * @param modifiers field's modifiers as defined by the class
726          * <code>Flags</code>.
727          * @param isBoolean <code>true</code> if the field's type is boolean
728          * @param excludedNames a list of names which cannot be suggested (already used names).
729          *         Can be <code>null</code> if there is no excluded names.
730          * @return char[] a name.
731          * @see Flags
732          * @see JavaCore#setOptions(java.util.Hashtable)
733          * @see JavaCore#getDefaultOptions()
734          */
735         public static char[] suggestGetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) {
736                 if (isBoolean) {
737                         char[] name = removePrefixAndSuffixForFieldName(project, fieldName, modifiers);
738                         int prefixLen =  GETTER_BOOL_NAME.length;
739                         if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name) 
740                                 && name.length > prefixLen && Character.isUpperCase(name[prefixLen])) {
741                                 return suggestNewName(name, excludedNames);
742                         } else {
743                                 return suggestNewName(
744                                         CharOperation.concat(GETTER_BOOL_NAME, suggestAccessorName(project, fieldName, modifiers)),
745                                         excludedNames
746                                 );
747                         }
748                 } else {
749                         return suggestNewName(
750                                 CharOperation.concat(GETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
751                                 excludedNames
752                         );
753                 }
754         }
755         
756         /**
757          * Suggest name for a getter method. The name is computed from field's name
758          * and possible prefixes or suffixes are removed.
759          * <p>
760          * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
761          * the suffix for field is <code>suf</code> then the prosposed name is <code>isFieldName</code> for boolean field or
762          * <code>getFieldName</code> for others. If there is no prefix and suffix the proposal is <code>isPreFieldNamesuf</code>
763          * for boolean field or <code>getPreFieldNamesuf</code> for others.
764          * </p>
765          * <p>
766          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
767          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
768          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
769          * </p>
770          * <p>
771          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
772          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
773          * </p>
774          * 
775          * @param project project which contains the field.
776          * @param fieldName field's name's.
777          * @param modifiers field's modifiers as defined by the class
778          * <code>Flags</code>.
779          * @param isBoolean <code>true</code> if the field's type is boolean
780          * @param excludedNames a list of names which cannot be suggested (already used names).
781          *         Can be <code>null</code> if there is no excluded names.
782          * @return char[] a name.
783          * @see Flags
784          * @see JavaCore#setOptions(java.util.Hashtable)
785          * @see JavaCore#getDefaultOptions()
786          */
787         public static String suggestGetterName(IJavaProject project, String fieldName, int modifiers, boolean isBoolean, String[] excludedNames) {
788                 return String.valueOf(
789                         suggestGetterName(
790                                 project,
791                                 fieldName.toCharArray(),
792                                 modifiers,
793                                 isBoolean,
794                                 convertStringToChars(excludedNames)));
795         }
796
797         /**
798          * Suggest name for a setter method. The name is computed from field's name
799          * and possible prefixes or suffixes are removed.
800          * <p>
801          * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
802          * the suffix for field is <code>suf</code> then the proposed name is <code>setFieldName</code>.
803          * If there is no prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
804          * </p>
805          * <p>
806          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
807          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
808          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
809          * </p>
810          * <p>
811          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
812          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
813          * </p>
814          * 
815          * @param project project which contains the field.
816          * @param fieldName field's name's.
817          * @param modifiers field's modifiers as defined by the class
818          * <code>Flags</code>.
819          * @param isBoolean <code>true</code> if the field's type is boolean
820          * @param excludedNames a list of names which cannot be suggested (already used names).
821          *         Can be <code>null</code> if there is no excluded names.
822          * @return char[] a name.
823          * @see Flags
824          * @see JavaCore#setOptions(java.util.Hashtable)
825          * @see JavaCore#getDefaultOptions()
826          */
827         public static char[] suggestSetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) {
828
829                 if (isBoolean) {
830                         char[] name = removePrefixAndSuffixForFieldName(project, fieldName, modifiers);
831                         int prefixLen =  GETTER_BOOL_NAME.length;
832                         if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name) 
833                                 && name.length > prefixLen && Character.isUpperCase(name[prefixLen])) {
834                                 name = CharOperation.subarray(name, prefixLen, name.length);
835                                 return suggestNewName(
836                                         CharOperation.concat(SETTER_NAME, suggestAccessorName(project, name, modifiers)),
837                                         excludedNames
838                                 );
839                         } else {
840                                 return suggestNewName(
841                                         CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
842                                         excludedNames
843                                 );
844                         }
845                 } else {
846                         return suggestNewName(
847                                 CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)),
848                                 excludedNames
849                         );
850                 }
851         }
852         
853         /**
854          * Suggest name for a setter method. The name is computed from field's name
855          * and possible prefixes or suffixes are removed.
856          * <p>
857          * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and
858          * the suffix for field is <code>suf</code> then the proposed name is <code>setFieldName</code>.
859          * If there is no prefix and suffix the proposal is <code>setPreFieldNamesuf</code>.
860          * </p>
861          * <p>
862          * This method is affected by the following JavaCore options : CODEASSIST_FIELD_PREFIXES, 
863          * CODEASSIST_FIELD_SUFFIXES for instance field and CODEASSIST_STATIC_FIELD_PREFIXES,
864          * CODEASSIST_STATIC_FIELD_SUFFIXES for static field.
865          * </p>
866          * <p>
867          * For a complete description of these configurable options, see <code>getDefaultOptions</code>.
868          * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>.
869          * </p>
870          * 
871          * @param project project which contains the field.
872          * @param fieldName field's name's.
873          * @param modifiers field's modifiers as defined by the class
874          * <code>Flags</code>.
875          * @param isBoolean <code>true</code> if the field's type is boolean
876          * @param excludedNames a list of names which cannot be suggested (already used names).
877          *         Can be <code>null</code> if there is no excluded names.
878          * @return char[] a name.
879          * @see Flags
880          * @see JavaCore#setOptions(java.util.Hashtable)
881          * @see JavaCore#getDefaultOptions()
882          */
883         public static String suggestSetterName(IJavaProject project, String fieldName, int modifiers, boolean isBoolean, String[] excludedNames) {
884                 return String.valueOf(
885                         suggestSetterName(
886                                 project,
887                                 fieldName.toCharArray(),
888                                 modifiers,
889                                 isBoolean,
890                                 convertStringToChars(excludedNames)));
891         }
892         
893         private static char[] suggestAccessorName(IJavaProject project, char[] fieldName, int modifiers) {
894                 char[] name = removePrefixAndSuffixForFieldName(project, fieldName, modifiers);
895                 if (name.length > 0 && Character.isLowerCase(name[0])) {
896                         name[0] = Character.toUpperCase(name[0]);
897                 }
898                 return name;
899         }
900         
901         private static char[] suggestNewName(char[] name, char[][] excludedNames){
902                 if(excludedNames == null) {
903                         return name;
904                 }
905                 
906                 char[] newName = name;
907                 int count = 2;
908                 int i = 0;
909                 while (i < excludedNames.length) {
910                         if(CharOperation.equals(newName, excludedNames[i], false)) {
911                                 newName = CharOperation.concat(name, String.valueOf(count++).toCharArray());
912                                 i = 0;
913                         } else {
914                                 i++;
915                         }
916                 }
917                 return newName;
918         }
919         
920         private static String[] convertCharsToString(char[][] c) {
921                 int length = c == null ? 0 : c.length;
922                 String[] s = new String[length];
923                 for (int i = 0; i < length; i++) {
924                         s[i] = String.valueOf(c[i]);
925                 }
926                 return s;
927         }
928         
929         private static char[][] convertStringToChars(String[] s) {
930                 int length = s == null ? 0 : s.length;
931                 char[][] c = new char[length][];
932                 for (int i = 0; i < length; i++) {
933                         if(s[i] == null) {
934                                 c[i] = CharOperation.NO_CHAR;
935                         } else {
936                                 c[i] = s[i].toCharArray();
937                         }
938                 }
939                 return c;
940         }
941 }