1 11 package org.eclipse.jdt.internal.core; 12 13 import java.io.File ; 14 import java.util.*; 15 16 import org.eclipse.core.resources.*; 17 import org.eclipse.core.runtime.IPath; 18 import org.eclipse.core.runtime.IProgressMonitor; 19 import org.eclipse.jdt.core.IClasspathEntry; 20 import org.eclipse.jdt.core.ICompilationUnit; 21 import org.eclipse.jdt.core.IJavaElement; 22 import org.eclipse.jdt.core.IJavaProject; 23 import org.eclipse.jdt.core.IPackageFragment; 24 import org.eclipse.jdt.core.IPackageFragmentRoot; 25 import org.eclipse.jdt.core.IType; 26 import org.eclipse.jdt.core.JavaCore; 27 import org.eclipse.jdt.core.JavaModelException; 28 import org.eclipse.jdt.core.compiler.CharOperation; 29 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 30 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 31 import org.eclipse.jdt.internal.compiler.env.AccessRestriction; 32 import org.eclipse.jdt.internal.compiler.env.AccessRuleSet; 33 import org.eclipse.jdt.internal.compiler.env.IBinaryType; 34 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 35 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 36 import org.eclipse.jdt.internal.core.util.HashtableOfArrayToObject; 37 import org.eclipse.jdt.internal.core.util.Messages; 38 import org.eclipse.jdt.internal.core.util.Util; 39 40 56 public class NameLookup implements SuffixConstants { 57 public static class Answer { 58 public IType type; 59 AccessRestriction restriction; 60 Answer(IType type, AccessRestriction restriction) { 61 this.type = type; 62 this.restriction = restriction; 63 } 64 public boolean ignoreIfBetter() { 65 return this.restriction != null && this.restriction.ignoreIfBetter(); 66 } 67 72 public boolean isBetter(Answer otherAnswer) { 73 if (otherAnswer == null) return true; 74 if (this.restriction == null) return true; 75 return otherAnswer.restriction != null 76 && this.restriction.getProblemId() < otherAnswer.restriction.getProblemId(); 77 } 78 } 79 80 84 public static final int ACCEPT_CLASSES = ASTNode.Bit2; 85 86 89 public static final int ACCEPT_INTERFACES = ASTNode.Bit3; 90 91 94 public static final int ACCEPT_ENUMS = ASTNode.Bit4; 95 96 99 public static final int ACCEPT_ANNOTATIONS = ASTNode.Bit5; 100 101 104 public static final int ACCEPT_ALL = ACCEPT_CLASSES | ACCEPT_INTERFACES | ACCEPT_ENUMS | ACCEPT_ANNOTATIONS; 105 106 public static boolean VERBOSE = false; 107 108 private static final IType[] NO_TYPES = {}; 109 110 115 protected IPackageFragmentRoot[] packageFragmentRoots; 116 117 126 protected HashtableOfArrayToObject packageFragments; 127 128 132 protected Map rootToResolvedEntries; 133 134 138 protected HashMap typesInWorkingCopies; 139 140 public long timeSpentInSeekTypesInSourcePackage = 0; 141 public long timeSpentInSeekTypesInBinaryPackage = 0; 142 143 public NameLookup( 144 IPackageFragmentRoot[] packageFragmentRoots, 145 HashtableOfArrayToObject packageFragments, 146 ICompilationUnit[] workingCopies, 147 Map rootToResolvedEntries) { 148 long start = -1; 149 if (VERBOSE) { 150 Util.verbose(" BUILDING NameLoopkup"); Util.verbose(" -> pkg roots size: " + (packageFragmentRoots == null ? 0 : packageFragmentRoots.length)); Util.verbose(" -> pkgs size: " + (packageFragments == null ? 0 : packageFragments.size())); Util.verbose(" -> working copy size: " + (workingCopies == null ? 0 : workingCopies.length)); start = System.currentTimeMillis(); 155 } 156 this.packageFragmentRoots = packageFragmentRoots; 157 if (workingCopies == null) { 158 this.packageFragments = packageFragments; 159 } else { 160 try { 162 this.packageFragments = (HashtableOfArrayToObject) packageFragments.clone(); 163 } catch (CloneNotSupportedException e1) { 164 } 166 this.typesInWorkingCopies = new HashMap(); 167 for (int i = 0, length = workingCopies.length; i < length; i++) { 168 ICompilationUnit workingCopy = workingCopies[i]; 169 PackageFragment pkg = (PackageFragment) workingCopy.getParent(); 170 HashMap typeMap = (HashMap) this.typesInWorkingCopies.get(pkg); 171 if (typeMap == null) { 172 typeMap = new HashMap(); 173 this.typesInWorkingCopies.put(pkg, typeMap); 174 } 175 try { 176 IType[] types = workingCopy.getTypes(); 177 int typeLength = types.length; 178 if (typeLength == 0) { 179 String typeName = Util.getNameWithoutJavaLikeExtension(workingCopy.getElementName()); 180 typeMap.put(typeName, NO_TYPES); 181 } else { 182 for (int j = 0; j < typeLength; j++) { 183 IType type = types[j]; 184 String typeName = type.getElementName(); 185 Object existing = typeMap.get(typeName); 186 if (existing == null) { 187 typeMap.put(typeName, type); 188 } else if (existing instanceof IType) { 189 typeMap.put(typeName, new IType[] {(IType) existing, type}); 190 } else { 191 IType[] existingTypes = (IType[]) existing; 192 int existingTypeLength = existingTypes.length; 193 System.arraycopy(existingTypes, 0, existingTypes = new IType[existingTypeLength+1], 0, existingTypeLength); 194 existingTypes[existingTypeLength] = type; 195 typeMap.put(typeName, existingTypes); 196 } 197 } 198 } 199 } catch (JavaModelException e) { 200 } 202 203 IPackageFragmentRoot root = (IPackageFragmentRoot) pkg.getParent(); 205 String [] pkgName = pkg.names; 206 Object existing = this.packageFragments.get(pkgName); 207 if (existing == null || existing == JavaProjectElementInfo.NO_ROOTS) { 208 this.packageFragments.put(pkgName, root); 209 JavaProjectElementInfo.addSuperPackageNames(pkgName, this.packageFragments); 212 } else { 213 if (existing instanceof PackageFragmentRoot) { 214 if (!existing.equals(root)) 215 this.packageFragments.put(pkgName, new IPackageFragmentRoot[] {(PackageFragmentRoot) existing, root}); 216 } else { 217 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) existing; 218 int rootLength = roots.length; 219 boolean containsRoot = false; 220 for (int j = 0; j < rootLength; j++) { 221 if (roots[j].equals(root)) { 222 containsRoot = true; 223 break; 224 } 225 } 226 if (containsRoot) { 227 System.arraycopy(roots, 0, roots = new IPackageFragmentRoot[rootLength+1], 0, rootLength); 228 roots[rootLength] = root; 229 this.packageFragments.put(pkgName, roots); 230 } 231 } 232 } 233 } 234 } 235 236 this.rootToResolvedEntries = rootToResolvedEntries; 237 if (VERBOSE) { 238 Util.verbose(" -> spent: " + (System.currentTimeMillis() - start) + "ms"); } 240 } 241 242 253 protected boolean acceptType(IType type, int acceptFlags, boolean isSourceType) { 254 if (acceptFlags == 0 || acceptFlags == ACCEPT_ALL) 255 return true; try { 257 int kind = isSourceType 258 ? TypeDeclaration.kind(((SourceTypeElementInfo) ((SourceType) type).getElementInfo()).getModifiers()) 259 : TypeDeclaration.kind(((IBinaryType) ((BinaryType) type).getElementInfo()).getModifiers()); 260 switch (kind) { 261 case TypeDeclaration.CLASS_DECL : 262 return (acceptFlags & ACCEPT_CLASSES) != 0; 263 case TypeDeclaration.INTERFACE_DECL : 264 return (acceptFlags & ACCEPT_INTERFACES) != 0; 265 case TypeDeclaration.ENUM_DECL : 266 return (acceptFlags & ACCEPT_ENUMS) != 0; 267 default: 268 return (acceptFlags & ACCEPT_ANNOTATIONS) != 0; 270 } 271 } catch (JavaModelException npe) { 272 return false; } 274 } 275 276 284 private void findAllTypes(String prefix, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { 285 int count= this.packageFragmentRoots.length; 286 for (int i= 0; i < count; i++) { 287 if (requestor.isCanceled()) 288 return; 289 IPackageFragmentRoot root= this.packageFragmentRoots[i]; 290 IJavaElement[] packages= null; 291 try { 292 packages= root.getChildren(); 293 } catch (JavaModelException npe) { 294 continue; } 296 if (packages != null) { 297 for (int j= 0, packageCount= packages.length; j < packageCount; j++) { 298 if (requestor.isCanceled()) 299 return; 300 seekTypes(prefix, (IPackageFragment) packages[j], partialMatch, acceptFlags, requestor); 301 } 302 } 303 } 304 } 305 306 315 public ICompilationUnit findCompilationUnit(String qualifiedTypeName) { 316 String [] pkgName = CharOperation.NO_STRINGS; 317 String cuName = qualifiedTypeName; 318 319 int index= qualifiedTypeName.lastIndexOf('.'); 320 if (index != -1) { 321 pkgName= Util.splitOn('.', qualifiedTypeName, 0, index); 322 cuName= qualifiedTypeName.substring(index + 1); 323 } 324 index= cuName.indexOf('$'); 325 if (index != -1) { 326 cuName= cuName.substring(0, index); 327 } 328 Object value = this.packageFragments.get(pkgName); 329 if (value != null) { 330 if (value instanceof PackageFragmentRoot) { 331 return findCompilationUnit(pkgName, cuName, (PackageFragmentRoot) value); 332 } else { 333 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; 334 for (int i= 0; i < roots.length; i++) { 335 PackageFragmentRoot root= (PackageFragmentRoot) roots[i]; 336 ICompilationUnit cu = findCompilationUnit(pkgName, cuName, root); 337 if (cu != null) 338 return cu; 339 } 340 } 341 } 342 return null; 343 } 344 345 private ICompilationUnit findCompilationUnit(String [] pkgName, String cuName, PackageFragmentRoot root) { 346 if (!root.isArchive()) { 347 IPackageFragment pkg = root.getPackageFragment(pkgName); 348 try { 349 ICompilationUnit[] cus = pkg.getCompilationUnits(); 350 for (int j = 0, length = cus.length; j < length; j++) { 351 ICompilationUnit cu = cus[j]; 352 if (Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), cuName)) 353 return cu; 354 } 355 } catch (JavaModelException e) { 356 } 359 } 360 return null; 361 } 362 363 372 public IPackageFragment findPackageFragment(IPath path) { 373 if (!path.isAbsolute()) { 374 throw new IllegalArgumentException (Messages.path_mustBeAbsolute); 375 } 376 380 IResource possibleFragment = ResourcesPlugin.getWorkspace().getRoot().findMember(path); 381 if (possibleFragment == null) { 382 for (int i = 0; i < this.packageFragmentRoots.length; i++) { 384 IPackageFragmentRoot root = this.packageFragmentRoots[i]; 385 if (!root.isExternal()) { 386 continue; 387 } 388 IPath rootPath = root.getPath(); 389 int matchingCount = rootPath.matchingFirstSegments(path); 390 if (matchingCount != 0) { 391 String name = path.toOSString(); 392 name = name.substring(rootPath.toOSString().length() + 1, name.length()); 394 name = name.replace(File.separatorChar, '.'); 395 IJavaElement[] list = null; 396 try { 397 list = root.getChildren(); 398 } catch (JavaModelException npe) { 399 continue; } 401 int elementCount = list.length; 402 for (int j = 0; j < elementCount; j++) { 403 IPackageFragment packageFragment = (IPackageFragment) list[j]; 404 if (nameMatches(name, packageFragment, false)) { 405 return packageFragment; 406 } 407 } 408 } 409 } 410 } else { 411 IJavaElement fromFactory = JavaCore.create(possibleFragment); 412 if (fromFactory == null) { 413 return null; 414 } 415 switch (fromFactory.getElementType()) { 416 case IJavaElement.PACKAGE_FRAGMENT: 417 return (IPackageFragment) fromFactory; 418 case IJavaElement.JAVA_PROJECT: 419 JavaProject project = (JavaProject) fromFactory; 421 try { 422 IClasspathEntry entry = project.getClasspathEntryFor(path); 423 if (entry != null) { 424 IPackageFragmentRoot root = 425 project.getPackageFragmentRoot(project.getResource()); 426 Object defaultPkgRoot = this.packageFragments.get(CharOperation.NO_STRINGS); 427 if (defaultPkgRoot == null) { 428 return null; 429 } 430 if (defaultPkgRoot instanceof PackageFragmentRoot && defaultPkgRoot.equals(root)) 431 return ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS); 432 else { 433 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) defaultPkgRoot; 434 for (int i = 0; i < roots.length; i++) { 435 if (roots[i].equals(root)) { 436 return ((PackageFragmentRoot) root).getPackageFragment(CharOperation.NO_STRINGS); 437 } 438 } 439 } 440 } 441 } catch (JavaModelException e) { 442 return null; 443 } 444 return null; 445 case IJavaElement.PACKAGE_FRAGMENT_ROOT: 446 return ((PackageFragmentRoot)fromFactory).getPackageFragment(CharOperation.NO_STRINGS); 447 } 448 } 449 return null; 450 } 451 452 464 public IPackageFragment[] findPackageFragments(String name, boolean partialMatch) { 465 return findPackageFragments(name, partialMatch, false); 466 } 467 468 482 public IPackageFragment[] findPackageFragments(String name, boolean partialMatch, boolean patternMatch) { 483 boolean hasPatternChars = patternMatch && (name.indexOf('*') >= 0 || name.indexOf('?') >= 0); 484 if (partialMatch || hasPatternChars) { 485 String [] splittedName = Util.splitOn('.', name, 0, name.length()); 486 IPackageFragment[] oneFragment = null; 487 ArrayList pkgs = null; 488 Object [][] keys = this.packageFragments.keyTable; 489 for (int i = 0, length = keys.length; i < length; i++) { 490 String [] pkgName = (String []) keys[i]; 491 if (pkgName != null) { 492 boolean match = hasPatternChars 493 ? Util.matchesWithIgnoreCase(pkgName, name) 494 : Util.startsWithIgnoreCase(pkgName, splittedName, partialMatch); 495 if (match) { 496 Object value = this.packageFragments.valueTable[i]; 497 if (value instanceof PackageFragmentRoot) { 498 IPackageFragment pkg = ((PackageFragmentRoot) value).getPackageFragment(pkgName); 499 if (oneFragment == null) { 500 oneFragment = new IPackageFragment[] {pkg}; 501 } else { 502 if (pkgs == null) { 503 pkgs = new ArrayList(); 504 pkgs.add(oneFragment[0]); 505 } 506 pkgs.add(pkg); 507 } 508 } else { 509 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; 510 for (int j = 0, length2 = roots.length; j < length2; j++) { 511 PackageFragmentRoot root = (PackageFragmentRoot) roots[j]; 512 IPackageFragment pkg = root.getPackageFragment(pkgName); 513 if (oneFragment == null) { 514 oneFragment = new IPackageFragment[] {pkg}; 515 } else { 516 if (pkgs == null) { 517 pkgs = new ArrayList(); 518 pkgs.add(oneFragment[0]); 519 } 520 pkgs.add(pkg); 521 } 522 } 523 } 524 } 525 } 526 } 527 if (pkgs == null) return oneFragment; 528 int resultLength = pkgs.size(); 529 IPackageFragment[] result = new IPackageFragment[resultLength]; 530 pkgs.toArray(result); 531 return result; 532 } else { 533 String [] splittedName = Util.splitOn('.', name, 0, name.length()); 534 Object value = this.packageFragments.get(splittedName); 535 if (value == null) 536 return null; 537 if (value instanceof PackageFragmentRoot) { 538 return new IPackageFragment[] {((PackageFragmentRoot) value).getPackageFragment(splittedName)}; 539 } else { 540 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; 541 IPackageFragment[] result = new IPackageFragment[roots.length]; 542 for (int i= 0; i < roots.length; i++) { 543 result[i] = ((PackageFragmentRoot) roots[i]).getPackageFragment(splittedName); 544 } 545 return result; 546 } 547 } 548 } 549 550 553 private IType findSecondaryType(String packageName, String typeName, IJavaProject project, boolean waitForIndexes, IProgressMonitor monitor) { 554 if (JavaModelManager.VERBOSE) { 555 Util.verbose("NameLookup FIND SECONDARY TYPES:"); Util.verbose(" -> pkg name: " + packageName); Util.verbose(" -> type name: " + typeName); Util.verbose(" -> project: "+project.getElementName()); } 560 JavaModelManager manager = JavaModelManager.getJavaModelManager(); 561 try { 562 IJavaProject javaProject = project; 563 Map secondaryTypePaths = manager.secondaryTypes(javaProject, waitForIndexes, monitor); 564 if (secondaryTypePaths.size() > 0) { 565 Map types = (Map) secondaryTypePaths.get(packageName==null?"":packageName); if (types != null && types.size() > 0) { 567 IType type = (IType) types.get(typeName); 568 if (type != null) { 569 if (JavaModelManager.VERBOSE) { 570 Util.verbose(" -> type: " + type.getElementName()); } 572 return type; 573 } 574 } 575 } 576 } 577 catch (JavaModelException jme) { 578 } 580 return null; 581 } 582 583 588 public Answer findType(String typeName, String packageName, boolean partialMatch, int acceptFlags, boolean checkRestrictions) { 589 return findType(typeName, 590 packageName, 591 partialMatch, 592 acceptFlags, 593 true, 594 false, 595 checkRestrictions, 596 null); 597 } 598 599 602 public Answer findType( 603 String typeName, 604 String packageName, 605 boolean partialMatch, 606 int acceptFlags, 607 boolean considerSecondaryTypes, 608 boolean waitForIndexes, 609 boolean checkRestrictions, 610 IProgressMonitor monitor) { 611 if (packageName == null || packageName.length() == 0) { 612 packageName= IPackageFragment.DEFAULT_PACKAGE_NAME; 613 } else if (typeName.length() > 0 && ScannerHelper.isLowerCase(typeName.charAt(0))) { 614 if (findPackageFragments(packageName + "." + typeName, false) != null) return null; } 617 618 JavaElementRequestor elementRequestor = new JavaElementRequestor(); 620 seekPackageFragments(packageName, false, elementRequestor); 621 IPackageFragment[] packages= elementRequestor.getPackageFragments(); 622 623 IType type = null; 625 int length= packages.length; 626 HashSet projects = null; 627 IJavaProject javaProject = null; 628 Answer suggestedAnswer = null; 629 for (int i= 0; i < length; i++) { 630 type = findType(typeName, packages[i], partialMatch, acceptFlags); 631 if (type != null) { 632 AccessRestriction accessRestriction = null; 633 if (checkRestrictions) { 634 accessRestriction = getViolatedRestriction(typeName, packageName, type, accessRestriction); 635 } 636 Answer answer = new Answer(type, accessRestriction); 637 if (!answer.ignoreIfBetter()) { 638 if (answer.isBetter(suggestedAnswer)) 639 return answer; 640 } else if (answer.isBetter(suggestedAnswer)) 641 suggestedAnswer = answer; 643 } 644 else if (suggestedAnswer == null && considerSecondaryTypes) { 645 if (javaProject == null) { 646 javaProject = packages[i].getJavaProject(); 647 } else if (projects == null) { 648 if (!javaProject.equals(packages[i].getJavaProject())) { 649 projects = new HashSet(3); 650 projects.add(javaProject); 651 projects.add(packages[i].getJavaProject()); 652 } 653 } else { 654 projects.add(packages[i].getJavaProject()); 655 } 656 } 657 } 658 if (suggestedAnswer != null) 659 return suggestedAnswer; 661 662 if (considerSecondaryTypes && javaProject != null) { 664 if (projects == null) { 665 type = findSecondaryType(packageName, typeName, javaProject, waitForIndexes, monitor); 666 } else { 667 Iterator allProjects = projects.iterator(); 668 while (type == null && allProjects.hasNext()) { 669 type = findSecondaryType(packageName, typeName, (IJavaProject) allProjects.next(), waitForIndexes, monitor); 670 } 671 } 672 } 673 return type == null ? null : new Answer(type, null); 674 } 675 676 private AccessRestriction getViolatedRestriction(String typeName, String packageName, IType type, AccessRestriction accessRestriction) { 677 PackageFragmentRoot root = (PackageFragmentRoot) type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); 678 ClasspathEntry entry = (ClasspathEntry) this.rootToResolvedEntries.get(root); 679 if (entry != null) { AccessRuleSet accessRuleSet = entry.getAccessRuleSet(); 681 if (accessRuleSet != null) { 682 char[][] packageChars = CharOperation.splitOn('.', packageName.toCharArray()); 684 char[] typeChars = typeName.toCharArray(); 685 accessRestriction = accessRuleSet.getViolatedRestriction(CharOperation.concatWith(packageChars, typeChars, '/')); 686 } 687 } 688 return accessRestriction; 689 } 690 691 712 public IType findType(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, boolean considerSecondaryTypes) { 713 IType type = findType(name, pkg, partialMatch, acceptFlags); 714 if (type == null && considerSecondaryTypes) { 715 type = findSecondaryType(pkg.getElementName(), name, pkg.getJavaProject(), false, null); 716 } 717 return type; 718 } 719 720 741 public IType findType(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags) { 742 if (pkg == null) return null; 743 744 SingleTypeRequestor typeRequestor = new SingleTypeRequestor(); 746 seekTypes(name, pkg, partialMatch, acceptFlags, typeRequestor); 747 return typeRequestor.getType(); 748 } 749 750 766 public IType findType(String name, boolean partialMatch, int acceptFlags) { 767 NameLookup.Answer answer = findType(name, partialMatch, acceptFlags, false); 768 return answer == null ? null : answer.type; 769 } 770 771 public Answer findType(String name, boolean partialMatch, int acceptFlags, boolean checkRestrictions) { 772 return findType(name, partialMatch, acceptFlags, true, true, checkRestrictions, null); 773 } 774 public Answer findType(String name, boolean partialMatch, int acceptFlags, boolean considerSecondaryTypes, boolean waitForIndexes, boolean checkRestrictions, IProgressMonitor monitor) { 775 int index= name.lastIndexOf('.'); 776 String className= null, packageName= null; 777 if (index == -1) { 778 packageName= IPackageFragment.DEFAULT_PACKAGE_NAME; 779 className= name; 780 } else { 781 packageName= name.substring(0, index); 782 className= name.substring(index + 1); 783 } 784 return findType(className, packageName, partialMatch, acceptFlags, considerSecondaryTypes, waitForIndexes, checkRestrictions, monitor); 785 } 786 787 private IType getMemberType(IType type, String name, int dot) { 788 while (dot != -1) { 789 int start = dot+1; 790 dot = name.indexOf('.', start); 791 String typeName = name.substring(start, dot == -1 ? name.length() : dot); 792 type = type.getType(typeName); 793 } 794 return type; 795 } 796 797 public boolean isPackage(String [] pkgName) { 798 return this.packageFragments.get(pkgName) != null; 799 } 800 801 810 protected boolean nameMatches(String searchName, IJavaElement element, boolean partialMatch) { 811 if (partialMatch) { 812 return element.getElementName().toLowerCase().startsWith(searchName); 814 } else { 815 return element.getElementName().equals(searchName); 816 } 817 } 818 819 828 protected boolean nameMatches(String searchName, ICompilationUnit cu, boolean partialMatch) { 829 if (partialMatch) { 830 return cu.getElementName().toLowerCase().startsWith(searchName); 832 } else { 833 return Util.equalsIgnoreJavaLikeExtension(cu.getElementName(), searchName); 834 } 835 } 836 837 847 public void seekPackageFragments(String name, boolean partialMatch, IJavaElementRequestor requestor) { 848 if (partialMatch) { 854 String [] splittedName = Util.splitOn('.', name, 0, name.length()); 855 Object [][] keys = this.packageFragments.keyTable; 856 for (int i = 0, length = keys.length; i < length; i++) { 857 if (requestor.isCanceled()) 858 return; 859 String [] pkgName = (String []) keys[i]; 860 if (pkgName != null && Util.startsWithIgnoreCase(pkgName, splittedName, partialMatch)) { 861 Object value = this.packageFragments.valueTable[i]; 862 if (value instanceof PackageFragmentRoot) { 863 PackageFragmentRoot root = (PackageFragmentRoot) value; 864 requestor.acceptPackageFragment(root.getPackageFragment(pkgName)); 865 } else { 866 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; 867 for (int j = 0, length2 = roots.length; j < length2; j++) { 868 if (requestor.isCanceled()) 869 return; 870 PackageFragmentRoot root = (PackageFragmentRoot) roots[j]; 871 requestor.acceptPackageFragment(root.getPackageFragment(pkgName)); 872 } 873 } 874 } 875 } 876 } else { 877 String [] splittedName = Util.splitOn('.', name, 0, name.length()); 878 Object value = this.packageFragments.get(splittedName); 879 if (value instanceof PackageFragmentRoot) { 880 requestor.acceptPackageFragment(((PackageFragmentRoot) value).getPackageFragment(splittedName)); 881 } else { 882 IPackageFragmentRoot[] roots = (IPackageFragmentRoot[]) value; 883 if (roots != null) { 884 for (int i = 0, length = roots.length; i < length; i++) { 885 if (requestor.isCanceled()) 886 return; 887 PackageFragmentRoot root = (PackageFragmentRoot) roots[i]; 888 requestor.acceptPackageFragment(root.getPackageFragment(splittedName)); 889 } 890 } 891 } 892 } 893 } 894 895 915 public void seekTypes(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { 916 923 String matchName= partialMatch ? name.toLowerCase() : name; 924 if (pkg == null) { 925 findAllTypes(matchName, partialMatch, acceptFlags, requestor); 926 return; 927 } 928 IPackageFragmentRoot root= (IPackageFragmentRoot) pkg.getParent(); 929 try { 930 931 int firstDot = -1; 933 String topLevelTypeName = null; 934 int packageFlavor= root.getKind(); 935 if (this.typesInWorkingCopies != null || packageFlavor == IPackageFragmentRoot.K_SOURCE) { 936 firstDot = matchName.indexOf('.'); 937 if (!partialMatch) 938 topLevelTypeName = firstDot == -1 ? matchName : matchName.substring(0, firstDot); 939 } 940 if (this.typesInWorkingCopies != null) { 941 if (seekTypesInWorkingCopies(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor)) 942 return; 943 } 944 945 switch (packageFlavor) { 947 case IPackageFragmentRoot.K_BINARY : 948 matchName= matchName.replace('.', '$'); 949 seekTypesInBinaryPackage(matchName, pkg, partialMatch, acceptFlags, requestor); 950 break; 951 case IPackageFragmentRoot.K_SOURCE : 952 seekTypesInSourcePackage(matchName, pkg, firstDot, partialMatch, topLevelTypeName, acceptFlags, requestor); 953 break; 954 default : 955 return; 956 } 957 } catch (JavaModelException e) { 958 return; 959 } 960 } 961 962 965 protected void seekTypesInBinaryPackage(String name, IPackageFragment pkg, boolean partialMatch, int acceptFlags, IJavaElementRequestor requestor) { 966 long start = -1; 967 if (VERBOSE) 968 start = System.currentTimeMillis(); 969 try { 970 if (!partialMatch) { 971 if (requestor.isCanceled()) return; 973 ClassFile classFile = new ClassFile((PackageFragment) pkg, name); 974 if (classFile.existsUsingJarTypeCache()) { 975 IType type = classFile.getType(); 976 if (acceptType(type, acceptFlags, false)) { 977 requestor.acceptType(type); 978 } 979 } 980 } else { 981 IJavaElement[] classFiles= null; 982 try { 983 classFiles= pkg.getChildren(); 984 } catch (JavaModelException npe) { 985 return; } 987 int length= classFiles.length; 988 String unqualifiedName = name; 989 int index = name.lastIndexOf('$'); 990 if (index != -1) { 991 unqualifiedName = Util.localTypeName(name, index, name.length()); 993 } 996 int matchLength = name.length(); 997 for (int i = 0; i < length; i++) { 998 if (requestor.isCanceled()) 999 return; 1000 IJavaElement classFile= classFiles[i]; 1001 String elementName = classFile.getElementName(); 1003 if (elementName.regionMatches(true , 0, name, 0, matchLength)) { 1004 IType type = ((ClassFile) classFile).getType(); 1005 String typeName = type.getElementName(); 1006 if (typeName.length() > 0 && !Character.isDigit(typeName.charAt(0))) { if (nameMatches(unqualifiedName, type, true) && acceptType(type, acceptFlags, false)) 1008 requestor.acceptType(type); 1009 } 1010 } 1011 } 1012 } 1013 } finally { 1014 if (VERBOSE) 1015 this.timeSpentInSeekTypesInBinaryPackage += System.currentTimeMillis()-start; 1016 } 1017 } 1018 1019 1022 protected void seekTypesInSourcePackage( 1023 String name, 1024 IPackageFragment pkg, 1025 int firstDot, 1026 boolean partialMatch, 1027 String topLevelTypeName, 1028 int acceptFlags, 1029 IJavaElementRequestor requestor) { 1030 1031 long start = -1; 1032 if (VERBOSE) 1033 start = System.currentTimeMillis(); 1034 try { 1035 if (!partialMatch) { 1036 try { 1037 IJavaElement[] compilationUnits = pkg.getChildren(); 1038 for (int i = 0, length = compilationUnits.length; i < length; i++) { 1039 if (requestor.isCanceled()) 1040 return; 1041 IJavaElement cu = compilationUnits[i]; 1042 String cuName = cu.getElementName(); 1043 int lastDot = cuName.lastIndexOf('.'); 1044 if (lastDot != topLevelTypeName.length() || !topLevelTypeName.regionMatches(0, cuName, 0, lastDot)) 1045 continue; 1046 IType type = ((ICompilationUnit) cu).getType(topLevelTypeName); 1047 type = getMemberType(type, name, firstDot); 1048 if (acceptType(type, acceptFlags, true)) { requestor.acceptType(type); 1050 break; } 1052 } 1053 } catch (JavaModelException e) { 1054 } 1056 } else { 1057 try { 1058 String cuPrefix = firstDot == -1 ? name : name.substring(0, firstDot); 1059 IJavaElement[] compilationUnits = pkg.getChildren(); 1060 for (int i = 0, length = compilationUnits.length; i < length; i++) { 1061 if (requestor.isCanceled()) 1062 return; 1063 IJavaElement cu = compilationUnits[i]; 1064 if (!cu.getElementName().toLowerCase().startsWith(cuPrefix)) 1065 continue; 1066 try { 1067 IType[] types = ((ICompilationUnit) cu).getTypes(); 1068 for (int j = 0, typeLength = types.length; j < typeLength; j++) 1069 seekTypesInTopLevelType(name, firstDot, types[j], requestor, acceptFlags); 1070 } catch (JavaModelException e) { 1071 } 1073 } 1074 } catch (JavaModelException e) { 1075 } 1077 } 1078 } finally { 1079 if (VERBOSE) 1080 this.timeSpentInSeekTypesInSourcePackage += System.currentTimeMillis()-start; 1081 } 1082 } 1083 1084 1090 protected boolean seekTypesInType(String prefix, int firstDot, IType type, IJavaElementRequestor requestor, int acceptFlags) { 1091 IType[] types= null; 1092 try { 1093 types= type.getTypes(); 1094 } catch (JavaModelException npe) { 1095 return false; } 1097 int length= types.length; 1098 if (length == 0) return false; 1099 1100 String memberPrefix = prefix; 1101 boolean isMemberTypePrefix = false; 1102 if (firstDot != -1) { 1103 memberPrefix= prefix.substring(0, firstDot); 1104 isMemberTypePrefix = true; 1105 } 1106 for (int i= 0; i < length; i++) { 1107 if (requestor.isCanceled()) 1108 return false; 1109 IType memberType= types[i]; 1110 if (memberType.getElementName().toLowerCase().startsWith(memberPrefix)) 1111 if (isMemberTypePrefix) { 1112 String subPrefix = prefix.substring(firstDot + 1, prefix.length()); 1113 return seekTypesInType(subPrefix, subPrefix.indexOf('.'), memberType, requestor, acceptFlags); 1114 } else { 1115 if (acceptType(memberType, acceptFlags, true)) { 1116 requestor.acceptMemberType(memberType); 1117 return true; 1118 } 1119 } 1120 } 1121 return false; 1122 } 1123 1124 protected boolean seekTypesInTopLevelType(String prefix, int firstDot, IType topLevelType, IJavaElementRequestor requestor, int acceptFlags) { 1125 if (!topLevelType.getElementName().toLowerCase().startsWith(prefix)) 1126 return false; 1127 if (firstDot == -1) { 1128 if (acceptType(topLevelType, acceptFlags, true)) { 1129 requestor.acceptType(topLevelType); 1130 return true; 1131 } 1132 } else { 1133 return seekTypesInType(prefix, firstDot, topLevelType, requestor, acceptFlags); 1134 } 1135 return false; 1136 } 1137 1138 1142 protected boolean seekTypesInWorkingCopies( 1143 String name, 1144 IPackageFragment pkg, 1145 int firstDot, 1146 boolean partialMatch, 1147 String topLevelTypeName, 1148 int acceptFlags, 1149 IJavaElementRequestor requestor) { 1150 1151 if (!partialMatch) { 1152 HashMap typeMap = (HashMap) (this.typesInWorkingCopies == null ? null : this.typesInWorkingCopies.get(pkg)); 1153 if (typeMap != null) { 1154 Object object = typeMap.get(topLevelTypeName); 1155 if (object instanceof IType) { 1156 IType type = getMemberType((IType) object, name, firstDot); 1157 if (acceptType(type, acceptFlags, true)) { 1158 requestor.acceptType(type); 1159 return true; } 1161 } else if (object instanceof IType[]) { 1162 if (object == NO_TYPES) return true; IType[] topLevelTypes = (IType[]) object; 1164 for (int i = 0, length = topLevelTypes.length; i < length; i++) { 1165 if (requestor.isCanceled()) 1166 return false; 1167 IType type = getMemberType(topLevelTypes[i], name, firstDot); 1168 if (acceptType(type, acceptFlags, true)) { 1169 requestor.acceptType(type); 1170 return true; } 1172 } 1173 } 1174 } 1175 } else { 1176 HashMap typeMap = (HashMap) (this.typesInWorkingCopies == null ? null : this.typesInWorkingCopies.get(pkg)); 1177 if (typeMap != null) { 1178 Iterator iterator = typeMap.values().iterator(); 1179 while (iterator.hasNext()) { 1180 if (requestor.isCanceled()) 1181 return false; 1182 Object object = iterator.next(); 1183 if (object instanceof IType) { 1184 seekTypesInTopLevelType(name, firstDot, (IType) object, requestor, acceptFlags); 1185 } else if (object instanceof IType[]) { 1186 IType[] topLevelTypes = (IType[]) object; 1187 for (int i = 0, length = topLevelTypes.length; i < length; i++) 1188 seekTypesInTopLevelType(name, firstDot, topLevelTypes[i], requestor, acceptFlags); 1189 } 1190 } 1191 } 1192 } 1193 return false; 1194 } 1195 1196} 1197 | Popular Tags |