KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > search > indexing > SourceIndexerRequestor


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.core.search.indexing;
12
13 import org.eclipse.jdt.core.Signature;
14 import org.eclipse.jdt.core.compiler.*;
15 import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
16 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
17 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
18 import org.eclipse.jdt.internal.core.search.processing.JobManager;
19
20 /**
21  * This class is used by the JavaParserIndexer. When parsing the java file, the requestor
22  * recognises the java elements (methods, fields, ...) and add them to an index.
23  */

24 public class SourceIndexerRequestor implements ISourceElementRequestor, IIndexConstants {
25     SourceIndexer indexer;
26
27     char[] packageName = CharOperation.NO_CHAR;
28     char[][] enclosingTypeNames = new char[5][];
29     int depth = 0;
30     int methodDepth = 0;
31     
32 public SourceIndexerRequestor(SourceIndexer indexer) {
33     this.indexer = indexer;
34 }
35 /**
36  * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
37  */

38 public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {
39     if (CharOperation.indexOf(Signature.C_GENERIC_START, typeName) > 0) {
40         typeName = Signature.toCharArray(Signature.getTypeErasure(Signature.createTypeSignature(typeName, false)).toCharArray());
41     }
42     this.indexer.addConstructorReference(typeName, argCount);
43     int lastDot = CharOperation.lastIndexOf('.', typeName);
44     if (lastDot != -1) {
45         char[][] qualification = CharOperation.splitOn('.', CharOperation.subarray(typeName, 0, lastDot));
46         for (int i = 0, length = qualification.length; i < length; i++) {
47             this.indexer.addNameReference(qualification[i]);
48         }
49     }
50 }
51 /**
52  * @see ISourceElementRequestor#acceptFieldReference(char[], int)
53  */

54 public void acceptFieldReference(char[] fieldName, int sourcePosition) {
55     this.indexer.addFieldReference(fieldName);
56 }
57 /**
58  * @see ISourceElementRequestor#acceptImport(int, int, char[][], boolean, int)
59  */

60 public void acceptImport(int declarationStart, int declarationEnd, char[][] tokens, boolean onDemand, int modifiers) {
61     // imports have already been reported while creating the ImportRef node (see SourceElementParser#comsume*ImportDeclarationName() methods)
62
}
63 /**
64  * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
65  */

66 public void acceptLineSeparatorPositions(int[] positions) {
67     // implements interface method
68
}
69 /**
70  * @see ISourceElementRequestor#acceptMethodReference(char[], int, int)
71  */

72 public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) {
73     this.indexer.addMethodReference(methodName, argCount);
74 }
75 /**
76  * @see ISourceElementRequestor#acceptPackage(int, int, char[])
77  */

78 public void acceptPackage(int declarationStart, int declarationEnd, char[] name) {
79     this.packageName = name;
80 }
81 /**
82  * @see ISourceElementRequestor#acceptProblem(CategorizedProblem)
83  */

84 public void acceptProblem(CategorizedProblem problem) {
85     // implements interface method
86
}
87 /**
88  * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int)
89  */

90 public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
91     int length = typeName.length;
92     for (int i = 0; i < length - 1; i++)
93         acceptUnknownReference(typeName[i], 0); // ?
94
acceptTypeReference(typeName[length - 1], 0);
95 }
96 /**
97  * @see ISourceElementRequestor#acceptTypeReference(char[], int)
98  */

99 public void acceptTypeReference(char[] simpleTypeName, int sourcePosition) {
100     this.indexer.addTypeReference(simpleTypeName);
101 }
102 /**
103  * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int)
104  */

105 public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) {
106     for (int i = 0; i < name.length; i++) {
107         acceptUnknownReference(name[i], 0);
108     }
109 }
110 /**
111  * @see ISourceElementRequestor#acceptUnknownReference(char[], int)
112  */

113 public void acceptUnknownReference(char[] name, int sourcePosition) {
114     this.indexer.addNameReference(name);
115 }
116 /*
117  * Rebuild the proper qualification for the current source type:
118  *
119  * java.lang.Object ---> null
120  * java.util.Hashtable$Entry --> [Hashtable]
121  * x.y.A$B$C --> [A, B]
122  */

