KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > core > search > matching > SuperTypeNamesCollector


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.matching;
12
13 import org.eclipse.core.runtime.IProgressMonitor;
14 import org.eclipse.core.runtime.SubProgressMonitor;
15 import org.eclipse.jdt.core.*;
16 import org.eclipse.jdt.core.ICompilationUnit;
17 import org.eclipse.jdt.core.compiler.CharOperation;
18 import org.eclipse.jdt.core.search.*;
19 import org.eclipse.jdt.internal.compiler.ASTVisitor;
20 import org.eclipse.jdt.internal.compiler.CompilationResult;
21 import org.eclipse.jdt.internal.compiler.ast.*;
22 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet;
23 import org.eclipse.jdt.internal.compiler.lookup.*;
24 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
25 import org.eclipse.jdt.internal.core.*;
26 import org.eclipse.jdt.internal.core.search.*;
27 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants;
28 import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
29 import org.eclipse.jdt.internal.core.util.ASTNodeFinder;
30 import org.eclipse.jdt.internal.core.util.Util;
31
32 /**
33  * Collects the super type names of a given declaring type.
34  * Returns NOT_FOUND_DECLARING_TYPE if the declaring type was not found.
35  * Returns null if the declaring type pattern doesn't require an exact match.
36  */

37 public class SuperTypeNamesCollector {
38
39     /**
40      * An ast visitor that visits type declarations and member type declarations
41      * collecting their super type names.
42      */

43     public class TypeDeclarationVisitor extends ASTVisitor {
44         public boolean visit(TypeDeclaration typeDeclaration, BlockScope scope) {
45             ReferenceBinding binding = typeDeclaration.binding;
46             if (SuperTypeNamesCollector.this.matches(binding))
47                 SuperTypeNamesCollector.this.collectSuperTypeNames(binding);
48             return true;
49         }
50         public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) {
51             ReferenceBinding binding = typeDeclaration.binding;
52             if (SuperTypeNamesCollector.this.matches(binding))
53                 SuperTypeNamesCollector.this.collectSuperTypeNames(binding);
54             return true;
55         }
56         public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
57             ReferenceBinding binding = memberTypeDeclaration.binding;
58             if (SuperTypeNamesCollector.this.matches(binding))
59                 SuperTypeNamesCollector.this.collectSuperTypeNames(binding);
60             return true;
61         }
62         public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
63             return false; // don't visit field declarations
64
}
65         public boolean visit(Initializer initializer, MethodScope scope) {
66             return false; // don't visit initializers
67
}
68         public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
69             return false; // don't visit constructor declarations
70
}
71         public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
72             return false; // don't visit method declarations
73
}
74     }
75 SearchPattern pattern;
76 char[] typeSimpleName;
77 char[] typeQualification;
78 MatchLocator locator;
79 IType type;
80 IProgressMonitor progressMonitor;
81 char[][][] result;
82 int resultIndex;
83
84 public SuperTypeNamesCollector(
85     SearchPattern pattern,
86     char[] typeSimpleName,
87     char[] typeQualification,
88     MatchLocator locator,
89     IType type,
90     IProgressMonitor progressMonitor) {
91
92     this.pattern = pattern;
93     this.typeSimpleName = typeSimpleName;
94     this.typeQualification = typeQualification;
95     this.locator = locator;
96     this.type = type;
97     this.progressMonitor = progressMonitor;
98 }
99
100 protected void addToResult(char[][] compoundName) {
101     int resultLength = this.result.length;
102     for (int i = 0; i < resultLength; i++)
103         if (CharOperation.equals(this.result[i], compoundName)) return; // already known
104

105     if (resultLength == this.resultIndex)
106         System.arraycopy(this.result, 0, this.result = new char[resultLength*2][][], 0, resultLength);
107     this.result[this.resultIndex++] = compoundName;
108 }
109 /*
110  * Parse the given compiation unit and build its type bindings.
111  */

