1 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 37 public class SuperTypeNamesCollector { 38 39 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; } 65 public boolean visit(Initializer initializer, MethodScope scope) { 66 return false; } 68 public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { 69 return false; } 71 public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { 72 return false; } 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; 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 112 protected CompilationUnitDeclaration buildBindings(ICompilationUnit compilationUnit, boolean isTopLevelOrMember) throws JavaModelException { 113 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 ); 123 this.locator.lookupEnvironment.completeTypeBindings(unit, !isTopLevelOrMember); 124 if (!isTopLevelOrMember) { 125 if (unit.scope != null) 126 unit.scope.faultInTypes(); unit.resolve(); 128 } 129 } 130 return unit; 131 } 132 public char[][][] collect() throws JavaModelException { 133 if (this.type != null) { 134 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 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 String [] paths = this.getPathsOfDeclaringType(); 166 if (paths == null) return null; 167 168 Util.sort(paths); 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; 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 ); 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 } catch (JavaModelException e) { 198 } 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 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 [] 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, null, this.typeSimpleName, 234 IIndexConstants.TYPE_SUFFIX, 235 this.pattern.getMatchRule()); 236 IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ 237 public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { 238 TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord; 239 if (record.enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR) { 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 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 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 |