1 11 package org.eclipse.jdt.internal.core.search.matching; 12 13 import org.eclipse.core.runtime.*; 14 import org.eclipse.jdt.core.*; 15 import org.eclipse.jdt.core.compiler.*; 16 import org.eclipse.jdt.core.search.*; 17 import org.eclipse.jdt.internal.compiler.ast.*; 18 import org.eclipse.jdt.internal.compiler.lookup.*; 19 import org.eclipse.jdt.internal.core.search.indexing.IIndexConstants; 20 21 public abstract class PatternLocator implements IIndexConstants { 22 23 protected int matchMode; 25 protected boolean isCaseSensitive; 26 protected boolean isCamelCase; 27 protected boolean isEquivalentMatch; 28 protected boolean isErasureMatch; 29 protected boolean mustResolve; 30 protected boolean mayBeGeneric; 31 32 SearchMatch match = null; 34 35 36 public static final int IMPOSSIBLE_MATCH = 0; 37 public static final int INACCURATE_MATCH = 1; 38 public static final int POSSIBLE_MATCH = 2; 39 public static final int ACCURATE_MATCH = 3; 40 public static final int ERASURE_MATCH = 4; 41 42 public static final int EXACT_FLAVOR = 0x0010; 45 public static final int PREFIX_FLAVOR = 0x0020; 46 public static final int PATTERN_FLAVOR = 0x0040; 47 public static final int REGEXP_FLAVOR = 0x0080; 48 public static final int CAMELCASE_FLAVOR = 0x0100; 49 public static final int SUPER_INVOCATION_FLAVOR = 0x0200; 50 public static final int SUB_INVOCATION_FLAVOR = 0x0400; 51 public static final int OVERRIDDEN_METHOD_FLAVOR = 0x0800; 52 public static final int MATCH_LEVEL_MASK = 0x0F; 53 public static final int FLAVORS_MASK = ~MATCH_LEVEL_MASK; 54 55 56 public static final int COMPILATION_UNIT_CONTAINER = 1; 57 public static final int CLASS_CONTAINER = 2; 58 public static final int METHOD_CONTAINER = 4; 59 public static final int FIELD_CONTAINER = 8; 60 public static final int ALL_CONTAINER = 61 COMPILATION_UNIT_CONTAINER | CLASS_CONTAINER | METHOD_CONTAINER | FIELD_CONTAINER; 62 63 64 public static final int RAW_MASK = SearchPattern.R_EQUIVALENT_MATCH | SearchPattern.R_ERASURE_MATCH; 65 public static final int RULE_MASK = RAW_MASK; 67 public static PatternLocator patternLocator(SearchPattern pattern) { 68 switch (((InternalSearchPattern)pattern).kind) { 69 case IIndexConstants.PKG_REF_PATTERN : 70 return new PackageReferenceLocator((PackageReferencePattern) pattern); 71 case IIndexConstants.PKG_DECL_PATTERN : 72 return new PackageDeclarationLocator((PackageDeclarationPattern) pattern); 73 case IIndexConstants.TYPE_REF_PATTERN : 74 return new TypeReferenceLocator((TypeReferencePattern) pattern); 75 case IIndexConstants.TYPE_DECL_PATTERN : 76 return new TypeDeclarationLocator((TypeDeclarationPattern) pattern); 77 case IIndexConstants.SUPER_REF_PATTERN : 78 return new SuperTypeReferenceLocator((SuperTypeReferencePattern) pattern); 79 case IIndexConstants.CONSTRUCTOR_PATTERN : 80 return new ConstructorLocator((ConstructorPattern) pattern); 81 case IIndexConstants.FIELD_PATTERN : 82 return new FieldLocator((FieldPattern) pattern); 83 case IIndexConstants.METHOD_PATTERN : 84 return new MethodLocator((MethodPattern) pattern); 85 case IIndexConstants.OR_PATTERN : 86 return new OrLocator((OrPattern) pattern); 87 case IIndexConstants.LOCAL_VAR_PATTERN : 88 return new LocalVariableLocator((LocalVariablePattern) pattern); 89 case IIndexConstants.TYPE_PARAM_PATTERN: 90 return new TypeParameterLocator((TypeParameterPattern) pattern); 91 } 92 return null; 93 } 94 public static char[] qualifiedPattern(char[] simpleNamePattern, char[] qualificationPattern) { 95 if (simpleNamePattern == null) { 97 if (qualificationPattern == null) return null; 98 return CharOperation.concat(qualificationPattern, ONE_STAR, '.'); 99 } else { 100 return qualificationPattern == null 101 ? CharOperation.concat(ONE_STAR, simpleNamePattern) 102 : CharOperation.concat(qualificationPattern, simpleNamePattern, '.'); 103 } 104 } 105 public static char[] qualifiedSourceName(TypeBinding binding) { 106 if (binding instanceof ReferenceBinding) { 107 ReferenceBinding type = (ReferenceBinding) binding; 108 if (type.isLocalType()) 109 return type.isMemberType() 110 ? CharOperation.concat(qualifiedSourceName(type.enclosingType()), type.sourceName(), '.') 111 : CharOperation.concat(qualifiedSourceName(type.enclosingType()), new char[] {'.', '1', '.'}, type.sourceName()); 112 } 113 return binding != null ? binding.qualifiedSourceName() : null; 114 } 115 116 public PatternLocator(SearchPattern pattern) { 117 int matchRule = pattern.getMatchRule(); 118 this.isCaseSensitive = (matchRule & SearchPattern.R_CASE_SENSITIVE) != 0; 119 this.isCamelCase = (matchRule & SearchPattern.R_CAMELCASE_MATCH) != 0; 120 this.isErasureMatch = (matchRule & SearchPattern.R_ERASURE_MATCH) != 0; 121 this.isEquivalentMatch = (matchRule & SearchPattern.R_EQUIVALENT_MATCH) != 0; 122 this.matchMode = matchRule & JavaSearchPattern.MATCH_MODE_MASK; 123 this.mustResolve = ((InternalSearchPattern)pattern).mustResolve; 124 } 125 128 protected void clear() { 129 } 131 136 protected char[] getQualifiedPattern(char[] simpleNamePattern, char[] qualificationPattern) { 137 if (simpleNamePattern == null) { 139 if (qualificationPattern == null) return null; 140 return CharOperation.concat(qualificationPattern, ONE_STAR, '.'); 141 } else if (qualificationPattern == null) { 142 return simpleNamePattern; 143 } else { 144 return CharOperation.concat(qualificationPattern, simpleNamePattern, '.'); 145 } 146 } 147 151 protected char[] getQualifiedSourceName(TypeBinding binding) { 152 TypeBinding type = binding instanceof ArrayBinding ? ((ArrayBinding)binding).leafComponentType : binding; 153 if (type instanceof ReferenceBinding) { 154 if (type.isLocalType()) { 155 return CharOperation.concat(qualifiedSourceName(type.enclosingType()), new char[] {'.', '1', '.'}, binding.sourceName()); 156 } else if (type.isMemberType()) { 157 return CharOperation.concat(qualifiedSourceName(type.enclosingType()), binding.sourceName(), '.'); 158 } 159 } 160 return binding != null ? binding.qualifiedSourceName() : null; 161 } 162 167 protected TypeBinding getTypeNameBinding(int index) { 168 return null; 169 } 170 173 public void initializePolymorphicSearch(MatchLocator locator) { 174 } 176 public int match(Annotation node, MatchingNodeSet nodeSet) { 177 return IMPOSSIBLE_MATCH; 179 } 180 185 public int match(ASTNode node, MatchingNodeSet nodeSet) { return IMPOSSIBLE_MATCH; 188 } 189 public int match(ConstructorDeclaration node, MatchingNodeSet nodeSet) { 190 return IMPOSSIBLE_MATCH; 192 } 193 public int match(Expression node, MatchingNodeSet nodeSet) { 194 return IMPOSSIBLE_MATCH; 196 } 197 public int match(FieldDeclaration node, MatchingNodeSet nodeSet) { 198 return IMPOSSIBLE_MATCH; 200 } 201 public int match(LocalDeclaration node, MatchingNodeSet nodeSet) { 202 return IMPOSSIBLE_MATCH; 204 } 205 public int match(MethodDeclaration node, MatchingNodeSet nodeSet) { 206 return IMPOSSIBLE_MATCH; 208 } 209 public int match(MemberValuePair node, MatchingNodeSet nodeSet) { 210 return IMPOSSIBLE_MATCH; 212 } 213 public int match(MessageSend node, MatchingNodeSet nodeSet) { 214 return IMPOSSIBLE_MATCH; 216 } 217 public int match(Reference node, MatchingNodeSet nodeSet) { 218 return IMPOSSIBLE_MATCH; 220 } 221 public int match(TypeDeclaration node, MatchingNodeSet nodeSet) { 222 return IMPOSSIBLE_MATCH; 224 } 225 public int match(TypeParameter node, MatchingNodeSet nodeSet) { 226 return IMPOSSIBLE_MATCH; 228 } 229 public int match(TypeReference node, MatchingNodeSet nodeSet) { 230 return IMPOSSIBLE_MATCH; 232 } 233 237 protected int matchContainer() { 238 return ALL_CONTAINER; 240 } 241 244 protected boolean matchesName(char[] pattern, char[] name) { 245 if (pattern == null) return true; if (name == null) return false; return matchNameValue(pattern, name) != IMPOSSIBLE_MATCH; 248 } 249 269 protected int matchNameValue(char[] pattern, char[] name) { 270 if (pattern == null) return ACCURATE_MATCH; if (name == null) return IMPOSSIBLE_MATCH; if (name.length == 0) { if (pattern.length == 0) { return ACCURATE_MATCH; 275 } 276 return IMPOSSIBLE_MATCH; 277 } else if (pattern.length == 0) { 278 return IMPOSSIBLE_MATCH; } 280 boolean matchFirstChar = !this.isCaseSensitive || pattern[0] == name[0]; 281 boolean sameLength = pattern.length == name.length; 282 boolean canBePrefix = name.length >= pattern.length; 283 if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(pattern, name)) { 284 return POSSIBLE_MATCH; 285 } 286 switch (this.matchMode) { 287 case SearchPattern.R_EXACT_MATCH: 288 if (!this.isCamelCase) { 289 if (sameLength && matchFirstChar && CharOperation.equals(pattern, name, this.isCaseSensitive)) { 290 return POSSIBLE_MATCH | EXACT_FLAVOR; 291 } 292 break; 293 } 294 case SearchPattern.R_PREFIX_MATCH: 296 if (canBePrefix && matchFirstChar && CharOperation.prefixEquals(pattern, name, this.isCaseSensitive)) { 297 return POSSIBLE_MATCH; 298 } 299 break; 300 case SearchPattern.R_PATTERN_MATCH: 301 if (!this.isCaseSensitive) { 302 pattern = CharOperation.toLowerCase(pattern); 303 } 304 if (CharOperation.match(pattern, name, this.isCaseSensitive)) { 305 return POSSIBLE_MATCH; 306 } 307 break; 308 case SearchPattern.R_REGEXP_MATCH : 309 break; 311 } 312 return IMPOSSIBLE_MATCH; 313 } 314 317 protected boolean matchesTypeReference(char[] pattern, TypeReference type) { 318 if (pattern == null) return true; if (type == null) return true; 321 char[][] compoundName = type.getTypeName(); 322 char[] simpleName = compoundName[compoundName.length - 1]; 323 int dimensions = type.dimensions() * 2; 324 if (dimensions > 0) { 325 int length = simpleName.length; 326 char[] result = new char[length + dimensions]; 327 System.arraycopy(simpleName, 0, result, 0, length); 328 for (int i = length, l = result.length; i < l;) { 329 result[i++] = '['; 330 result[i++] = ']'; 331 } 332 simpleName = result; 333 } 334 335 return matchesName(pattern, simpleName); 336 } 337 340 protected int matchLevel(ImportReference importRef) { 341 return IMPOSSIBLE_MATCH; 343 } 344 347 protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException { 348 int level = resolveLevel(binding); 349 if (level >= INACCURATE_MATCH) { 350 matchReportImportRef( 351 importRef, 352 binding, 353 locator.createImportHandle(importRef), 354 level == ACCURATE_MATCH 355 ? SearchMatch.A_ACCURATE 356 : SearchMatch.A_INACCURATE, 357 locator); 358 } 359 } 360 363 protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException { 364 if (locator.encloses(element)) { 365 this.matchReportReference(importRef, element, null, accuracy, locator); 367 } 368 } 369 372 protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 373 match = null; 374 int referenceType = referenceType(); 375 int offset = reference.sourceStart; 376 switch (referenceType) { 377 case IJavaElement.PACKAGE_FRAGMENT: 378 match = locator.newPackageReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference); 379 break; 380 case IJavaElement.TYPE: 381 match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); 382 break; 383 case IJavaElement.FIELD: 384 match = locator.newFieldReferenceMatch(element, elementBinding, accuracy, offset, reference.sourceEnd-offset+1, reference); 385 break; 386 case IJavaElement.LOCAL_VARIABLE: 387 match = locator.newLocalVariableReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference); 388 break; 389 case IJavaElement.TYPE_PARAMETER: 390 match = locator.newTypeParameterReferenceMatch(element, accuracy, offset, reference.sourceEnd-offset+1, reference); 391 break; 392 } 393 if (match != null) { 394 locator.report(match); 395 } 396 } 397 400 protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 401 matchReportReference(reference, element, elementBinding, accuracy, locator); 402 } 403 406 protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException { 407 matchReportReference(reference, element, elementBinding, accuracy, locator); 408 } 409 public SearchMatch newDeclarationMatch(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, int length, MatchLocator locator) { 410 return locator.newDeclarationMatch(element, elementBinding, accuracy, reference.sourceStart, length); 411 } 412 protected int referenceType() { 413 return 0; } 415 423 public int resolveLevel(ASTNode possibleMatchingNode) { 424 return IMPOSSIBLE_MATCH; 427 } 428 432 protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, MatchLocator locator) { 433 if (locator.unitScope != null) { 435 updateMatch(parameterizedBinding, patternTypeArguments, false, 0, locator); 436 } 437 } 438 protected void updateMatch(ParameterizedTypeBinding parameterizedBinding, char[][][] patternTypeArguments, boolean patternHasTypeParameters, int depth, MatchLocator locator) { 439 if (locator.unitScope == null) return; 441 442 boolean endPattern = patternTypeArguments==null ? true : depth>=patternTypeArguments.length; 444 TypeBinding[] argumentsBindings = parameterizedBinding.arguments; 445 boolean isRaw = parameterizedBinding.isRawType()|| (argumentsBindings==null && parameterizedBinding.genericType().isGenericType()); 446 if (isRaw && !match.isRaw()) { 447 match.setRaw(isRaw); 448 } 449 450 if (!endPattern && patternTypeArguments != null) { 452 if (!isRaw && patternHasTypeParameters && argumentsBindings != null) { 454 boolean needUpdate = false; 455 TypeVariableBinding[] typeVariables = parameterizedBinding.genericType().typeVariables(); 456 for (int i=0, l=argumentsBindings.length; i<l; i++) { 457 if (argumentsBindings[i] != typeVariables[i]) { 458 needUpdate = true; 459 break; 460 } 461 } 462 if (needUpdate) { 463 char[][] patternArguments = patternTypeArguments[depth]; 464 updateMatch(argumentsBindings, locator, patternArguments, patternHasTypeParameters); 465 } 466 } else { 467 char[][] patternArguments = patternTypeArguments[depth]; 468 updateMatch(argumentsBindings, locator, patternArguments, patternHasTypeParameters); 469 } 470 } 471 472 TypeBinding enclosingType = parameterizedBinding.enclosingType(); 474 if (enclosingType != null && (enclosingType.isParameterizedType() || enclosingType.isRawType())) { 475 updateMatch((ParameterizedTypeBinding)enclosingType, patternTypeArguments, patternHasTypeParameters, depth+1, locator); 476 } 477 } 478 483 protected void updateMatch(TypeBinding[] argumentsBinding, MatchLocator locator, char[][] patternArguments, boolean hasTypeParameters) { 484 if (locator.unitScope == null) return; 486 487 int patternTypeArgsLength = patternArguments==null ? 0 : patternArguments.length; 489 int typeArgumentsLength = argumentsBinding == null ? 0 : argumentsBinding.length; 490 491 int matchRule = match.getRule(); 493 if (match.isRaw()) { 494 if (patternTypeArgsLength != 0) { 495 matchRule &= ~SearchPattern.R_FULL_MATCH; 496 } 497 } 498 if (hasTypeParameters) { 499 matchRule = SearchPattern.R_ERASURE_MATCH; 500 } 501 502 if (patternTypeArgsLength == typeArgumentsLength) { 504 if (!match.isRaw() && hasTypeParameters) { 505 match.setRule(SearchPattern.R_ERASURE_MATCH); 507 return; 508 } 509 } else { 510 if (patternTypeArgsLength==0) { 511 if (!match.isRaw() || hasTypeParameters) { 512 match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); 513 } 514 } else if (typeArgumentsLength==0) { 515 match.setRule(matchRule & ~SearchPattern.R_FULL_MATCH); 517 } else { 518 match.setRule(0); } 520 return; 521 } 522 if (argumentsBinding == null || patternArguments == null) { 523 match.setRule(matchRule); 524 return; 525 } 526 527 if (!hasTypeParameters && !match.isRaw() && (match.isEquivalent() || match.isExact())) { 529 for (int i=0; i<typeArgumentsLength; i++) { 530 TypeBinding argumentBinding = argumentsBinding[i]; 532 if (argumentBinding instanceof CaptureBinding) { 533 WildcardBinding capturedWildcard = ((CaptureBinding)argumentBinding).wildcard; 534 if (capturedWildcard != null) argumentBinding = capturedWildcard; 535 } 536 char[] patternTypeArgument = patternArguments[i]; 538 char patternWildcard = patternTypeArgument[0]; 539 char[] patternTypeName = patternTypeArgument; 540 int patternWildcardKind = -1; 541 switch (patternWildcard) { 542 case Signature.C_STAR: 543 if (argumentBinding.isWildcard()) { 544 WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; 545 if (wildcardBinding.boundKind == Wildcard.UNBOUND) continue; 546 } 547 matchRule &= ~SearchPattern.R_FULL_MATCH; 548 continue; case Signature.C_EXTENDS : 550 patternWildcardKind = Wildcard.EXTENDS; 551 patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); 552 break; 553 case Signature.C_SUPER : 554 patternWildcardKind = Wildcard.SUPER; 555 patternTypeName = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); 556 default : 557 break; 558 } 559 patternTypeName = Signature.toCharArray(patternTypeName); 560 TypeBinding patternBinding = locator.getType(patternTypeArgument, patternTypeName); 561 562 if (patternBinding == null) { 564 if (argumentBinding.isWildcard()) { 565 WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; 566 if (wildcardBinding.boundKind == Wildcard.UNBOUND) { 567 matchRule &= ~SearchPattern.R_FULL_MATCH; 568 } else { 569 match.setRule(SearchPattern.R_ERASURE_MATCH); 570 return; 571 } 572 } 573 continue; 574 } 575 576 switch (patternWildcard) { 578 case Signature.C_STAR : matchRule &= ~SearchPattern.R_FULL_MATCH; 581 continue; 582 case Signature.C_EXTENDS : if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; 585 if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) { 587 continue; 588 } 589 switch (wildcardBinding.boundKind) { 591 case Wildcard.EXTENDS: 592 if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { 593 matchRule &= ~SearchPattern.R_FULL_MATCH; 595 continue; 596 } 597 break; 598 case Wildcard.SUPER: 599 break; 600 case Wildcard.UNBOUND: 601 matchRule &= ~SearchPattern.R_FULL_MATCH; 602 continue; 603 } 604 } else if (argumentBinding.isCompatibleWith(patternBinding)) { 605 matchRule &= ~SearchPattern.R_FULL_MATCH; 607 continue; 608 } 609 break; 610 case Signature.C_SUPER : if (argumentBinding.isWildcard()) { WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; 613 if (wildcardBinding.boundKind == patternWildcardKind && wildcardBinding.bound == patternBinding) { 615 continue; 616 } 617 switch (wildcardBinding.boundKind) { 619 case Wildcard.EXTENDS: 620 break; 621 case Wildcard.SUPER: 622 if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { 623 matchRule &= ~SearchPattern.R_FULL_MATCH; 625 continue; 626 } 627 break; 628 case Wildcard.UNBOUND: 629 matchRule &= ~SearchPattern.R_FULL_MATCH; 630 continue; 631 } 632 } else if (patternBinding.isCompatibleWith(argumentBinding)) { 633 matchRule &= ~SearchPattern.R_FULL_MATCH; 635 continue; 636 } 637 break; 638 default: 639 if (argumentBinding.isWildcard()) { 640 WildcardBinding wildcardBinding = (WildcardBinding) argumentBinding; 641 switch (wildcardBinding.boundKind) { 642 case Wildcard.EXTENDS: 643 if (wildcardBinding.bound== null || patternBinding.isCompatibleWith(wildcardBinding.bound)) { 644 matchRule &= ~SearchPattern.R_FULL_MATCH; 646 continue; 647 } 648 break; 649 case Wildcard.SUPER: 650 if (wildcardBinding.bound== null || wildcardBinding.bound.isCompatibleWith(patternBinding)) { 651 matchRule &= ~SearchPattern.R_FULL_MATCH; 653 continue; 654 } 655 break; 656 case Wildcard.UNBOUND: 657 matchRule &= ~SearchPattern.R_FULL_MATCH; 658 continue; 659 } 660 } else if (argumentBinding == patternBinding) 661 continue; 663 break; 664 } 665 666 match.setRule(SearchPattern.R_ERASURE_MATCH); 668 return; 669 } 670 } 671 672 match.setRule(matchRule); 674 } 675 682 public int resolveLevel(Binding binding) { 683 return INACCURATE_MATCH; 685 } 686 695 protected int resolveLevelForType(char[] simpleNamePattern, char[] qualificationPattern, TypeBinding binding) { 696 char[] qualifiedPattern = getQualifiedPattern(simpleNamePattern, qualificationPattern); 698 int level = resolveLevelForType(qualifiedPattern, binding); 699 if (level == ACCURATE_MATCH || binding == null) return level; 700 TypeBinding type = binding instanceof ArrayBinding ? ((ArrayBinding)binding).leafComponentType : binding; 701 char[] sourceName = null; 702 if (type.isMemberType() || type.isLocalType()) { 703 if (qualificationPattern != null) { 704 sourceName = getQualifiedSourceName(binding); 705 } else { 706 sourceName = binding.sourceName(); 707 } 708 } else if (qualificationPattern == null) { 709 sourceName = getQualifiedSourceName(binding); 710 } 711 if (sourceName == null) return IMPOSSIBLE_MATCH; 712 if ((this.matchMode & SearchPattern.R_PREFIX_MATCH) != 0) { 713 if (CharOperation.prefixEquals(qualifiedPattern, sourceName, this.isCaseSensitive)) { 714 return ACCURATE_MATCH; 715 } 716 } 717 if (this.isCamelCase) { 718 if (!this.isCaseSensitive || (qualifiedPattern.length>0 && sourceName.length>0 && qualifiedPattern[0] == sourceName[0])) { 719 if (CharOperation.camelCaseMatch(qualifiedPattern, sourceName)) { 720 return ACCURATE_MATCH; 721 } 722 } 723 if (this.matchMode == SearchPattern.R_EXACT_MATCH) { 724 boolean matchPattern = CharOperation.prefixEquals(qualifiedPattern, sourceName, this.isCaseSensitive); 725 return matchPattern ? ACCURATE_MATCH : IMPOSSIBLE_MATCH; 726 } 727 } 728 boolean matchPattern = CharOperation.match(qualifiedPattern, sourceName, this.isCaseSensitive); 729 return matchPattern ? ACCURATE_MATCH : IMPOSSIBLE_MATCH; 730 731 } 732 733 739 protected int resolveLevelForType(char[] qualifiedPattern, TypeBinding type) { 740 if (qualifiedPattern == null) return ACCURATE_MATCH; 741 if (type == null) return INACCURATE_MATCH; 742 743 if (type.isTypeVariable()) return IMPOSSIBLE_MATCH; 745 746 748 char[] qualifiedPackageName = type.qualifiedPackageName(); 749 char[] qualifiedSourceName = qualifiedSourceName(type); 750 char[] fullyQualifiedTypeName = qualifiedPackageName.length == 0 751 ? qualifiedSourceName 752 : CharOperation.concat(qualifiedPackageName, qualifiedSourceName, '.'); 753 return CharOperation.match(qualifiedPattern, fullyQualifiedTypeName, this.isCaseSensitive) 754 ? ACCURATE_MATCH 755 : IMPOSSIBLE_MATCH; 756 } 757 760 protected int resolveLevelForType (char[] simpleNamePattern, 761 char[] qualificationPattern, 762 char[][][] patternTypeArguments, 763 int depth, 764 TypeBinding type) { 765 int level = resolveLevelForType(simpleNamePattern, qualificationPattern, type); 767 if (level == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; 768 if (type == null || patternTypeArguments == null || patternTypeArguments.length == 0 || depth >= patternTypeArguments.length) { 769 return level; 770 } 771 772 int impossible = this.isErasureMatch ? ERASURE_MATCH : IMPOSSIBLE_MATCH; 774 775 if (type.isGenericType()) { 777 TypeVariableBinding[] typeVariables = null; 779 if (type instanceof SourceTypeBinding) { 780 SourceTypeBinding sourceTypeBinding = (SourceTypeBinding) type; 781 typeVariables = sourceTypeBinding.typeVariables; 782 } else if (type instanceof BinaryTypeBinding) { 783 BinaryTypeBinding binaryTypeBinding = (BinaryTypeBinding) type; 784 if (this.mustResolve) 785 typeVariables = binaryTypeBinding.typeVariables(); } 787 if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && 788 typeVariables != null && typeVariables.length > 0) { 789 if (typeVariables.length != patternTypeArguments[depth].length) return IMPOSSIBLE_MATCH; 790 } 791 return level; } else if (type.isRawType()) { 794 return level; } else { 796 TypeBinding leafType = type.leafComponentType(); 797 if (!leafType.isParameterizedType()) { 798 return (patternTypeArguments[depth]==null || patternTypeArguments[depth].length==0) ? level : IMPOSSIBLE_MATCH; 801 } 802 ParameterizedTypeBinding paramTypeBinding = (ParameterizedTypeBinding) leafType; 803 804 if (patternTypeArguments[depth] != null && patternTypeArguments[depth].length > 0 && 806 paramTypeBinding.arguments != null && paramTypeBinding.arguments.length > 0) { 807 808 int length = patternTypeArguments[depth].length; 810 if (paramTypeBinding.arguments.length != length) return IMPOSSIBLE_MATCH; 811 812 nextTypeArgument: for (int i= 0; i<length; i++) { 814 char[] patternTypeArgument = patternTypeArguments[depth][i]; 815 TypeBinding argTypeBinding = paramTypeBinding.arguments[i]; 816 switch (patternTypeArgument[0]) { 818 case Signature.C_STAR : case Signature.C_SUPER : continue nextTypeArgument; 822 case Signature.C_EXTENDS : 823 patternTypeArgument = CharOperation.subarray(patternTypeArgument, 1, patternTypeArgument.length); 825 default : 826 break; 828 } 829 patternTypeArgument = Signature.toCharArray(patternTypeArgument); 831 if (!this.isCaseSensitive) patternTypeArgument = CharOperation.toLowerCase(patternTypeArgument); 832 boolean patternTypeArgHasAnyChars = CharOperation.contains(new char[] {'*', '?'}, patternTypeArgument); 833 834 if (argTypeBinding instanceof CaptureBinding) { 837 WildcardBinding capturedWildcard = ((CaptureBinding)argTypeBinding).wildcard; 838 if (capturedWildcard != null) argTypeBinding = capturedWildcard; 839 } 840 if (argTypeBinding.isWildcard()) { 841 WildcardBinding wildcardBinding = (WildcardBinding) argTypeBinding; 842 switch (wildcardBinding.boundKind) { 843 case Wildcard.EXTENDS: 844 if (patternTypeArgHasAnyChars) return impossible; 846 case Wildcard.UNBOUND: 847 continue nextTypeArgument; 849 } 850 ReferenceBinding boundBinding = (ReferenceBinding) wildcardBinding.bound; 852 if (CharOperation.match(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || 853 CharOperation.match(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { 854 continue nextTypeArgument; 856 } 857 858 if (patternTypeArgHasAnyChars) return impossible; 860 861 boundBinding = boundBinding.superclass(); 863 while (boundBinding != null) { 864 if (CharOperation.equals(patternTypeArgument, boundBinding.shortReadableName(), this.isCaseSensitive) || 865 CharOperation.equals(patternTypeArgument, boundBinding.readableName(), this.isCaseSensitive)) { 866 continue nextTypeArgument; 868 } else if (boundBinding.isLocalType() || boundBinding.isMemberType()) { 869 if (CharOperation.match(patternTypeArgument, boundBinding.sourceName(), this.isCaseSensitive)) 871 continue nextTypeArgument; 872 } 873 boundBinding = boundBinding.superclass(); 874 } 875 return impossible; 876 } 877 878 if (CharOperation.match(patternTypeArgument, argTypeBinding.shortReadableName(), this.isCaseSensitive) || 880 CharOperation.match(patternTypeArgument, argTypeBinding.readableName(), this.isCaseSensitive)) { 881 continue nextTypeArgument; 882 } else if (argTypeBinding.isLocalType() || argTypeBinding.isMemberType()) { 883 if (CharOperation.match(patternTypeArgument, argTypeBinding.sourceName(), this.isCaseSensitive)) 885 continue nextTypeArgument; 886 } 887 888 if (patternTypeArgHasAnyChars) return impossible; 890 891 TypeBinding leafTypeBinding = argTypeBinding.leafComponentType(); 893 if (leafTypeBinding.isBaseType()) return impossible; 894 ReferenceBinding refBinding = ((ReferenceBinding) leafTypeBinding).superclass(); 895 while (refBinding != null) { 896 if (CharOperation.equals(patternTypeArgument, refBinding.shortReadableName(), this.isCaseSensitive) || 897 CharOperation.equals(patternTypeArgument, refBinding.readableName(), this.isCaseSensitive)) { 898 continue nextTypeArgument; 900 } else if (refBinding.isLocalType() || refBinding.isMemberType()) { 901 if (CharOperation.match(patternTypeArgument, refBinding.sourceName(), this.isCaseSensitive)) 903 continue nextTypeArgument; 904 } 905 refBinding = refBinding.superclass(); 906 } 907 return impossible; 908 } 909 } 910 911 TypeBinding enclosingType = paramTypeBinding.enclosingType(); 913 if (enclosingType != null && enclosingType.isParameterizedType() && depth < patternTypeArguments.length && qualificationPattern != null) { 914 int lastDot = CharOperation.lastIndexOf('.', qualificationPattern); 915 char[] enclosingQualificationPattern = lastDot==-1 ? null : CharOperation.subarray(qualificationPattern, 0, lastDot); 916 char[] enclosingSimpleNamePattern = lastDot==-1 ? qualificationPattern : CharOperation.subarray(qualificationPattern, lastDot+1, qualificationPattern.length); 917 int enclosingLevel = resolveLevelForType(enclosingSimpleNamePattern, enclosingQualificationPattern, patternTypeArguments, depth+1, enclosingType); 918 if (enclosingLevel == impossible) return impossible; 919 if (enclosingLevel == IMPOSSIBLE_MATCH) return IMPOSSIBLE_MATCH; 920 } 921 return level; 922 } 923 } 924 public String toString(){ 925 return "SearchPattern"; } 927 } 928 | Popular Tags |