1 11 package org.eclipse.jdt.internal.core.search; 12 13 import java.util.*; 14 15 import org.eclipse.core.resources.*; 16 import org.eclipse.core.runtime.*; 17 18 import org.eclipse.jdt.core.*; 19 import org.eclipse.jdt.core.compiler.CharOperation; 20 import org.eclipse.jdt.core.search.*; 21 import org.eclipse.jdt.internal.compiler.*; 22 import org.eclipse.jdt.internal.compiler.ast.*; 23 import org.eclipse.jdt.internal.compiler.env.AccessRestriction; 24 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; 25 import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; 26 import org.eclipse.jdt.internal.compiler.lookup.*; 27 import org.eclipse.jdt.internal.compiler.parser.Parser; 28 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; 29 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 30 import org.eclipse.jdt.internal.core.*; 31 import org.eclipse.jdt.internal.core.search.indexing.*; 32 import org.eclipse.jdt.internal.core.search.matching.*; 33 import org.eclipse.jdt.internal.core.util.Messages; 34 import org.eclipse.jdt.internal.core.util.Util; 35 36 41 public class BasicSearchEngine { 42 43 46 private Parser parser; 47 private CompilerOptions compilerOptions; 48 49 53 private ICompilationUnit[] workingCopies; 54 55 59 private WorkingCopyOwner workingCopyOwner; 60 61 64 public static boolean VERBOSE = false; 65 66 69 public BasicSearchEngine() { 70 } 72 73 76 public BasicSearchEngine(ICompilationUnit[] workingCopies) { 77 this.workingCopies = workingCopies; 78 } 79 80 char convertTypeKind(int typeDeclarationKind) { 81 switch(typeDeclarationKind) { 82 case TypeDeclaration.CLASS_DECL : return IIndexConstants.CLASS_SUFFIX; 83 case TypeDeclaration.INTERFACE_DECL : return IIndexConstants.INTERFACE_SUFFIX; 84 case TypeDeclaration.ENUM_DECL : return IIndexConstants.ENUM_SUFFIX; 85 case TypeDeclaration.ANNOTATION_TYPE_DECL : return IIndexConstants.ANNOTATION_TYPE_SUFFIX; 86 default : return IIndexConstants.TYPE_SUFFIX; 87 } 88 } 89 92 public BasicSearchEngine(WorkingCopyOwner workingCopyOwner) { 93 this.workingCopyOwner = workingCopyOwner; 94 } 95 96 99 public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException { 100 return createHierarchyScope(type, DefaultWorkingCopyOwner.PRIMARY); 101 } 102 103 106 public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException { 107 return new HierarchyScope(type, owner); 108 } 109 110 113 public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) { 114 return createJavaSearchScope(elements, true); 115 } 116 117 120 public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) { 121 int includeMask = IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES | IJavaSearchScope.SYSTEM_LIBRARIES; 122 if (includeReferencedProjects) { 123 includeMask |= IJavaSearchScope.REFERENCED_PROJECTS; 124 } 125 return createJavaSearchScope(elements, includeMask); 126 } 127 128 131 public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, int includeMask) { 132 JavaSearchScope scope = new JavaSearchScope(); 133 HashSet visitedProjects = new HashSet(2); 134 for (int i = 0, length = elements.length; i < length; i++) { 135 IJavaElement element = elements[i]; 136 if (element != null) { 137 try { 138 if (element instanceof JavaProject) { 139 scope.add((JavaProject)element, includeMask, visitedProjects); 140 } else { 141 scope.add(element); 142 } 143 } catch (JavaModelException e) { 144 } 146 } 147 } 148 return scope; 149 } 150 151 154 public static TypeNameMatch createTypeNameMatch(IType type, int modifiers) { 155 return new JavaSearchTypeNameMatch(type, modifiers); 156 } 157 158 161 public static IJavaSearchScope createWorkspaceScope() { 162 return JavaModelManager.getJavaModelManager().getWorkspaceScope(); 163 } 164 165 173 void findMatches(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { 174 if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); 175 try { 176 if (VERBOSE) { 177 Util.verbose("Searching for pattern: " + pattern.toString()); Util.verbose(scope.toString()); 179 } 180 if (participants == null) { 181 if (VERBOSE) Util.verbose("No participants => do nothing!"); return; 183 } 184 185 186 int length = participants.length; 187 if (monitor != null) 188 monitor.beginTask(Messages.engine_searching, 100 * length); 189 IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); 190 requestor.beginReporting(); 191 for (int i = 0; i < length; i++) { 192 if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); 193 194 SearchParticipant participant = participants[i]; 195 try { 196 if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_indexing, new String [] {participant.getDescription()})); 197 participant.beginSearching(); 198 requestor.enterParticipant(participant); 199 PathCollector pathCollector = new PathCollector(); 200 indexManager.performConcurrentJob( 201 new PatternSearchJob(pattern, participant, scope, pathCollector), 202 IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, 203 monitor==null ? null : new SubProgressMonitor(monitor, 50)); 204 if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); 205 206 if (monitor != null) monitor.subTask(Messages.bind(Messages.engine_searching_matching, new String [] {participant.getDescription()})); 208 String [] indexMatchPaths = pathCollector.getPaths(); 209 if (indexMatchPaths != null) { 210 pathCollector = null; int indexMatchLength = indexMatchPaths.length; 212 SearchDocument[] indexMatches = new SearchDocument[indexMatchLength]; 213 for (int j = 0; j < indexMatchLength; j++) { 214 indexMatches[j] = participant.getDocument(indexMatchPaths[j]); 215 } 216 SearchDocument[] matches = MatchLocator.addWorkingCopies(pattern, indexMatches, getWorkingCopies(), participant); 217 participant.locateMatches(matches, pattern, scope, requestor, monitor==null ? null : new SubProgressMonitor(monitor, 50)); 218 } 219 } finally { 220 requestor.exitParticipant(participant); 221 participant.doneSearching(); 222 } 223 } 224 } finally { 225 requestor.endReporting(); 226 if (monitor != null) 227 monitor.done(); 228 } 229 } 230 236 public static SearchParticipant getDefaultSearchParticipant() { 237 return new JavaSearchParticipant(); 238 } 239 240 241 244 public static String getMatchRuleString(final int matchRule) { 245 if (matchRule == 0) { 246 return "R_EXACT_MATCH"; } 248 StringBuffer buffer = new StringBuffer (); 249 for (int i=1; i<=8; i++) { 250 int bit = matchRule & (1<<(i-1)); 251 if (bit != 0 && buffer.length()>0) buffer.append(" | "); switch (bit) { 253 case SearchPattern.R_PREFIX_MATCH: 254 buffer.append("R_PREFIX_MATCH"); break; 256 case SearchPattern.R_CASE_SENSITIVE: 257 buffer.append("R_CASE_SENSITIVE"); break; 259 case SearchPattern.R_EQUIVALENT_MATCH: 260 buffer.append("R_EQUIVALENT_MATCH"); break; 262 case SearchPattern.R_ERASURE_MATCH: 263 buffer.append("R_ERASURE_MATCH"); break; 265 case SearchPattern.R_FULL_MATCH: 266 buffer.append("R_FULL_MATCH"); break; 268 case SearchPattern.R_PATTERN_MATCH: 269 buffer.append("R_PATTERN_MATCH"); break; 271 case SearchPattern.R_REGEXP_MATCH: 272 buffer.append("R_REGEXP_MATCH"); break; 274 case SearchPattern.R_CAMELCASE_MATCH: 275 buffer.append("R_CAMELCASE_MATCH"); break; 277 } 278 } 279 return buffer.toString(); 280 } 281 282 287 public static String getSearchForString(final int searchFor) { 288 switch (searchFor) { 289 case IJavaSearchConstants.TYPE: 290 return ("TYPE"); case IJavaSearchConstants.METHOD: 292 return ("METHOD"); case IJavaSearchConstants.PACKAGE: 294 return ("PACKAGE"); case IJavaSearchConstants.CONSTRUCTOR: 296 return ("CONSTRUCTOR"); case IJavaSearchConstants.FIELD: 298 return ("FIELD"); case IJavaSearchConstants.CLASS: 300 return ("CLASS"); case IJavaSearchConstants.INTERFACE: 302 return ("INTERFACE"); case IJavaSearchConstants.ENUM: 304 return ("ENUM"); case IJavaSearchConstants.ANNOTATION_TYPE: 306 return ("ANNOTATION_TYPE"); case IJavaSearchConstants.CLASS_AND_ENUM: 308 return ("CLASS_AND_ENUM"); case IJavaSearchConstants.CLASS_AND_INTERFACE: 310 return ("CLASS_AND_INTERFACE"); case IJavaSearchConstants.INTERFACE_AND_ANNOTATION: 312 return ("INTERFACE_AND_ANNOTATION"); } 314 return "UNKNOWN"; } 316 317 private Parser getParser() { 318 if (this.parser == null) { 319 this.compilerOptions = new CompilerOptions(JavaCore.getOptions()); 320 ProblemReporter problemReporter = 321 new ProblemReporter( 322 DefaultErrorHandlingPolicies.proceedWithAllProblems(), 323 this.compilerOptions, 324 new DefaultProblemFactory()); 325 this.parser = new Parser(problemReporter, true); 326 } 327 return this.parser; 328 } 329 330 334 private ICompilationUnit[] getWorkingCopies() { 335 ICompilationUnit[] copies; 336 if (this.workingCopies != null) { 337 if (this.workingCopyOwner == null) { 338 copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false); 339 if (copies == null) { 340 copies = this.workingCopies; 341 } else { 342 HashMap pathToCUs = new HashMap(); 343 for (int i = 0, length = copies.length; i < length; i++) { 344 ICompilationUnit unit = copies[i]; 345 pathToCUs.put(unit.getPath(), unit); 346 } 347 for (int i = 0, length = this.workingCopies.length; i < length; i++) { 348 ICompilationUnit unit = this.workingCopies[i]; 349 pathToCUs.put(unit.getPath(), unit); 350 } 351 int length = pathToCUs.size(); 352 copies = new ICompilationUnit[length]; 353 pathToCUs.values().toArray(copies); 354 } 355 } else { 356 copies = this.workingCopies; 357 } 358 } else if (this.workingCopyOwner != null) { 359 copies = JavaModelManager.getJavaModelManager().getWorkingCopies(this.workingCopyOwner, true); 360 } else { 361 copies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false); 362 } 363 if (copies == null) return null; 364 365 ICompilationUnit[] result = null; 367 int length = copies.length; 368 int index = 0; 369 for (int i = 0; i < length; i++) { 370 CompilationUnit copy = (CompilationUnit)copies[i]; 371 try { 372 if (!copy.isPrimary() 373 || copy.hasUnsavedChanges() 374 || copy.hasResourceChanged()) { 375 if (result == null) { 376 result = new ICompilationUnit[length]; 377 } 378 result[index++] = copy; 379 } 380 } catch (JavaModelException e) { 381 } 383 } 384 if (index != length && result != null) { 385 System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index); 386 } 387 return result; 388 } 389 390 393 private ICompilationUnit[] getWorkingCopies(IJavaElement element) { 394 if (element instanceof IMember) { 395 ICompilationUnit cu = ((IMember)element).getCompilationUnit(); 396 if (cu != null && cu.isWorkingCopy()) { 397 ICompilationUnit[] copies = getWorkingCopies(); 398 int length = copies == null ? 0 : copies.length; 399 if (length > 0) { 400 ICompilationUnit[] newWorkingCopies = new ICompilationUnit[length+1]; 401 System.arraycopy(copies, 0, newWorkingCopies, 0, length); 402 newWorkingCopies[length] = cu; 403 return newWorkingCopies; 404 } 405 return new ICompilationUnit[] {cu}; 406 } 407 } 408 return getWorkingCopies(); 409 } 410 411 boolean match(char patternTypeSuffix, int modifiers) { 412 switch(patternTypeSuffix) { 413 case IIndexConstants.CLASS_SUFFIX : 414 return (modifiers & (Flags.AccAnnotation | Flags.AccInterface | Flags.AccEnum)) == 0; 415 case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX: 416 return (modifiers & (Flags.AccAnnotation | Flags.AccEnum)) == 0; 417 case IIndexConstants.CLASS_AND_ENUM_SUFFIX: 418 return (modifiers & (Flags.AccAnnotation | Flags.AccInterface)) == 0; 419 case IIndexConstants.INTERFACE_SUFFIX : 420 return (modifiers & Flags.AccInterface) != 0; 421 case IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX: 422 return (modifiers & (Flags.AccInterface | Flags.AccAnnotation)) != 0; 423 case IIndexConstants.ENUM_SUFFIX : 424 return (modifiers & Flags.AccEnum) != 0; 425 case IIndexConstants.ANNOTATION_TYPE_SUFFIX : 426 return (modifiers & Flags.AccAnnotation) != 0; 427 } 428 return true; 429 } 430 431 boolean match(char patternTypeSuffix, char[] patternPkg, char[] patternTypeName, int matchRule, int typeKind, char[] pkg, char[] typeName) { 432 switch(patternTypeSuffix) { 433 case IIndexConstants.CLASS_SUFFIX : 434 if (typeKind != TypeDeclaration.CLASS_DECL) return false; 435 break; 436 case IIndexConstants.CLASS_AND_INTERFACE_SUFFIX: 437 if (typeKind != TypeDeclaration.CLASS_DECL && typeKind != TypeDeclaration.INTERFACE_DECL) return false; 438 break; 439 case IIndexConstants.CLASS_AND_ENUM_SUFFIX: 440 if (typeKind != TypeDeclaration.CLASS_DECL && typeKind != TypeDeclaration.ENUM_DECL) return false; 441 break; 442 case IIndexConstants.INTERFACE_SUFFIX : 443 if (typeKind != TypeDeclaration.INTERFACE_DECL) return false; 444 break; 445 case IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX: 446 if (typeKind != TypeDeclaration.INTERFACE_DECL && typeKind != TypeDeclaration.ANNOTATION_TYPE_DECL) return false; 447 break; 448 case IIndexConstants.ENUM_SUFFIX : 449 if (typeKind != TypeDeclaration.ENUM_DECL) return false; 450 break; 451 case IIndexConstants.ANNOTATION_TYPE_SUFFIX : 452 if (typeKind != TypeDeclaration.ANNOTATION_TYPE_DECL) return false; 453 break; 454 case IIndexConstants.TYPE_SUFFIX : } 456 457 boolean isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0; 458 if (patternPkg != null && !CharOperation.equals(patternPkg, pkg, isCaseSensitive)) 459 return false; 460 461 if (patternTypeName != null) { 462 boolean isCamelCase = (matchRule & SearchPattern.R_CAMELCASE_MATCH) != 0; 463 int matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK; 464 if (!isCaseSensitive && !isCamelCase) { 465 patternTypeName = CharOperation.toLowerCase(patternTypeName); 466 } 467 boolean matchFirstChar = !isCaseSensitive || patternTypeName[0] == typeName[0]; 468 if (isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(patternTypeName, typeName)) { 469 return true; 470 } 471 switch(matchMode) { 472 case SearchPattern.R_EXACT_MATCH : 473 if (!isCamelCase) { 474 return matchFirstChar && CharOperation.equals(patternTypeName, typeName, isCaseSensitive); 475 } 476 case SearchPattern.R_PREFIX_MATCH : 478 return matchFirstChar && CharOperation.prefixEquals(patternTypeName, typeName, isCaseSensitive); 479 case SearchPattern.R_PATTERN_MATCH : 480 return CharOperation.match(patternTypeName, typeName, isCaseSensitive); 481 case SearchPattern.R_REGEXP_MATCH : 482 break; 484 } 485 } 486 return true; 487 488 } 489 490 498 public void search(SearchPattern pattern, SearchParticipant[] participants, IJavaSearchScope scope, SearchRequestor requestor, IProgressMonitor monitor) throws CoreException { 499 if (VERBOSE) { 500 Util.verbose("BasicSearchEngine.search(SearchPattern, SearchParticipant[], IJavaSearchScope, SearchRequestor, IProgressMonitor)"); } 502 findMatches(pattern, participants, scope, requestor, monitor); 503 } 504 505 510 public void searchAllSecondaryTypeNames( 511 IPackageFragmentRoot[] sourceFolders, 512 final IRestrictedAccessTypeRequestor nameRequestor, 513 boolean waitForIndexes, 514 IProgressMonitor progressMonitor) throws JavaModelException { 515 516 if (VERBOSE) { 517 Util.verbose("BasicSearchEngine.searchAllSecondaryTypeNames(IPackageFragmentRoot[], IRestrictedAccessTypeRequestor, boolean, IProgressMonitor)"); StringBuffer buffer = new StringBuffer (" - source folders: "); int length = sourceFolders.length; 520 for (int i=0; i<length; i++) { 521 if (i==0) { 522 buffer.append('['); 523 } else { 524 buffer.append(','); 525 } 526 buffer.append(sourceFolders[i].getElementName()); 527 } 528 buffer.append("]\n - waitForIndexes: "); buffer.append(waitForIndexes); 530 Util.verbose(buffer.toString()); 531 } 532 533 IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); 534 final TypeDeclarationPattern pattern = new SecondaryTypeDeclarationPattern(); 535 536 final HashSet workingCopyPaths = new HashSet(); 538 String workingCopyPath = null; 539 ICompilationUnit[] copies = getWorkingCopies(); 540 final int copiesLength = copies == null ? 0 : copies.length; 541 if (copies != null) { 542 if (copiesLength == 1) { 543 workingCopyPath = copies[0].getPath().toString(); 544 } else { 545 for (int i = 0; i < copiesLength; i++) { 546 ICompilationUnit workingCopy = copies[i]; 547 workingCopyPaths.add(workingCopy.getPath().toString()); 548 } 549 } 550 } 551 final String singleWkcpPath = workingCopyPath; 552 553 IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ 555 public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { 556 TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord; 558 if (!record.secondary) { 559 return true; } 561 if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) { 562 return true; } 564 switch (copiesLength) { 565 case 0: 566 break; 567 case 1: 568 if (singleWkcpPath.equals(documentPath)) { 569 return true; } 571 break; 572 default: 573 if (workingCopyPaths.contains(documentPath)) { 574 return true; } 576 break; 577 } 578 579 AccessRestriction accessRestriction = null; 581 if (access != null) { 582 int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1; 584 int nameLength = record.simpleName==null ? 0 : record.simpleName.length; 585 char[] path = new char[pkgLength+nameLength]; 586 int pos = 0; 587 if (pkgLength > 0) { 588 System.arraycopy(record.pkg, 0, path, pos, pkgLength-1); 589 CharOperation.replace(path, '.', '/'); 590 path[pkgLength-1] = '/'; 591 pos += pkgLength; 592 } 593 if (nameLength > 0) { 594 System.arraycopy(record.simpleName, 0, path, pos, nameLength); 595 pos += nameLength; 596 } 597 if (pos > 0) { 599 accessRestriction = access.getViolatedRestriction(path); 600 } 601 } 602 nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction); 603 return true; 604 } 605 }; 606 607 try { 609 if (progressMonitor != null) { 610 progressMonitor.beginTask(Messages.engine_searching, 100); 611 } 612 indexManager.performConcurrentJob( 613 new PatternSearchJob( 614 pattern, 615 getDefaultSearchParticipant(), createJavaSearchScope(sourceFolders), 617 searchRequestor), 618 waitForIndexes 619 ? IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH 620 : IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH, 621 progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); 622 } catch (OperationCanceledException oce) { 623 } finally { 625 if (progressMonitor != null) { 626 progressMonitor.done(); 627 } 628 } 629 } 630 631 639 public void searchAllTypeNames( 640 final char[] packageName, 641 final int packageMatchRule, 642 final char[] typeName, 643 final int typeMatchRule, 644 int searchFor, 645 IJavaSearchScope scope, 646 final IRestrictedAccessTypeRequestor nameRequestor, 647 int waitingPolicy, 648 IProgressMonitor progressMonitor) throws JavaModelException { 649 650 if (VERBOSE) { 651 Util.verbose("BasicSearchEngine.searchAllTypeNames(char[], char[], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); Util.verbose(" - package name: "+(packageName==null?"null":new String (packageName))); Util.verbose(" - match rule: "+getMatchRuleString(packageMatchRule)); Util.verbose(" - type name: "+(typeName==null?"null":new String (typeName))); Util.verbose(" - match rule: "+getMatchRuleString(typeMatchRule)); Util.verbose(" - search for: "+searchFor); Util.verbose(" - scope: "+scope); } 659 660 IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); 662 final char typeSuffix; 663 switch(searchFor){ 664 case IJavaSearchConstants.CLASS : 665 typeSuffix = IIndexConstants.CLASS_SUFFIX; 666 break; 667 case IJavaSearchConstants.CLASS_AND_INTERFACE : 668 typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX; 669 break; 670 case IJavaSearchConstants.CLASS_AND_ENUM : 671 typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX; 672 break; 673 case IJavaSearchConstants.INTERFACE : 674 typeSuffix = IIndexConstants.INTERFACE_SUFFIX; 675 break; 676 case IJavaSearchConstants.INTERFACE_AND_ANNOTATION : 677 typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX; 678 break; 679 case IJavaSearchConstants.ENUM : 680 typeSuffix = IIndexConstants.ENUM_SUFFIX; 681 break; 682 case IJavaSearchConstants.ANNOTATION_TYPE : 683 typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; 684 break; 685 default : 686 typeSuffix = IIndexConstants.TYPE_SUFFIX; 687 break; 688 } 689 final TypeDeclarationPattern pattern = packageMatchRule == SearchPattern.R_EXACT_MATCH 690 ? new TypeDeclarationPattern( 691 packageName, 692 null, 693 typeName, 694 typeSuffix, 695 typeMatchRule) 696 : new QualifiedTypeDeclarationPattern( 697 packageName, 698 packageMatchRule, 699 typeName, 700 typeSuffix, 701 typeMatchRule); 702 703 final HashSet workingCopyPaths = new HashSet(); 705 String workingCopyPath = null; 706 ICompilationUnit[] copies = getWorkingCopies(); 707 final int copiesLength = copies == null ? 0 : copies.length; 708 if (copies != null) { 709 if (copiesLength == 1) { 710 workingCopyPath = copies[0].getPath().toString(); 711 } else { 712 for (int i = 0; i < copiesLength; i++) { 713 ICompilationUnit workingCopy = copies[i]; 714 workingCopyPaths.add(workingCopy.getPath().toString()); 715 } 716 } 717 } 718 final String singleWkcpPath = workingCopyPath; 719 720 IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ 722 public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { 723 TypeDeclarationPattern record = (TypeDeclarationPattern)indexRecord; 725 if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) { 726 return true; } 728 switch (copiesLength) { 729 case 0: 730 break; 731 case 1: 732 if (singleWkcpPath.equals(documentPath)) { 733 return true; } 735 break; 736 default: 737 if (workingCopyPaths.contains(documentPath)) { 738 return true; } 740 break; 741 } 742 743 AccessRestriction accessRestriction = null; 745 if (access != null) { 746 int pkgLength = (record.pkg==null || record.pkg.length==0) ? 0 : record.pkg.length+1; 748 int nameLength = record.simpleName==null ? 0 : record.simpleName.length; 749 char[] path = new char[pkgLength+nameLength]; 750 int pos = 0; 751 if (pkgLength > 0) { 752 System.arraycopy(record.pkg, 0, path, pos, pkgLength-1); 753 CharOperation.replace(path, '.', '/'); 754 path[pkgLength-1] = '/'; 755 pos += pkgLength; 756 } 757 if (nameLength > 0) { 758 System.arraycopy(record.simpleName, 0, path, pos, nameLength); 759 pos += nameLength; 760 } 761 if (pos > 0) { 763 accessRestriction = access.getViolatedRestriction(path); 764 } 765 } 766 if (match(record.typeSuffix, record.modifiers)) { 767 nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction); 768 } 769 return true; 770 } 771 }; 772 773 try { 774 if (progressMonitor != null) { 775 progressMonitor.beginTask(Messages.engine_searching, 100); 776 } 777 indexManager.performConcurrentJob( 779 new PatternSearchJob( 780 pattern, 781 getDefaultSearchParticipant(), scope, 783 searchRequestor), 784 waitingPolicy, 785 progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); 786 787 if (copies != null) { 789 for (int i = 0; i < copiesLength; i++) { 790 final ICompilationUnit workingCopy = copies[i]; 791 if (!scope.encloses(workingCopy)) continue; 792 final String path = workingCopy.getPath().toString(); 793 if (workingCopy.isConsistent()) { 794 IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations(); 795 char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray(); 796 IType[] allTypes = workingCopy.getAllTypes(); 797 for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) { 798 IType type = allTypes[j]; 799 IJavaElement parent = type.getParent(); 800 char[][] enclosingTypeNames; 801 if (parent instanceof IType) { 802 char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray(); 803 enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName); 804 } else { 805 enclosingTypeNames = CharOperation.NO_CHAR_CHAR; 806 } 807 char[] simpleName = type.getElementName().toCharArray(); 808 int kind; 809 if (type.isEnum()) { 810 kind = TypeDeclaration.ENUM_DECL; 811 } else if (type.isAnnotation()) { 812 kind = TypeDeclaration.ANNOTATION_TYPE_DECL; 813 } else if (type.isClass()) { 814 kind = TypeDeclaration.CLASS_DECL; 815 } else { 816 kind = TypeDeclaration.INTERFACE_DECL; 817 } 818 if (match(typeSuffix, packageName, typeName, typeMatchRule, kind, packageDeclaration, simpleName)) { 819 if (nameRequestor instanceof TypeNameMatchRequestorWrapper) { 820 ((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, type.getFlags())); 821 } else { 822 nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null); 823 } 824 } 825 } 826 } else { 827 Parser basicParser = getParser(); 828 org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy; 829 CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit); 830 CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult); 831 if (parsedUnit != null) { 832 final char[] packageDeclaration = parsedUnit.currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.'); 833 class AllTypeDeclarationsVisitor extends ASTVisitor { 834 public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) { 835 return false; } 837 public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) { 838 if (match(typeSuffix, packageName, typeName, typeMatchRule, TypeDeclaration.kind(typeDeclaration.modifiers), packageDeclaration, typeDeclaration.name)) { 839 if (nameRequestor instanceof TypeNameMatchRequestorWrapper) { 840 IType type = workingCopy.getType(new String (typeName)); 841 ((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, typeDeclaration.modifiers)); 842 } else { 843 nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null); 844 } 845 } 846 return true; 847 } 848 public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) { 849 if (match(typeSuffix, packageName, typeName, typeMatchRule, TypeDeclaration.kind(memberTypeDeclaration.modifiers), packageDeclaration, memberTypeDeclaration.name)) { 850 TypeDeclaration enclosing = memberTypeDeclaration.enclosingType; 852 char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR; 853 while (enclosing != null) { 854 enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames); 855 if ((enclosing.bits & ASTNode.IsMemberType) != 0) { 856 enclosing = enclosing.enclosingType; 857 } else { 858 enclosing = null; 859 } 860 } 861 if (nameRequestor instanceof TypeNameMatchRequestorWrapper) { 863 IType type = workingCopy.getType(new String (enclosingTypeNames[0])); 864 for (int j=1, l=enclosingTypeNames.length; j<l; j++) { 865 type = type.getType(new String (enclosingTypeNames[j])); 866 } 867 ((TypeNameMatchRequestorWrapper)nameRequestor).requestor.acceptTypeNameMatch(new JavaSearchTypeNameMatch(type, 0)); 868 } else { 869 nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null); 870 } 871 } 872 return true; 873 } 874 } 875 parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope); 876 } 877 } 878 } 879 } 880 } finally { 881 if (progressMonitor != null) { 882 progressMonitor.done(); 883 } 884 } 885 } 886 887 894 public void searchAllTypeNames( 895 final char[][] qualifications, 896 final char[][] typeNames, 897 final int matchRule, 898 int searchFor, 899 IJavaSearchScope scope, 900 final IRestrictedAccessTypeRequestor nameRequestor, 901 int waitingPolicy, 902 IProgressMonitor progressMonitor) throws JavaModelException { 903 904 if (VERBOSE) { 905 Util.verbose("BasicSearchEngine.searchAllTypeNames(char[][], char[][], int, int, IJavaSearchScope, IRestrictedAccessTypeRequestor, int, IProgressMonitor)"); Util.verbose(" - package name: "+(qualifications==null?"null":new String (CharOperation.concatWith(qualifications, ',')))); Util.verbose(" - type name: "+(typeNames==null?"null":new String (CharOperation.concatWith(typeNames, ',')))); Util.verbose(" - match rule: "+matchRule); Util.verbose(" - search for: "+searchFor); Util.verbose(" - scope: "+scope); } 912 IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); 913 914 final char typeSuffix; 915 switch(searchFor){ 916 case IJavaSearchConstants.CLASS : 917 typeSuffix = IIndexConstants.CLASS_SUFFIX; 918 break; 919 case IJavaSearchConstants.CLASS_AND_INTERFACE : 920 typeSuffix = IIndexConstants.CLASS_AND_INTERFACE_SUFFIX; 921 break; 922 case IJavaSearchConstants.CLASS_AND_ENUM : 923 typeSuffix = IIndexConstants.CLASS_AND_ENUM_SUFFIX; 924 break; 925 case IJavaSearchConstants.INTERFACE : 926 typeSuffix = IIndexConstants.INTERFACE_SUFFIX; 927 break; 928 case IJavaSearchConstants.INTERFACE_AND_ANNOTATION : 929 typeSuffix = IIndexConstants.INTERFACE_AND_ANNOTATION_SUFFIX; 930 break; 931 case IJavaSearchConstants.ENUM : 932 typeSuffix = IIndexConstants.ENUM_SUFFIX; 933 break; 934 case IJavaSearchConstants.ANNOTATION_TYPE : 935 typeSuffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; 936 break; 937 default : 938 typeSuffix = IIndexConstants.TYPE_SUFFIX; 939 break; 940 } 941 final MultiTypeDeclarationPattern pattern = new MultiTypeDeclarationPattern(qualifications, typeNames, typeSuffix, matchRule); 942 943 final HashSet workingCopyPaths = new HashSet(); 945 String workingCopyPath = null; 946 ICompilationUnit[] copies = getWorkingCopies(); 947 final int copiesLength = copies == null ? 0 : copies.length; 948 if (copies != null) { 949 if (copiesLength == 1) { 950 workingCopyPath = copies[0].getPath().toString(); 951 } else { 952 for (int i = 0; i < copiesLength; i++) { 953 ICompilationUnit workingCopy = copies[i]; 954 workingCopyPaths.add(workingCopy.getPath().toString()); 955 } 956 } 957 } 958 final String singleWkcpPath = workingCopyPath; 959 960 IndexQueryRequestor searchRequestor = new IndexQueryRequestor(){ 962 public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant, AccessRuleSet access) { 963 QualifiedTypeDeclarationPattern record = (QualifiedTypeDeclarationPattern) indexRecord; 965 if (record.enclosingTypeNames == IIndexConstants.ONE_ZERO_CHAR) { 966 return true; } 968 switch (copiesLength) { 969 case 0: 970 break; 971 case 1: 972 if (singleWkcpPath.equals(documentPath)) { 973 return true; } 975 break; 976 default: 977 if (workingCopyPaths.contains(documentPath)) { 978 return true; } 980 break; 981 } 982 983 AccessRestriction accessRestriction = null; 985 if (access != null) { 986 int qualificationLength = (record.qualification == null || record.qualification.length == 0) ? 0 : record.qualification.length + 1; 988 int nameLength = record.simpleName == null ? 0 : record.simpleName.length; 989 char[] path = new char[qualificationLength + nameLength]; 990 int pos = 0; 991 if (qualificationLength > 0) { 992 System.arraycopy(record.qualification, 0, path, pos, qualificationLength - 1); 993 CharOperation.replace(path, '.', '/'); 994 path[qualificationLength-1] = '/'; 995 pos += qualificationLength; 996 } 997 if (nameLength > 0) { 998 System.arraycopy(record.simpleName, 0, path, pos, nameLength); 999 pos += nameLength; 1000 } 1001 if (pos > 0) { 1003 accessRestriction = access.getViolatedRestriction(path); 1004 } 1005 } 1006 nameRequestor.acceptType(record.modifiers, record.pkg, record.simpleName, record.enclosingTypeNames, documentPath, accessRestriction); 1007 return true; 1008 } 1009 }; 1010 1011 try { 1012 if (progressMonitor != null) { 1013 progressMonitor.beginTask(Messages.engine_searching, 100); 1014 } 1015 indexManager.performConcurrentJob( 1017 new PatternSearchJob( 1018 pattern, 1019 getDefaultSearchParticipant(), scope, 1021 searchRequestor), 1022 waitingPolicy, 1023 progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); 1024 1025 if (copies != null) { 1027 for (int i = 0, length = copies.length; i < length; i++) { 1028 ICompilationUnit workingCopy = copies[i]; 1029 final String path = workingCopy.getPath().toString(); 1030 if (workingCopy.isConsistent()) { 1031 IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations(); 1032 char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray(); 1033 IType[] allTypes = workingCopy.getAllTypes(); 1034 for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) { 1035 IType type = allTypes[j]; 1036 IJavaElement parent = type.getParent(); 1037 char[][] enclosingTypeNames; 1038 char[] qualification = packageDeclaration; 1039 if (parent instanceof IType) { 1040 char[] parentQualifiedName = ((IType)parent).getTypeQualifiedName('.').toCharArray(); 1041 enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName); 1042 qualification = CharOperation.concat(qualification, parentQualifiedName); 1043 } else { 1044 enclosingTypeNames = CharOperation.NO_CHAR_CHAR; 1045 } 1046 char[] simpleName = type.getElementName().toCharArray(); 1047 char suffix = IIndexConstants.TYPE_SUFFIX; 1048 if (type.isClass()) { 1049 suffix = IIndexConstants.CLASS_SUFFIX; 1050 } else if (type.isInterface()) { 1051 suffix = IIndexConstants.INTERFACE_SUFFIX; 1052 } else if (type.isEnum()) { 1053 suffix = IIndexConstants.ENUM_SUFFIX; 1054 } else if (type.isAnnotation()) { 1055 suffix = IIndexConstants.ANNOTATION_TYPE_SUFFIX; 1056 } 1057 if (pattern.matchesDecodedKey(new QualifiedTypeDeclarationPattern(qualification, simpleName, suffix, matchRule))) { 1058 nameRequestor.acceptType(type.getFlags(), packageDeclaration, simpleName, enclosingTypeNames, path, null); 1059 } 1060 } 1061 } else { 1062 Parser basicParser = getParser(); 1063 org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) workingCopy; 1064 CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit); 1065 CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult); 1066 if (parsedUnit != null) { 1067 final char[] packageDeclaration = parsedUnit.currentPackage == null 1068 ? CharOperation.NO_CHAR 1069 : CharOperation.concatWith(parsedUnit.currentPackage.getImportName(), '.'); 1070 class AllTypeDeclarationsVisitor extends ASTVisitor { 1071 public boolean visit(TypeDeclaration typeDeclaration, BlockScope blockScope) { 1072 return false; } 1074 public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) { 1075 SearchPattern decodedPattern = 1076 new QualifiedTypeDeclarationPattern(packageDeclaration, typeDeclaration.name, convertTypeKind(TypeDeclaration.kind(typeDeclaration.modifiers)), matchRule); 1077 if (pattern.matchesDecodedKey(decodedPattern)) { 1078 nameRequestor.acceptType(typeDeclaration.modifiers, packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path, null); 1079 } 1080 return true; 1081 } 1082 public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope classScope) { 1083 char[] qualification = packageDeclaration; 1085 TypeDeclaration enclosing = memberTypeDeclaration.enclosingType; 1086 char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR; 1087 while (enclosing != null) { 1088 qualification = CharOperation.concat(qualification, enclosing.name, '.'); 1089 enclosingTypeNames = CharOperation.arrayConcat(new char[][] {enclosing.name}, enclosingTypeNames); 1090 if ((enclosing.bits & ASTNode.IsMemberType) != 0) { 1091 enclosing = enclosing.enclosingType; 1092 } else { 1093 enclosing = null; 1094 } 1095 } 1096 SearchPattern decodedPattern = 1097 new QualifiedTypeDeclarationPattern(qualification, memberTypeDeclaration.name, convertTypeKind(TypeDeclaration.kind(memberTypeDeclaration.modifiers)), matchRule); 1098 if (pattern.matchesDecodedKey(decodedPattern)) { 1099 nameRequestor.acceptType(memberTypeDeclaration.modifiers, packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path, null); 1100 } 1101 return true; 1102 } 1103 } 1104 parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope); 1105 } 1106 } 1107 } 1108 } 1109 } finally { 1110 if (progressMonitor != null) { 1111 progressMonitor.done(); 1112 } 1113 } 1114 } 1115 1116 public void searchDeclarations(IJavaElement enclosingElement, SearchRequestor requestor, SearchPattern pattern, IProgressMonitor monitor) throws JavaModelException { 1117 if (VERBOSE) { 1118 Util.verbose(" - java element: "+enclosingElement); } 1120 IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[] {enclosingElement}); 1121 IResource resource = enclosingElement.getResource(); 1122 if (enclosingElement instanceof IMember) { 1123 IMember member = (IMember) enclosingElement; 1124 ICompilationUnit cu = member.getCompilationUnit(); 1125 if (cu != null) { 1126 resource = cu.getResource(); 1127 } else if (member.isBinary()) { 1128 resource = null; 1131 } 1132 } 1133 try { 1134 if (resource instanceof IFile) { 1135 try { 1136 requestor.beginReporting(); 1137 if (VERBOSE) { 1138 Util.verbose("Searching for " + pattern + " in " + resource.getFullPath()); } 1140 SearchParticipant participant = getDefaultSearchParticipant(); 1141 SearchDocument[] documents = MatchLocator.addWorkingCopies( 1142 pattern, 1143 new SearchDocument[] {new JavaSearchDocument(enclosingElement.getPath().toString(), participant)}, 1144 getWorkingCopies(enclosingElement), 1145 participant); 1146 participant.locateMatches( 1147 documents, 1148 pattern, 1149 scope, 1150 requestor, 1151 monitor); 1152 } finally { 1153 requestor.endReporting(); 1154 } 1155 } else { 1156 search( 1157 pattern, 1158 new SearchParticipant[] {getDefaultSearchParticipant()}, 1159 scope, 1160 requestor, 1161 monitor); 1162 } 1163 } catch (CoreException e) { 1164 if (e instanceof JavaModelException) 1165 throw (JavaModelException) e; 1166 throw new JavaModelException(e); 1167 } 1168 } 1169 1170 1178 public void searchDeclarationsOfAccessedFields(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { 1179 if (VERBOSE) { 1180 Util.verbose("BasicSearchEngine.searchDeclarationsOfAccessedFields(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); } 1182 SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement); 1183 searchDeclarations(enclosingElement, requestor, pattern, monitor); 1184 } 1185 1186 1194 public void searchDeclarationsOfReferencedTypes(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { 1195 if (VERBOSE) { 1196 Util.verbose("BasicSearchEngine.searchDeclarationsOfReferencedTypes(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); } 1198 SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement); 1199 searchDeclarations(enclosingElement, requestor, pattern, monitor); 1200 } 1201 1202 1210 public void searchDeclarationsOfSentMessages(IJavaElement enclosingElement, SearchRequestor requestor, IProgressMonitor monitor) throws JavaModelException { 1211 if (VERBOSE) { 1212 Util.verbose("BasicSearchEngine.searchDeclarationsOfSentMessages(IJavaElement, SearchRequestor, SearchPattern, IProgressMonitor)"); } 1214 SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement); 1215 searchDeclarations(enclosingElement, requestor, pattern, monitor); 1216 } 1217} 1218 | Popular Tags |