112 protected CompilationUnitDeclaration buildBindings(ICompilationUnit compilationUnit, boolean isTopLevelOrMember) throws JavaModelException {
113     // source unit
114
org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) compilationUnit;
115
116     CompilationResult compilationResult = new CompilationResult(sourceUnit, 1, 1, 0);
117     CompilationUnitDeclaration unit =
118         isTopLevelOrMember ?
119             this.locator.basicParser().dietParse(sourceUnit, compilationResult) :
120             this.locator.basicParser().parse(sourceUnit, compilationResult);
121     if (unit != null) {
122         this.locator.lookupEnvironment.buildTypeBindings(unit, null /*no access restriction*/);
123         this.locator.lookupEnvironment.completeTypeBindings(unit, !isTopLevelOrMember);
124         if (!isTopLevelOrMember) {
125             if (unit.scope != null)
126                 unit.scope.faultInTypes(); // fault in fields & methods
127
unit.resolve();
128         }
129     }
130     return unit;
131 }
132 public char[][][] collect() throws JavaModelException {
133     if (this.type != null) {
134         // Collect the paths of the cus that are in the hierarchy of the given type
135
this.result = new char[1][][];
136         this.resultIndex = 0;
137         JavaProject javaProject = (JavaProject) this.type.getJavaProject();
138         this.locator.initialize(javaProject, 0);
139         try {
140             if (this.type.isBinary()) {
141                 BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null);
142                 if (binding != null)
143                     collectSuperTypeNames(binding);
144             } else {
145                 ICompilationUnit unit = this.type.getCompilationUnit();
146                 SourceType sourceType = (SourceType) this.type;
147                 boolean isTopLevelOrMember = sourceType.getOuterMostLocalContext() == null;
148                 CompilationUnitDeclaration parsedUnit = buildBindings(unit, isTopLevelOrMember);
149                 if (parsedUnit != null) {
150                     TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type);
151                     if (typeDecl != null && typeDecl.binding != null)
152                         collectSuperTypeNames(typeDecl.binding);
153                 }
154             }
155         } catch (AbortCompilation e) {
156             // problem with classpath: report inacurrate matches
157
return null;
158         }
159         if (this.result.length > this.resultIndex)
160             System.arraycopy(this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
161         return this.result;
162     }
163
164     // Collect the paths of the cus that declare a type which matches declaringQualification + declaringSimpleName
165
String JavaDoc[] paths = this.getPathsOfDeclaringType();
166     if (paths == null) return null;
167
168     // Create bindings from source types and binary types and collect super type names of the type declaration
169
// that match the given declaring type
170
Util.sort(paths); // sort by projects
171
JavaProject previousProject = null;
172     this.result = new char[1][][];
173     this.resultIndex = 0;
174     for (int i = 0, length = paths.length; i < length; i++) {
175         try {
176             Openable openable = this.locator.handleFactory.createOpenable(paths[i], this.locator.scope);
177             if (openable == null) continue; // outside classpath
178

179             IJavaProject project = openable.getJavaProject();
180             if (!project.equals(previousProject)) {
181                 previousProject = (JavaProject) project;
182                 this.locator.initialize(previousProject, 0);
183             }
184             if (openable instanceof ICompilationUnit) {
185                 ICompilationUnit unit = (ICompilationUnit) openable;
186                 CompilationUnitDeclaration parsedUnit = buildBindings(unit, true /*only toplevel and member types are visible to the focus type*/);
187                 if (parsedUnit != null)
188                     parsedUnit.traverse(new TypeDeclarationVisitor(), parsedUnit.scope);
189             } else if (openable instanceof IClassFile) {
190                 IClassFile classFile = (IClassFile) openable;
191                 BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null);
192                 if (matches(binding))
193                     collectSuperTypeNames(binding);
194             }
195         } catch (AbortCompilation e) {
196             // ignore: continue with next element
197
} catch (JavaModelException e) {
198             // ignore: continue with next element
199
}
200     }
201     if (this.result.length > this.resultIndex)
202         System.arraycopy(this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex);
203     return this.result;
204 }
205 /**
206  * Collects the names of all the supertypes of the given type.
207  */

208 protected void collectSuperTypeNames(ReferenceBinding binding) {
209     ReferenceBinding superclass = binding.superclass();
210     if (superclass != null) {
211         this.addToResult(superclass.compoundName);
212         this.collectSuperTypeNames(superclass);
213     }
214
215     ReferenceBinding[] interfaces = binding.superInterfaces();
216     if (interfaces != null) {
217         for (int i = 0; i < interfaces.length; i++) {
218             ReferenceBinding interfaceBinding = interfaces[i];
219             this.addToResult(interfaceBinding.compoundName);
220             this.collectSuperTypeNames(interfaceBinding);
221         }
222     }
223 }
224 protected String JavaDoc[] getPathsOfDeclaringType() {
225     if (this.typeQualification == null && this.typeSimpleName == null) return null;
226
227     final PathCollector pathCollector = new PathCollector();
228     IJavaSearchScope scope = SearchEngine.createWorkspaceScope();
229     IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
230     SearchPattern searchPattern = new TypeDeclarationPattern(
231         this.typeSimpleName != null ? null : this.typeQualification, // use the qualification only if no simple name
232
null, // do find member types
233
this.typeSimpleName,
234         IIndexConstants.TYPE_SUFFIX,
235         this.pattern.getMatchRule());
236     IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){
237         public boolean acceptIndexMatch(String JavaDoc documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) {
238             TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord;
239             if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR) { // filter out local and anonymous classes
240
pathCollector.acceptIndexMatch(documentPath, indexRecord, participant, access);
241             }
242             return true;
243         }
244     };
245
246     indexManager.performConcurrentJob(
247         new PatternSearchJob(
248             searchPattern,
249             new JavaSearchParticipant(),
250             scope,
251             searchRequestor),
252         IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
253         progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100));
254     return pathCollector.getPaths();
255 }
256 protected boolean matches(char[][] compoundName) {
257     int length = compoundName.length;
258     if (length == 0) return false;
259     char[] simpleName = compoundName[length-1];
260     int last = length - 1;
261     if (this.typeSimpleName == null || this.pattern.matchesName(simpleName, this.typeSimpleName)) {
262         // most frequent case: simple name equals last segment of compoundName
263
char[][] qualification = new char[last][];
264         System.arraycopy(compoundName, 0, qualification, 0, last);
265         return this.pattern.matchesName(this.typeQualification, CharOperation.concatWith(qualification, '.'));
266     }
267
268     if (!CharOperation.endsWith(simpleName, this.typeSimpleName)) return false;
269
270     // member type -> transform A.B.C$D into A.B.C.D
271
System.arraycopy(compoundName, 0, compoundName = new char[length+1][], 0, last);
272     int dollar = CharOperation.indexOf('$', simpleName);
273     if (dollar == -1) return false;
274     compoundName[last] = CharOperation.subarray(simpleName, 0, dollar);
275     compoundName[length] = CharOperation.subarray(simpleName, dollar+1, simpleName.length);
276     return this.matches(compoundName);
277 }
278 protected boolean matches(ReferenceBinding binding) {
279     return binding != null && binding.compoundName != null && this.matches(binding.compoundName);
280 }
281 }
282
Popular Tags