123 public char[][] enclosingTypeNames(){
124
125     if (depth == 0) return null;
126
127     char[][] qualification = new char[this.depth][];
128     System.arraycopy(this.enclosingTypeNames, 0, qualification, 0, this.depth);
129     return qualification;
130 }
131 private void enterAnnotationType(TypeInfo typeInfo) {
132     char[][] typeNames;
133     if (this.methodDepth > 0) {
134         typeNames = ONE_ZERO_CHAR;
135     } else {
136         typeNames = this.enclosingTypeNames();
137     }
138     this.indexer.addAnnotationTypeDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, typeInfo.secondary);
139     this.pushTypeName(typeInfo.name);
140 }
141
142 private void enterClass(TypeInfo typeInfo) {
143
144     // eliminate possible qualifications, given they need to be fully resolved again
145
if (typeInfo.superclass != null) {
146         typeInfo.superclass = getSimpleName(typeInfo.superclass);
147         
148         // add implicit constructor reference to default constructor
149
this.indexer.addConstructorReference(typeInfo.superclass, 0);
150     }
151     if (typeInfo.superinterfaces != null){
152         for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++) {
153             typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
154         }
155     }
156     char[][] typeNames;
157     if (this.methodDepth > 0) {
158         // set specific ['0'] value for local and anonymous to be able to filter them
159
typeNames = ONE_ZERO_CHAR;
160     } else {
161         typeNames = this.enclosingTypeNames();
162     }
163     char[][] typeParameterSignatures = null;
164     if (typeInfo.typeParameters != null) {
165         int typeParametersLength = typeInfo.typeParameters.length;
166         typeParameterSignatures = new char[typeParametersLength][];
167         for (int i = 0; i < typeParametersLength; i++) {
168             ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
169             typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds == null ? CharOperation.NO_CHAR_CHAR : typeParameterInfo.bounds);
170         }
171     }
172     this.indexer.addClassDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superclass, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
173     this.pushTypeName(typeInfo.name);
174 }
175 /**
176  * @see ISourceElementRequestor#enterCompilationUnit()
177  */

178 public void enterCompilationUnit() {
179     // implements interface method
180
}
181 /**
182  * @see ISourceElementRequestor#enterConstructor(MethodInfo)
183  */

184 public void enterConstructor(MethodInfo methodInfo) {
185     this.indexer.addConstructorDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.exceptionTypes);
186     this.methodDepth++;
187 }
188 private void enterEnum(TypeInfo typeInfo) {
189     // eliminate possible qualifications, given they need to be fully resolved again
190
if (typeInfo.superinterfaces != null){
191         for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
192             typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
193         }
194     }
195     char[][] typeNames;
196     if (this.methodDepth > 0) {
197         typeNames = ONE_ZERO_CHAR;
198     } else {
199         typeNames = this.enclosingTypeNames();
200     }
201     char[] superclass = typeInfo.superclass == null ? CharOperation.concatWith(TypeConstants.JAVA_LANG_ENUM, '.'): typeInfo.superclass;
202     this.indexer.addEnumDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, superclass, typeInfo.superinterfaces, typeInfo.secondary);
203     this.pushTypeName(typeInfo.name);
204 }
205 /**
206  * @see ISourceElementRequestor#enterField(FieldInfo)
207  */

208 public void enterField(FieldInfo fieldInfo) {
209     this.indexer.addFieldDeclaration(fieldInfo.type, fieldInfo.name);
210     this.methodDepth++;
211 }
212 /**
213  * @see ISourceElementRequestor#enterInitializer(int, int)
214  */

215 public void enterInitializer(int declarationSourceStart, int modifiers) {
216     this.methodDepth++;
217 }
218 private void enterInterface(TypeInfo typeInfo) {
219     // eliminate possible qualifications, given they need to be fully resolved again
220
if (typeInfo.superinterfaces != null){
221         for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
222             typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
223         }
224     }
225     char[][] typeNames;
226     if (this.methodDepth > 0) {
227         typeNames = ONE_ZERO_CHAR;
228     } else {
229         typeNames = this.enclosingTypeNames();
230     }
231     char[][] typeParameterSignatures = null;
232     if (typeInfo.typeParameters != null) {
233         int typeParametersLength = typeInfo.typeParameters.length;
234         typeParameterSignatures = new char[typeParametersLength][];
235         for (int i = 0; i < typeParametersLength; i++) {
236             ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
237             typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds);
238         }
239     }
240     this.indexer.addInterfaceDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
241     this.pushTypeName(typeInfo.name);
242 }
243 /**
244  * @see ISourceElementRequestor#enterMethod(MethodInfo)
245  */

