1 11 package org.eclipse.jdt.internal.core.search.matching; 12 13 import org.eclipse.core.resources.IResource; 14 import org.eclipse.core.runtime.*; 15 import org.eclipse.jdt.core.*; 16 import org.eclipse.jdt.core.compiler.CharOperation; 17 import org.eclipse.jdt.core.search.*; 18 import org.eclipse.jdt.internal.compiler.ast.*; 19 import org.eclipse.jdt.internal.compiler.env.IBinaryType; 20 import org.eclipse.jdt.internal.compiler.lookup.*; 21 import org.eclipse.jdt.internal.compiler.util.SimpleSet; 22 import org.eclipse.jdt.internal.core.JavaElement; 23 24 public class TypeReferenceLocator extends PatternLocator { 25 26 protected TypeReferencePattern pattern; 27 protected boolean isDeclarationOfReferencedTypesPattern; 28 29 public TypeReferenceLocator(TypeReferencePattern pattern) { 30 31 super(pattern); 32 33 this.pattern = pattern; 34 this.isDeclarationOfReferencedTypesPattern = this.pattern instanceof DeclarationOfReferencedTypesPattern; 35 } 36 protected IJavaElement findElement(IJavaElement element, int accuracy) { 37 if (accuracy != SearchMatch.A_ACCURATE) return null; 39 40 DeclarationOfReferencedTypesPattern declPattern = (DeclarationOfReferencedTypesPattern) this.pattern; 42 while (element != null && !declPattern.enclosingElement.equals(element)) 43 element = element.getParent(); 44 return element; 45 } 46 public int match(Annotation node, MatchingNodeSet nodeSet) { 47 return match(node.type, nodeSet); 48 } 49 public int match(ASTNode node, MatchingNodeSet nodeSet) { if (!(node instanceof ImportReference)) return IMPOSSIBLE_MATCH; 51 52 return nodeSet.addMatch(node, matchLevel((ImportReference) node)); 53 } 54 public int match(Reference node, MatchingNodeSet nodeSet) { if (!(node instanceof NameReference)) return IMPOSSIBLE_MATCH; 61 62 if (this.pattern.simpleName == null) 63 return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); 64 65 if (node instanceof SingleNameReference) { 66 if (matchesName(this.pattern.simpleName, ((SingleNameReference) node).token)) 67 return nodeSet.addMatch(node, POSSIBLE_MATCH); } else { 69 char[][] tokens = ((QualifiedNameReference) node).tokens; 70 for (int i = 0, max = tokens.length; i < max; i++) 71 if (matchesName(this.pattern.simpleName, tokens[i])) 72 return nodeSet.addMatch(node, POSSIBLE_MATCH); } 74 75 return IMPOSSIBLE_MATCH; 76 } 77 public int match(TypeReference node, MatchingNodeSet nodeSet) { 79 if (this.pattern.simpleName == null) 80 return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); 81 82 if (node instanceof SingleTypeReference) { 83 if (matchesName(this.pattern.simpleName, ((SingleTypeReference) node).token)) 84 return nodeSet.addMatch(node, ((InternalSearchPattern)this.pattern).mustResolve ? POSSIBLE_MATCH : ACCURATE_MATCH); 85 } else { 86 char[][] tokens = ((QualifiedTypeReference) node).tokens; 87 for (int i = 0, max = tokens.length; i < max; i++) 88 if (matchesName(this.pattern.simpleName, tokens[i])) 89 return nodeSet.addMatch(node, POSSIBLE_MATCH); } 91 92 return IMPOSSIBLE_MATCH; 93 } 94 95 protected int matchLevel(ImportReference importRef) { 96 if (this.pattern.qualification == null) { 97 if (this.pattern.simpleName == null) return ACCURATE_MATCH; 98 char[][] tokens = importRef.tokens; 99 if (matchesName(this.pattern.simpleName, tokens[tokens.length-1])) return ACCURATE_MATCH; 100 } else { 101 char[][] tokens = importRef.tokens; 102 char[] qualifiedPattern = this.pattern.simpleName == null 103 ? this.pattern.qualification 104 : CharOperation.concat(this.pattern.qualification, this.pattern.simpleName, '.'); 105 char[] qualifiedTypeName = CharOperation.concatWith(tokens, '.'); 106 if (qualifiedPattern == null) return ACCURATE_MATCH; if (qualifiedTypeName == null) return IMPOSSIBLE_MATCH; if (qualifiedTypeName.length == 0) { if (qualifiedPattern.length == 0) { return ACCURATE_MATCH; 111 } 112 return IMPOSSIBLE_MATCH; 113 } 114 boolean matchFirstChar = !this.isCaseSensitive || (qualifiedPattern[0] == qualifiedTypeName[0]); 115 if (this.isCamelCase && matchFirstChar && CharOperation.camelCaseMatch(qualifiedPattern, qualifiedTypeName)) { 116 return POSSIBLE_MATCH; 117 } 118 switch (this.matchMode) { 119 case SearchPattern.R_EXACT_MATCH: 120 case SearchPattern.R_PREFIX_MATCH: 121 if (CharOperation.prefixEquals(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) { 122 return POSSIBLE_MATCH; 123 } 124 break; 125 126 case SearchPattern.R_PATTERN_MATCH: 127 if (CharOperation.match(qualifiedPattern, qualifiedTypeName, this.isCaseSensitive)) { 128 return POSSIBLE_MATCH; 129 } 130 break; 131 132 case SearchPattern.R_REGEXP_MATCH : 133 break; 135 } 136 } 137 return IMPOSSIBLE_MATCH; 138 } 139 142 protected void matchLevelAndReportImportRef(ImportReference importRef, Binding binding, MatchLocator locator) throws CoreException { 143 Binding refBinding = binding; 144 if (importRef.isStatic()) { 145 if (binding instanceof FieldBinding) { 148 FieldBinding fieldBinding = (FieldBinding) binding; 149 if (!fieldBinding.isStatic()) return; 150 refBinding = fieldBinding.declaringClass; 151 } else if (binding instanceof MethodBinding) { 152 MethodBinding methodBinding = (MethodBinding) binding; 153 if (!methodBinding.isStatic()) return; 154 refBinding = methodBinding.declaringClass; 155 } else if (binding instanceof MemberTypeBinding) { 156 MemberTypeBinding memberBinding = (MemberTypeBinding) binding; 157 if (!memberBinding.isStatic()) return; 158 } 159 int level = resolveLevel(refBinding); 161 if (level >= INACCURATE_MATCH) { 162 matchReportImportRef( 163 importRef, 164 binding, 165 locator.createImportHandle(importRef), 166 level == ACCURATE_MATCH 167 ? SearchMatch.A_ACCURATE 168 : SearchMatch.A_INACCURATE, 169 locator); 170 } 171 return; 172 } 173 super.matchLevelAndReportImportRef(importRef, refBinding, locator); 174 } 175 protected void matchReportImportRef(ImportReference importRef, Binding binding, IJavaElement element, int accuracy, MatchLocator locator) throws CoreException { 176 if (this.isDeclarationOfReferencedTypesPattern) { 177 if ((element = findElement(element, accuracy)) != null) { 178 SimpleSet knownTypes = ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes; 179 while (binding instanceof ReferenceBinding) { 180 ReferenceBinding typeBinding = (ReferenceBinding) binding; 181 reportDeclaration(typeBinding, 1, locator, knownTypes); 182 binding = typeBinding.enclosingType(); 183 } 184 } 185 return; 186 } 187 188 if (this.pattern.hasTypeArguments() && !this.isEquivalentMatch &&!this.isErasureMatch) { 190 return; 191 } 192 193 match = locator.newTypeReferenceMatch(element, binding, accuracy, importRef); 195 196 match.setRaw(true); 198 if (this.pattern.hasTypeArguments()) { 199 match.setRule(match.getRule() & (~SearchPattern.R_FULL_MATCH)); 201 } 202 203 ReferenceBinding typeBinding = null; 205 boolean lastButOne = false; 206 if (binding instanceof ReferenceBinding) { 207 typeBinding = (ReferenceBinding) binding; 208 } else if (binding instanceof FieldBinding) { typeBinding = ((FieldBinding)binding).declaringClass; 210 lastButOne = importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0); 211 } else if (binding instanceof MethodBinding) { typeBinding = ((MethodBinding)binding).declaringClass; 213 lastButOne = importRef.isStatic() && ((importRef.bits & ASTNode.OnDemand) == 0); 214 } 215 if (typeBinding != null) { 216 int lastIndex = importRef.tokens.length - 1; 217 if (lastButOne) { 218 lastIndex--; 220 } 221 if (typeBinding instanceof ProblemReferenceBinding) { 222 ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding; 223 typeBinding = pbBinding.closestMatch(); 224 lastIndex = pbBinding.compoundName.length - 1; 225 } 226 while (typeBinding != null && lastIndex >= 0) { 228 if (resolveLevelForType(typeBinding) != IMPOSSIBLE_MATCH) { 229 if (locator.encloses(element)) { 230 long[] positions = importRef.sourcePositions; 231 int index = lastIndex; 233 if (this.pattern.qualification != null) { 234 index = lastIndex - this.pattern.segmentsSize; 235 } 236 if (index < 0) index = 0; 237 int start = (int) ((positions[index]) >>> 32); 238 int end = (int) positions[lastIndex]; 239 match.setOffset(start); 241 match.setLength(end-start+1); 242 locator.report(match); 243 } 244 return; 245 } 246 lastIndex--; 247 typeBinding = typeBinding.enclosingType(); 248 } 249 } 250 locator.reportAccurateTypeReference(match, importRef, this.pattern.simpleName); 251 } 252 protected void matchReportReference(ArrayTypeReference arrayRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 253 if (this.pattern.simpleName == null) { 254 if (locator.encloses(element)) { 256 int offset = arrayRef.sourceStart; 257 int length = arrayRef.sourceEnd-offset+1; 258 if (this.match == null) { 259 this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, offset, length, arrayRef); 260 } else { 261 this.match.setOffset(offset); 262 this.match.setLength(length); 263 } 264 locator.report(match); 265 return; 266 } 267 } 268 match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, arrayRef); 269 if (arrayRef.resolvedType != null) { 270 matchReportReference(arrayRef, -1, arrayRef.resolvedType.leafComponentType(), locator); 271 return; 272 } 273 locator.reportAccurateTypeReference(match, arrayRef, this.pattern.simpleName); 274 } 275 278 protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 279 matchReportReference(reference, element, null, null, elementBinding, accuracy, locator); 280 } 281 284 protected void matchReportReference(ASTNode reference, IJavaElement element, IJavaElement localElement, IJavaElement[] otherElements, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 285 if (this.isDeclarationOfReferencedTypesPattern) { 286 if ((element = findElement(element, accuracy)) != null) 287 reportDeclaration(reference, element, locator, ((DeclarationOfReferencedTypesPattern) this.pattern).knownTypes); 288 return; 289 } 290 291 TypeReferenceMatch refMatch = locator.newTypeReferenceMatch(element, elementBinding, accuracy, reference); 293 refMatch.setLocalElement(localElement); 294 refMatch.setOtherElements(otherElements); 295 this.match = refMatch; 296 297 if (reference instanceof QualifiedNameReference) 299 matchReportReference((QualifiedNameReference) reference, element, elementBinding, accuracy, locator); 300 else if (reference instanceof QualifiedTypeReference) 301 matchReportReference((QualifiedTypeReference) reference, element, elementBinding, accuracy, locator); 302 else if (reference instanceof ArrayTypeReference) 303 matchReportReference((ArrayTypeReference) reference, element, elementBinding, accuracy, locator); 304 else { 305 TypeBinding typeBinding = reference instanceof Expression ? ((Expression)reference).resolvedType : null; 306 if (typeBinding != null) { 307 matchReportReference((Expression)reference, -1, typeBinding, locator); 308 return; 309 } 310 locator.report(match); 311 } 312 } 313 316 protected void matchReportReference(ASTNode reference, IJavaElement element, Binding elementBinding, Scope scope, int accuracy, MatchLocator locator) throws CoreException { 317 if (scope == null || (scope.kind != Scope.BLOCK_SCOPE && scope.kind != Scope.METHOD_SCOPE)) { 318 matchReportReference(reference, element, elementBinding, accuracy, locator); 319 return; 320 } 321 322 BlockScope blockScope = (BlockScope) scope; 324 LocalDeclaration[] localDeclarations = blockScope.findLocalVariableDeclarations(reference.sourceStart); 325 IJavaElement localElement = null; 326 IJavaElement[] otherElements = null; 327 328 if (localDeclarations != null) { 330 int length = localDeclarations.length; 331 332 int idx = 0; 334 for (; idx<length; idx++) { 335 if (localDeclarations[idx] == null) break; 336 if (reference.sourceStart == localDeclarations[idx].declarationSourceStart) { 337 localElement = locator.createHandle(localDeclarations[idx], element); 338 break; 339 } 340 if (idx>0 && localDeclarations[idx].sourceStart > reference.sourceStart) { 341 localElement = locator.createHandle(localDeclarations[idx-1], element); 342 break; 343 } 344 } 345 if (localElement == null && idx > 0) { 346 if (reference.sourceEnd < localDeclarations[idx-1].declarationEnd) { 347 localElement = locator.createHandle(localDeclarations[idx-1], element); 348 } 349 } 350 351 int size = 0; 353 for (int j=1; j<length; j++) { 354 if (localDeclarations[j] == null) break; 355 if (reference.sourceStart == localDeclarations[j].declarationSourceStart) { 356 if (otherElements == null) { 357 otherElements = new IJavaElement[length-j]; 358 } 359 otherElements[size++] = locator.createHandle(localDeclarations[j], element); 360 } 361 } 362 if (size > 0 && size != (length-1)) { 363 System.arraycopy(otherElements, 0, otherElements = new IJavaElement[size], 0, size); 364 } 365 } 366 367 matchReportReference(reference, element, localElement, otherElements, elementBinding, accuracy, locator); 369 } 370 protected void matchReportReference(QualifiedNameReference qNameRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 371 Binding binding = qNameRef.binding; 372 TypeBinding typeBinding = null; 373 int lastIndex = qNameRef.tokens.length - 1; 374 switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) { 375 case Binding.FIELD : typeBinding = qNameRef.actualReceiverType; 377 lastIndex -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1; 378 break; 379 case Binding.TYPE : if (binding instanceof TypeBinding) 381 typeBinding = (TypeBinding) binding; 382 break; 383 case Binding.VARIABLE : case Binding.TYPE | Binding.VARIABLE : 385 if (binding instanceof ProblemReferenceBinding) { 386 typeBinding = (TypeBinding) binding; 387 } else if (binding instanceof ProblemFieldBinding) { 388 typeBinding = qNameRef.actualReceiverType; 389 lastIndex -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1; 390 } else if (binding instanceof ProblemBinding) { 391 typeBinding = ((ProblemBinding) binding).searchType; 392 } 393 break; 394 } 395 if (typeBinding instanceof ProblemReferenceBinding) { 396 ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding; 397 typeBinding = pbBinding.closestMatch(); 398 lastIndex = pbBinding.compoundName.length - 1; 399 } 400 401 if (this.match == null) { 403 this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qNameRef); 404 } 405 406 if (typeBinding instanceof ReferenceBinding) { 408 ReferenceBinding refBinding = (ReferenceBinding) typeBinding; 409 while (refBinding != null && lastIndex >= 0) { 410 if (resolveLevelForType(refBinding) == ACCURATE_MATCH) { 411 if (locator.encloses(element)) { 412 long[] positions = qNameRef.sourcePositions; 413 int index = lastIndex; 415 if (this.pattern.qualification != null) { 416 index = lastIndex - this.pattern.segmentsSize; 417 } 418 if (index < 0) index = 0; 419 int start = (int) ((positions[index]) >>> 32); 420 int end = (int) positions[lastIndex]; 421 match.setOffset(start); 422 match.setLength(end-start+1); 423 424 matchReportReference(qNameRef, lastIndex, refBinding, locator); 426 } 427 return; 428 } 429 lastIndex--; 430 refBinding = refBinding.enclosingType(); 431 } 432 } 433 locator.reportAccurateTypeReference(match, qNameRef, this.pattern.simpleName); 434 } 435 protected void matchReportReference(QualifiedTypeReference qTypeRef, IJavaElement element, Binding elementBinding, int accuracy, MatchLocator locator) throws CoreException { 436 TypeBinding typeBinding = qTypeRef.resolvedType; 437 int lastIndex = qTypeRef.tokens.length - 1; 438 if (typeBinding instanceof ArrayBinding) 439 typeBinding = ((ArrayBinding) typeBinding).leafComponentType; 440 if (typeBinding instanceof ProblemReferenceBinding) { 441 ProblemReferenceBinding pbBinding = (ProblemReferenceBinding) typeBinding; 442 typeBinding = pbBinding.closestMatch(); 443 lastIndex = pbBinding.compoundName.length - 1; 444 } 445 446 if (this.match == null) { 448 this.match = locator.newTypeReferenceMatch(element, elementBinding, accuracy, qTypeRef); 449 } 450 451 if (typeBinding instanceof ReferenceBinding) { 453 ReferenceBinding refBinding = (ReferenceBinding) typeBinding; 454 while (refBinding != null && lastIndex >= 0) { 455 if (resolveLevelForType(refBinding) != IMPOSSIBLE_MATCH) { 456 if (locator.encloses(element)) { 457 long[] positions = qTypeRef.sourcePositions; 458 int index = lastIndex; 460 if (this.pattern.qualification != null) { 461 index = lastIndex - this.pattern.segmentsSize; 462 } 463 if (index < 0) index = 0; 464 int start = (int) ((positions[index]) >>> 32); 465 int end = (int) positions[lastIndex]; 466 match.setOffset(start); 467 match.setLength(end-start+1); 468 469 matchReportReference(qTypeRef, lastIndex, refBinding, locator); 471 } 472 return; 473 } 474 lastIndex--; 475 refBinding = refBinding.enclosingType(); 476 } 477 } 478 locator.reportAccurateTypeReference(match, qTypeRef, this.pattern.simpleName); 479 } 480 void matchReportReference(Expression expr, int lastIndex, TypeBinding refBinding, MatchLocator locator) throws CoreException { 481 482 if (refBinding.isParameterizedType() || refBinding.isRawType()) { 484 485 ParameterizedTypeBinding parameterizedBinding = (ParameterizedTypeBinding)refBinding; 487 updateMatch(parameterizedBinding, this.pattern.getTypeArguments(), this.pattern.hasTypeParameters(), 0, locator); 488 489 if (match.getRule() == 0) return; boolean report = (this.isErasureMatch && match.isErasure()) || (this.isEquivalentMatch && match.isEquivalent()) || match.isExact(); 492 if (!report) return; 493 494 if (refBinding.isParameterizedType() && this.pattern.hasTypeArguments()) { 496 TypeReference typeRef = null; 497 TypeReference[] typeArguments = null; 498 if (expr instanceof ParameterizedQualifiedTypeReference) { 499 typeRef = (ParameterizedQualifiedTypeReference) expr; 500 typeArguments = ((ParameterizedQualifiedTypeReference) expr).typeArguments[lastIndex]; 501 } 502 else if (expr instanceof ParameterizedSingleTypeReference) { 503 typeRef = (ParameterizedSingleTypeReference) expr; 504 typeArguments = ((ParameterizedSingleTypeReference) expr).typeArguments; 505 } 506 if (typeRef != null) { 507 locator.reportAccurateParameterizedTypeReference(match, typeRef, lastIndex, typeArguments); 508 return; 509 } 510 } 511 } else if (this.pattern.hasTypeArguments()) { match.setRule(SearchPattern.R_ERASURE_MATCH); 513 } 514 515 if (expr instanceof ArrayTypeReference) { 517 locator.reportAccurateTypeReference(match, expr, this.pattern.simpleName); 518 return; 519 } 520 if (refBinding.isLocalType()) { 521 LocalTypeBinding local = (LocalTypeBinding) refBinding; 523 IJavaElement focus = ((InternalSearchPattern)pattern).focus; 524 if (focus != null && local.enclosingMethod != null && focus.getParent().getElementType() == IJavaElement.METHOD) { 525 IMethod method = (IMethod) focus.getParent(); 526 if (!CharOperation.equals(local.enclosingMethod.selector, method.getElementName().toCharArray())) { 527 return; 528 } 529 } 530 } 531 locator.report(match); 532 } 533 protected int referenceType() { 534 return IJavaElement.TYPE; 535 } 536 protected void reportDeclaration(ASTNode reference, IJavaElement element, MatchLocator locator, SimpleSet knownTypes) throws CoreException { 537 int maxType = -1; 538 TypeBinding typeBinding = null; 539 if (reference instanceof TypeReference) { 540 typeBinding = ((TypeReference) reference).resolvedType; 541 maxType = Integer.MAX_VALUE; 542 } else if (reference instanceof QualifiedNameReference) { 543 QualifiedNameReference qNameRef = (QualifiedNameReference) reference; 544 Binding binding = qNameRef.binding; 545 maxType = qNameRef.tokens.length - 1; 546 switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) { 547 case Binding.FIELD : typeBinding = qNameRef.actualReceiverType; 549 maxType -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1; 550 break; 551 case Binding.TYPE : if (binding instanceof TypeBinding) 553 typeBinding = (TypeBinding) binding; 554 break; 555 case Binding.VARIABLE : case Binding.TYPE | Binding.VARIABLE : 557 if (binding instanceof ProblemFieldBinding) { 558 typeBinding = qNameRef.actualReceiverType; 559 maxType -= qNameRef.otherBindings == null ? 1 : qNameRef.otherBindings.length + 1; 560 } else if (binding instanceof ProblemBinding) { 561 ProblemBinding pbBinding = (ProblemBinding) binding; 562 typeBinding = pbBinding.searchType; char[] partialQualifiedName = pbBinding.name; 564 maxType = CharOperation.occurencesOf('.', partialQualifiedName) - 1; if (typeBinding == null || maxType < 0) return; 566 } 567 break; 568 } 569 } else if (reference instanceof SingleNameReference) { 570 typeBinding = (TypeBinding) ((SingleNameReference) reference).binding; 571 maxType = 1; 572 } 573 574 if (typeBinding instanceof ArrayBinding) 575 typeBinding = ((ArrayBinding) typeBinding).leafComponentType; 576 if (typeBinding == null || typeBinding instanceof BaseTypeBinding) return; 577 if (typeBinding instanceof ProblemReferenceBinding) { 578 ReferenceBinding original = ((ProblemReferenceBinding) typeBinding).closestMatch(); 579 if (original == null) return; typeBinding = original; 581 } 582 typeBinding = typeBinding.erasure(); 583 reportDeclaration((ReferenceBinding) typeBinding, maxType, locator, knownTypes); 584 } 585 protected void reportDeclaration(ReferenceBinding typeBinding, int maxType, MatchLocator locator, SimpleSet knownTypes) throws CoreException { 586 IType type = locator.lookupType(typeBinding); 587 if (type == null) return; 589 IResource resource = type.getResource(); 590 boolean isBinary = type.isBinary(); 591 IBinaryType info = null; 592 if (isBinary) { 593 if (resource == null) 594 resource = type.getJavaProject().getProject(); 595 info = locator.getBinaryInfo((org.eclipse.jdt.internal.core.ClassFile) type.getClassFile(), resource); 596 } 597 while (maxType >= 0 && type != null) { 598 if (!knownTypes.includes(type)) { 599 if (isBinary) { 600 locator.reportBinaryMemberDeclaration(resource, type, typeBinding, info, SearchMatch.A_ACCURATE); 601 } else { 602 if (typeBinding instanceof ParameterizedTypeBinding) 603 typeBinding = ((ParameterizedTypeBinding) typeBinding).genericType(); 604 ClassScope scope = ((SourceTypeBinding) typeBinding).scope; 605 if (scope != null) { 606 TypeDeclaration typeDecl = scope.referenceContext; 607 int offset = typeDecl.sourceStart; 608 match = new TypeDeclarationMatch(((JavaElement) type).resolved(typeBinding), SearchMatch.A_ACCURATE, offset, typeDecl.sourceEnd-offset+1, locator.getParticipant(), resource); 609 locator.report(match); 610 } 611 } 612 knownTypes.add(type); 613 } 614 typeBinding = typeBinding.enclosingType(); 615 IJavaElement parent = type.getParent(); 616 if (parent instanceof IType) { 617 type = (IType)parent; 618 } else { 619 type = null; 620 } 621 maxType--; 622 } 623 } 624 public int resolveLevel(ASTNode node) { 625 if (node instanceof TypeReference) 626 return resolveLevel((TypeReference) node); 627 if (node instanceof NameReference) 628 return resolveLevel((NameReference) node); 629 return IMPOSSIBLE_MATCH; 631 } 632 public int resolveLevel(Binding binding) { 633 if (binding == null) return INACCURATE_MATCH; 634 if (!(binding instanceof TypeBinding)) return IMPOSSIBLE_MATCH; 635 636 TypeBinding typeBinding = (TypeBinding) binding; 637 if (typeBinding instanceof ArrayBinding) 638 typeBinding = ((ArrayBinding) typeBinding).leafComponentType; 639 if (typeBinding instanceof ProblemReferenceBinding) 640 typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch(); 641 642 if (((InternalSearchPattern) this.pattern).focus instanceof IType && typeBinding instanceof ReferenceBinding) { 643 IPackageFragment pkg = ((IType) ((InternalSearchPattern) this.pattern).focus).getPackageFragment(); 644 if (!PackageReferenceLocator.isDeclaringPackageFragment(pkg, (ReferenceBinding) typeBinding)) 646 return IMPOSSIBLE_MATCH; 647 } 648 649 return resolveLevelForTypeOrEnclosingTypes(this.pattern.simpleName, this.pattern.qualification, typeBinding); 650 } 651 protected int resolveLevel(NameReference nameRef) { 652 Binding binding = nameRef.binding; 653 654 if (nameRef instanceof SingleNameReference) { 655 if (binding instanceof ProblemReferenceBinding) 656 binding = ((ProblemReferenceBinding) binding).closestMatch(); 657 if (binding instanceof ReferenceBinding) 658 return resolveLevelForType((ReferenceBinding) binding); 659 return binding == null || binding instanceof ProblemBinding ? INACCURATE_MATCH : IMPOSSIBLE_MATCH; 660 } 661 662 TypeBinding typeBinding = null; 663 QualifiedNameReference qNameRef = (QualifiedNameReference) nameRef; 664 switch (qNameRef.bits & ASTNode.RestrictiveFlagMASK) { 665 case Binding.FIELD : if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2)) 667 return IMPOSSIBLE_MATCH; typeBinding = nameRef.actualReceiverType; 669 break; 670 case Binding.LOCAL : return IMPOSSIBLE_MATCH; case Binding.TYPE : if (binding instanceof TypeBinding) 674 typeBinding = (TypeBinding) binding; 675 break; 676 680 case Binding.VARIABLE : case Binding.TYPE | Binding.VARIABLE : 682 if (binding instanceof ProblemReferenceBinding) { 683 typeBinding = (TypeBinding) binding; 684 } else if (binding instanceof ProblemFieldBinding) { 685 if (qNameRef.tokens.length < (qNameRef.otherBindings == null ? 2 : qNameRef.otherBindings.length + 2)) 686 return IMPOSSIBLE_MATCH; typeBinding = nameRef.actualReceiverType; 688 } else if (binding instanceof ProblemBinding) { 689 ProblemBinding pbBinding = (ProblemBinding) binding; 690 if (CharOperation.occurencesOf('.', pbBinding.name) <= 0) return INACCURATE_MATCH; 692 typeBinding = pbBinding.searchType; 693 } 694 break; 695 } 696 return resolveLevel(typeBinding); 697 } 698 protected int resolveLevel(TypeReference typeRef) { 699 TypeBinding typeBinding = typeRef.resolvedType; 700 if (typeBinding instanceof ArrayBinding) 701 typeBinding = ((ArrayBinding) typeBinding).leafComponentType; 702 if (typeBinding instanceof ProblemReferenceBinding) 703 typeBinding = ((ProblemReferenceBinding) typeBinding).closestMatch(); 704 705 if (typeRef instanceof SingleTypeReference) { 706 return resolveLevelForType(typeBinding); 707 } else 708 return resolveLevelForTypeOrEnclosingTypes(this.pattern.simpleName, this.pattern.qualification, typeBinding); 709 } 710 714 protected int resolveLevelForType(TypeBinding typeBinding) { 715 return resolveLevelForType( 716 this.pattern.simpleName, 717 this.pattern.qualification, 718 this.pattern.getTypeArguments(), 719 0, 720 typeBinding); 721 } 722 729 protected int resolveLevelForTypeOrEnclosingTypes(char[] simpleNamePattern, char[] qualificationPattern, TypeBinding binding) { 730 if (binding == null) return INACCURATE_MATCH; 731 732 if (binding instanceof ReferenceBinding) { 733 ReferenceBinding type = (ReferenceBinding) binding; 734 while (type != null) { 735 int level = resolveLevelForType(type); 736 if (level != IMPOSSIBLE_MATCH) return level; 737 738 type = type.enclosingType(); 739 } 740 } 741 return IMPOSSIBLE_MATCH; 742 } 743 public String toString() { 744 return "Locator for " + this.pattern.toString(); } 746 } 747 | Popular Tags |