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