246 public void enterMethod(MethodInfo methodInfo) {
247     this.indexer.addMethodDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.returnType, methodInfo.exceptionTypes);
248     this.methodDepth++;
249 }
250 /**
251  * @see ISourceElementRequestor#enterType(TypeInfo)
252  */

253 public void enterType(TypeInfo typeInfo) {
254     // TODO (jerome) might want to merge the 4 methods
255
switch (TypeDeclaration.kind(typeInfo.modifiers)) {
256         case TypeDeclaration.CLASS_DECL:
257             enterClass(typeInfo);
258             break;
259         case TypeDeclaration.ANNOTATION_TYPE_DECL:
260             enterAnnotationType(typeInfo);
261             break;
262         case TypeDeclaration.INTERFACE_DECL:
263             enterInterface(typeInfo);
264             break;
265         case TypeDeclaration.ENUM_DECL:
266             enterEnum(typeInfo);
267             break;
268     }
269 }
270
271 /**
272  * @see ISourceElementRequestor#exitCompilationUnit(int)
273  */

274 public void exitCompilationUnit(int declarationEnd) {
275     // implements interface method
276
}
277 /**
278  * @see ISourceElementRequestor#exitConstructor(int)
279  */

280 public void exitConstructor(int declarationEnd) {
281     this.methodDepth--;
282 }
283 /**
284  * @see ISourceElementRequestor#exitField(int, int, int)
285  */

286 public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
287     this.methodDepth--;
288 }
289 /**
290  * @see ISourceElementRequestor#exitInitializer(int)
291  */

292 public void exitInitializer(int declarationEnd) {
293     this.methodDepth--;
294 }
295 /**
296  * @see ISourceElementRequestor#exitMethod(int, int, int)
297  */

298 public void exitMethod(int declarationEnd, int defaultValueStart, int defaultValueEnd) {
299     this.methodDepth--;
300 }
301 /**
302  * @see ISourceElementRequestor#exitType(int)
303  */

304 public void exitType(int declarationEnd) {
305     popTypeName();
306 }
307 /*
308  * Returns the unqualified name without parameters from the given type name.
309  */

310 private char[] getSimpleName(char[] typeName) {
311     int lastDot = -1, lastGenericStart = -1;
312     int depthCount = 0;
313     int length = typeName.length;
314     lastDotLookup: for (int i = length -1; i >= 0; i--) {
315         switch (typeName[i]) {
316             case '.':
317                 if (depthCount == 0) {
318                     lastDot = i;
319                     break lastDotLookup;
320                 }
321                 break;
322             case '<':
323                 depthCount--;
324                 if (depthCount == 0) lastGenericStart = i;
325                 break;
326             case '>':
327                 depthCount++;
328                 break;
329         }
330     }
331     if (lastGenericStart < 0) {
332         if (lastDot < 0) {
333             return typeName;
334         }
335         return CharOperation.subarray(typeName, lastDot + 1, length);
336     }
337     return CharOperation.subarray(typeName, lastDot + 1, lastGenericStart);
338 }
339 public void popTypeName() {
340     if (depth > 0) {
341         enclosingTypeNames[--depth] = null;
342     } else if (JobManager.VERBOSE) {
343         // dump a trace so it can be tracked down
344
try {
345             enclosingTypeNames[-1] = null;
346         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
347             e.printStackTrace();
348         }
349     }
350 }
351 public void pushTypeName(char[] typeName) {
352     if (depth == enclosingTypeNames.length)
353         System.arraycopy(enclosingTypeNames, 0, enclosingTypeNames = new char[depth*2][], 0, depth);
354     enclosingTypeNames[depth++] = typeName;
355 }
356 }
357
Popular Tags