1 11 package org.eclipse.jdt.internal.codeassist; 12 13 import java.util.ArrayList ; 14 import java.util.Locale ; 15 import java.util.Map ; 16 17 import org.eclipse.jdt.core.CompletionContext; 18 import org.eclipse.jdt.core.CompletionFlags; 19 import org.eclipse.jdt.core.CompletionProposal; 20 import org.eclipse.jdt.core.CompletionRequestor; 21 import org.eclipse.jdt.core.Flags; 22 import org.eclipse.jdt.core.IAccessRule; 23 import org.eclipse.jdt.core.IJavaProject; 24 import org.eclipse.jdt.core.IMethod; 25 import org.eclipse.jdt.core.IType; 26 import org.eclipse.jdt.core.JavaModelException; 27 import org.eclipse.jdt.core.Signature; 28 import org.eclipse.jdt.core.compiler.CategorizedProblem; 29 import org.eclipse.jdt.core.compiler.CharOperation; 30 import org.eclipse.jdt.core.compiler.IProblem; 31 import org.eclipse.jdt.core.search.IJavaSearchConstants; 32 33 import org.eclipse.jdt.internal.codeassist.complete.*; 34 import org.eclipse.jdt.internal.codeassist.impl.AssistParser; 35 import org.eclipse.jdt.internal.codeassist.impl.Engine; 36 import org.eclipse.jdt.internal.codeassist.impl.Keywords; 37 import org.eclipse.jdt.internal.compiler.CompilationResult; 38 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; 39 import org.eclipse.jdt.internal.compiler.ast.*; 40 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 41 import org.eclipse.jdt.internal.compiler.env.*; 42 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; 43 import org.eclipse.jdt.internal.compiler.lookup.*; 44 import org.eclipse.jdt.internal.compiler.parser.Scanner; 45 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 46 import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter; 47 import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants; 48 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; 49 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 50 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; 51 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 52 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 53 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 54 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; 55 import org.eclipse.jdt.internal.compiler.util.ObjectVector; 56 import org.eclipse.jdt.internal.core.BasicCompilationUnit; 57 import org.eclipse.jdt.internal.core.INamingRequestor; 58 import org.eclipse.jdt.internal.core.InternalNamingConventions; 59 import org.eclipse.jdt.internal.core.SourceMethod; 60 import org.eclipse.jdt.internal.core.SourceMethodElementInfo; 61 import org.eclipse.jdt.internal.core.SourceType; 62 import org.eclipse.jdt.internal.core.BinaryTypeConverter; 63 import org.eclipse.jdt.internal.core.SearchableEnvironment; 64 import org.eclipse.jdt.internal.core.SourceTypeElementInfo; 65 66 71 public final class CompletionEngine 72 extends Engine 73 implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants { 74 75 public class CompletionProblemFactory extends DefaultProblemFactory { 76 private int lastErrorStart; 77 78 private boolean checkProblems = false; 79 public boolean hasForbiddenProblems = false; 80 public boolean hasAllowedProblems = false; 81 82 public CompletionProblemFactory(Locale loc) { 83 super(loc); 84 } 85 86 public CategorizedProblem createProblem( 87 char[] originatingFileName, 88 int problemId, 89 String [] problemArguments, 90 String [] messageArguments, 91 int severity, 92 int start, 93 int end, 94 int lineNumber, 95 int columnNumber) { 96 97 CategorizedProblem pb = super.createProblem( 98 originatingFileName, 99 problemId, 100 problemArguments, 101 messageArguments, 102 severity, 103 start, 104 end, 105 lineNumber, 106 columnNumber); 107 int id = pb.getID(); 108 if (CompletionEngine.this.actualCompletionPosition > start 109 && this.lastErrorStart < start 110 && pb.isError() 111 && (id & IProblem.Syntax) == 0 112 && (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) { 113 114 CompletionEngine.this.problem = pb; 115 this.lastErrorStart = start; 116 } 117 if (this.checkProblems && !this.hasForbiddenProblems) { 118 switch (id) { 119 case IProblem.UsingDeprecatedType: 120 this.hasForbiddenProblems = 121 CompletionEngine.this.options.checkDeprecation; 122 break; 123 case IProblem.NotVisibleType: 124 this.hasForbiddenProblems = 125 CompletionEngine.this.options.checkVisibility; 126 break; 127 case IProblem.ForbiddenReference: 128 this.hasForbiddenProblems = 129 CompletionEngine.this.options.checkForbiddenReference; 130 break; 131 case IProblem.DiscouragedReference: 132 this.hasForbiddenProblems = 133 CompletionEngine.this.options.checkDiscouragedReference; 134 break; 135 default: 136 if ((severity & ProblemSeverities.Optional) != 0) { 137 this.hasAllowedProblems = true; 138 } else { 139 this.hasForbiddenProblems = true; 140 } 141 142 break; 143 } 144 } 145 146 return pb; 147 } 148 149 public void startCheckingProblems() { 150 this.checkProblems = true; 151 this.hasForbiddenProblems = false; 152 this.hasAllowedProblems = false; 153 } 154 155 public void stopCheckingProblems() { 156 this.checkProblems = false; 157 } 158 } 159 160 private static class AcceptedType { 161 public AcceptedType( 162 char[] packageName, 163 char[] simpleTypeName, 164 char[][] enclosingTypeNames, 165 int modifiers, 166 int accessibility) { 167 this.packageName = packageName; 168 this.simpleTypeName = simpleTypeName; 169 this.enclosingTypeNames = enclosingTypeNames; 170 this.modifiers = modifiers; 171 this.accessibility = accessibility; 172 } 173 public char[] packageName; 174 public char[] simpleTypeName; 175 public char[][] enclosingTypeNames; 176 public int modifiers; 177 public int accessibility; 178 179 public boolean mustBeQualified = false; 180 public char[] fullyQualifiedName = null; 181 public char[] qualifiedTypeName = null; 182 183 public String toString() { 184 StringBuffer buffer = new StringBuffer (); 185 buffer.append('{'); 186 buffer.append(packageName); 187 buffer.append(','); 188 buffer.append(simpleTypeName); 189 buffer.append(','); 190 buffer.append(CharOperation.concatWith(enclosingTypeNames, '.')); 191 buffer.append('}'); 192 return buffer.toString(); 193 } 194 } 195 196 public HashtableOfObject typeCache; 197 198 public static boolean DEBUG = false; 199 public static boolean PERF = false; 200 201 public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false; 203 204 private final static char[] ERROR_PATTERN = "*error*".toCharArray(); private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); private final static char[] SEMICOLON = new char[] { ';' }; 207 208 private final static char[] CLASS = "Class".toCharArray(); private final static char[] VOID = "void".toCharArray(); private final static char[] INT = "int".toCharArray(); private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT}; 212 private final static char[] VALUE = "value".toCharArray(); private final static char[] EXTENDS = "extends".toCharArray(); private final static char[] SUPER = "super".toCharArray(); 216 private final static char[] VARARGS = "...".toCharArray(); 218 private final static char[] IMPORT = "import".toCharArray(); private final static char[] STATIC = "static".toCharArray(); private final static char[] ON_DEMAND = ".*".toCharArray(); private final static char[] IMPORT_END = ";\n".toCharArray(); 223 private final static char[] JAVA_LANG_OBJECT_SIGNATURE = 224 createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT); 225 private final static char[] JAVA_LANG_NAME = 226 CharOperation.concatWith(JAVA_LANG, '.'); 227 228 private final static int NONE = 0; 229 private final static int SUPERTYPE = 1; 230 private final static int SUBTYPE = 2; 231 232 private final static int FIELD = 0; 233 private final static int LOCAL = 1; 234 private final static int ARGUMENT = 2; 235 236 int expectedTypesPtr = -1; 237 TypeBinding[] expectedTypes = new TypeBinding[1]; 238 int expectedTypesFilter; 239 boolean hasJavaLangObjectAsExpectedType = false; 240 int uninterestingBindingsPtr = -1; 241 Binding[] uninterestingBindings = new Binding[1]; 242 int forbbidenBindingsPtr = -1; 243 Binding[] forbbidenBindings = new Binding[1]; 244 int forbbidenBindingsFilter; 245 246 ImportBinding[] favoriteReferenceBindings; 247 248 boolean assistNodeIsClass; 249 boolean assistNodeIsEnum; 250 boolean assistNodeIsException; 251 boolean assistNodeIsInterface; 252 boolean assistNodeIsAnnotation; 253 boolean assistNodeIsConstructor; 254 boolean assistNodeIsSuperType; 255 int assistNodeInJavadoc = 0; 256 boolean assistNodeCanBeSingleMemberAnnotation = false; 257 258 long targetedElement; 259 260 IJavaProject javaProject; 261 CompletionParser parser; 262 CompletionRequestor requestor; 263 CompletionProblemFactory problemFactory; 264 ProblemReporter problemReporter; 265 char[] source; 266 char[] completionToken; 267 char[] qualifiedCompletionToken; 268 boolean resolvingImports = false; 269 boolean resolvingStaticImports = false; 270 boolean insideQualifiedReference = false; 271 boolean noProposal = true; 272 CategorizedProblem problem = null; 273 char[] fileName = null; 274 int startPosition, actualCompletionPosition, endPosition, offset; 275 int javadocTagPosition; HashtableOfObject knownPkgs = new HashtableOfObject(10); 277 HashtableOfObject knownTypes = new HashtableOfObject(10); 278 Scanner nameScanner; 279 280 305 static final BaseTypeBinding[] BASE_TYPES = { 306 TypeBinding.BOOLEAN, 307 TypeBinding.BYTE, 308 TypeBinding.CHAR, 309 TypeBinding.DOUBLE, 310 TypeBinding.FLOAT, 311 TypeBinding.INT, 312 TypeBinding.LONG, 313 TypeBinding.SHORT, 314 TypeBinding.VOID 315 }; 316 static final int BASE_TYPES_LENGTH = BASE_TYPES.length; 317 static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][]; 318 static { 319 for (int i=0; i<BASE_TYPES_LENGTH; i++) { 320 BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName; 321 } 322 } 323 324 static final char[] classField = "class".toCharArray(); static final char[] lengthField = "length".toCharArray(); static final char[] cloneMethod = "clone".toCharArray(); static final char[] THIS = "this".toCharArray(); static final char[] THROWS = "throws".toCharArray(); 330 static InvocationSite FakeInvocationSite = new InvocationSite(){ 331 public TypeBinding[] genericTypeArguments() { return null; } 332 public boolean isSuperAccess(){ return false; } 333 public boolean isTypeAccess(){ return false; } 334 public void setActualReceiverType(ReferenceBinding receiverType) {} 335 public void setDepth(int depth){} 336 public void setFieldIndex(int depth){} 337 public int sourceStart() { return 0; } 338 public int sourceEnd() { return 0; } 339 }; 340 341 private ObjectVector acceptedTypes; 342 343 360 public CompletionEngine( 361 SearchableEnvironment nameEnvironment, 362 CompletionRequestor requestor, 363 Map settings, 364 IJavaProject javaProject) { 365 super(settings); 366 this.javaProject = javaProject; 367 this.requestor = requestor; 368 this.nameEnvironment = nameEnvironment; 369 this.typeCache = new HashtableOfObject(5); 370 371 this.problemFactory = new CompletionProblemFactory(Locale.getDefault()); 372 this.problemReporter = new ProblemReporter( 373 DefaultErrorHandlingPolicies.proceedWithAllProblems(), 374 this.compilerOptions, 375 problemFactory); 376 this.lookupEnvironment = 377 new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment); 378 this.parser = 379 new CompletionParser(this.problemReporter); 380 this.nameScanner = 381 new Scanner( 382 false , 383 false , 384 false , 385 this.compilerOptions.sourceLevel, 386 null , 387 null, 388 true); 389 } 390 391 399 public void acceptType( 400 char[] packageName, 401 char[] simpleTypeName, 402 char[][] enclosingTypeNames, 403 int modifiers, 404 AccessRestriction accessRestriction) { 405 406 if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return; 407 408 if (this.options.checkVisibility) { 409 if((modifiers & ClassFileConstants.AccPublic) == 0) { 410 if((modifiers & ClassFileConstants.AccPrivate) != 0) return; 411 412 char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.'); 413 if(!CharOperation.equals(packageName, currentPackage)) return; 414 } 415 } 416 417 int accessibility = IAccessRule.K_ACCESSIBLE; 418 if(accessRestriction != null) { 419 switch (accessRestriction.getProblemId()) { 420 case IProblem.ForbiddenReference: 421 if (this.options.checkForbiddenReference) { 422 return; 423 } 424 accessibility = IAccessRule.K_NON_ACCESSIBLE; 425 break; 426 case IProblem.DiscouragedReference: 427 if (this.options.checkDiscouragedReference) { 428 return; 429 } 430 accessibility = IAccessRule.K_DISCOURAGED; 431 break; 432 } 433 } 434 435 if(acceptedTypes == null) { 436 acceptedTypes = new ObjectVector(); 437 } 438 acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility)); 439 } 440 441 private void acceptTypes(Scope scope) { 442 if(this.acceptedTypes == null) return; 443 444 int length = this.acceptedTypes.size(); 445 446 if(length == 0) return; 447 448 HashtableOfObject onDemandFound = new HashtableOfObject(); 449 450 next : for (int i = 0; i < length; i++) { 451 AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i); 452 char[] packageName = acceptedType.packageName; 453 char[] simpleTypeName = acceptedType.simpleTypeName; 454 char[][] enclosingTypeNames = acceptedType.enclosingTypeNames; 455 int modifiers = acceptedType.modifiers; 456 int accessibility = acceptedType.accessibility; 457 458 char[] typeName; 459 char[] flatEnclosingTypeNames; 460 if(enclosingTypeNames == null || enclosingTypeNames.length == 0) { 461 flatEnclosingTypeNames = null; 462 typeName = simpleTypeName; 463 } else { 464 flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.'); 465 typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.'); 466 } 467 char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.'); 468 469 if (this.knownTypes.containsKey(fullyQualifiedName)) continue next; 470 471 this.knownTypes.put(fullyQualifiedName, this); 472 473 if (this.resolvingImports) { 474 char[] completionName; 475 476 if(this.resolvingStaticImports) { 477 if(enclosingTypeNames == null || enclosingTypeNames.length == 0) { 478 completionName = CharOperation.concat(fullyQualifiedName, new char[] { '.' }); 479 } else if ((modifiers & ClassFileConstants.AccStatic) == 0) { 480 continue next; 481 } else { 482 completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' }); 483 } 484 } else { 485 completionName = CharOperation.concat(fullyQualifiedName, new char[] { ';' }); 486 } 487 488 int relevance = computeBaseRelevance(); 489 relevance += computeRelevanceForResolution(); 490 relevance += computeRelevanceForInterestingProposal(); 491 relevance += computeRelevanceForRestrictions(accessibility); 492 if(insideQualifiedReference) { 493 relevance += computeRelevanceForCaseMatching(this.completionToken, fullyQualifiedName); 494 } else { 495 relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName); 496 } 497 498 this.noProposal = false; 499 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 500 createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance); 501 } 502 } else { 503 if(!this.importCachesInitialized) { 504 this.initializeImportCaches(); 505 } 506 507 for (int j = 0; j < this.importCacheCount; j++) { 508 char[][] importName = this.importsCache[j]; 509 if(CharOperation.equals(typeName, importName[0])) { 510 proposeType( 511 packageName, 512 simpleTypeName, 513 modifiers, 514 accessibility, 515 typeName, 516 fullyQualifiedName, 517 !CharOperation.equals(fullyQualifiedName, importName[1]), 518 scope); 519 continue next; 520 } 521 } 522 523 524 if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) { 525 proposeType( 526 packageName, 527 simpleTypeName, 528 modifiers, 529 accessibility, 530 typeName, 531 fullyQualifiedName, 532 false, 533 scope); 534 continue next; 535 } else { 536 char[] fullyQualifiedEnclosingTypeOrPackageName = null; 537 538 AcceptedType foundType = null; 539 if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) { 540 for (int j = 0; j < this.onDemandImportCacheCount; j++) { 541 ImportBinding importBinding = this.onDemandImportsCache[j]; 542 543 char[][] importName = importBinding.compoundName; 544 char[] importFlatName = CharOperation.concatWith(importName, '.'); 545 546 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 547 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) { 548 fullyQualifiedEnclosingTypeOrPackageName = 549 CharOperation.concat( 550 packageName, 551 flatEnclosingTypeNames, 552 '.'); 553 } else { 554 fullyQualifiedEnclosingTypeOrPackageName = 555 packageName; 556 } 557 } 558 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 559 if(importBinding.isStatic()) { 560 if((modifiers & ClassFileConstants.AccStatic) != 0) { 561 acceptedType.qualifiedTypeName = typeName; 562 acceptedType.fullyQualifiedName = fullyQualifiedName; 563 onDemandFound.put( 564 simpleTypeName, 565 acceptedType); 566 continue next; 567 } 568 } else { 569 acceptedType.qualifiedTypeName = typeName; 570 acceptedType.fullyQualifiedName = fullyQualifiedName; 571 onDemandFound.put( 572 simpleTypeName, 573 acceptedType); 574 continue next; 575 } 576 } 577 } 578 } else if(!foundType.mustBeQualified){ 579 done : for (int j = 0; j < this.onDemandImportCacheCount; j++) { 580 ImportBinding importBinding = this.onDemandImportsCache[j]; 581 582 char[][] importName = importBinding.compoundName; 583 char[] importFlatName = CharOperation.concatWith(importName, '.'); 584 585 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 586 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) { 587 fullyQualifiedEnclosingTypeOrPackageName = 588 CharOperation.concat( 589 packageName, 590 flatEnclosingTypeNames, 591 '.'); 592 } else { 593 fullyQualifiedEnclosingTypeOrPackageName = 594 packageName; 595 } 596 } 597 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 598 if(importBinding.isStatic()) { 599 if((modifiers & ClassFileConstants.AccStatic) != 0) { 600 foundType.mustBeQualified = true; 601 break done; 602 } 603 } else { 604 foundType.mustBeQualified = true; 605 break done; 606 } 607 } 608 } 609 } 610 proposeType( 611 packageName, 612 simpleTypeName, 613 modifiers, 614 accessibility, 615 typeName, 616 fullyQualifiedName, 617 true, 618 scope); 619 } 620 } 621 } 622 char[][] keys = onDemandFound.keyTable; 623 Object [] values = onDemandFound.valueTable; 624 int max = keys.length; 625 for (int i = 0; i < max; i++) { 626 if(keys[i] != null) { 627 AcceptedType value = (AcceptedType) values[i]; 628 if(value != null) { 629 proposeType( 630 value.packageName, 631 value.simpleTypeName, 632 value.modifiers, 633 value.accessibility, 634 value.qualifiedTypeName, 635 value.fullyQualifiedName, 636 value.mustBeQualified, 637 scope); 638 } 639 } 640 } 641 this.acceptedTypes = null; } 643 644 public void acceptUnresolvedName(char[] name) { 645 int relevance = computeBaseRelevance(); 646 relevance += computeRelevanceForResolution(false); 647 relevance += computeRelevanceForInterestingProposal(); 648 relevance += computeRelevanceForCaseMatching(completionToken, name); 649 relevance += computeRelevanceForQualification(false); 650 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); CompletionEngine.this.noProposal = false; 652 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 653 CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition); 654 proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE); 655 proposal.setPackageName(JAVA_LANG_NAME); 656 proposal.setTypeName(OBJECT); 657 proposal.setName(name); 658 proposal.setCompletion(name); 659 proposal.setFlags(Flags.AccDefault); 660 proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset); 661 proposal.setRelevance(relevance); 662 CompletionEngine.this.requestor.accept(proposal); 663 if(DEBUG) { 664 CompletionEngine.this.printDebug(proposal); 665 } 666 } 667 } 668 669 private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) { 671 int paramLength = parameters.length; 672 int argLength = arguments.length; 673 int lastIndex = argLength; 674 if (isVarargs) { 675 lastIndex = paramLength - 1; 676 if (paramLength == argLength) { TypeBinding varArgType = parameters[lastIndex]; TypeBinding lastArgument = arguments[lastIndex]; 679 if (varArgType != lastArgument && !lastArgument.isCompatibleWith(varArgType)) 680 return false; 681 } else if (paramLength < argLength) { TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType(); 683 for (int i = lastIndex; i < argLength; i++) 684 if (varArgType != arguments[i] && !arguments[i].isCompatibleWith(varArgType)) 685 return false; 686 } else if (lastIndex != argLength) { return false; 688 } 689 } else { 691 if(paramLength != argLength) 692 return false; 693 } 694 for (int i = 0; i < lastIndex; i++) 695 if (parameters[i] != arguments[i] && !arguments[i].isCompatibleWith(parameters[i])) 696 return false; 697 return true; 698 } 699 700 private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope) { 701 char[] completionName = fullyQualifiedName; 702 if(isQualified) { 703 if (packageName == null || packageName.length == 0) 704 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 705 return; } else { 707 completionName = simpleTypeName; 708 } 709 710 TypeBinding guessedType = null; 711 if ((modifiers & ClassFileConstants.AccAnnotation) != 0 && 712 this.assistNodeIsAnnotation && 713 (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) { 714 char[][] cn = CharOperation.splitOn('.', fullyQualifiedName); 715 716 TypeReference ref; 717 if (cn.length == 1) { 718 ref = new SingleTypeReference(simpleTypeName, 0); 719 } else { 720 ref = new QualifiedTypeReference(cn,new long[cn.length]); 721 } 722 723 switch (scope.kind) { 724 case Scope.METHOD_SCOPE : 725 case Scope.BLOCK_SCOPE : 726 guessedType = ref.resolveType((BlockScope)scope); 727 break; 728 case Scope.CLASS_SCOPE : 729 guessedType = ref.resolveType((ClassScope)scope); 730 break; 731 } 732 733 if (guessedType == null || !guessedType.isValidBinding()) return; 734 735 if (!hasPossibleAnnotationTarget(guessedType, scope)) return; 736 } 737 738 int relevance = computeBaseRelevance(); 739 relevance += computeRelevanceForResolution(); 740 relevance += computeRelevanceForInterestingProposal(); 741 relevance += computeRelevanceForRestrictions(accessibility); 742 relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName); 743 relevance += computeRelevanceForExpectingType(packageName, simpleTypeName); 744 relevance += computeRelevanceForQualification(isQualified); 745 746 int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation); 747 switch (kind) { 748 case ClassFileConstants.AccAnnotation: 749 case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface: 750 relevance += computeRelevanceForAnnotation(); 751 if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType); 752 relevance += computeRelevanceForInterface(); 753 break; 754 case ClassFileConstants.AccEnum: 755 relevance += computeRelevanceForEnum(); 756 break; 757 case ClassFileConstants.AccInterface: 758 relevance += computeRelevanceForInterface(); 759 break; 760 default: 761 relevance += computeRelevanceForClass(); 762 relevance += computeRelevanceForException(simpleTypeName); 763 break; 764 } 765 766 this.noProposal = false; 767 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 768 createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance); 769 } 770 } 771 772 779 public void acceptPackage(char[] packageName) { 780 781 if (this.knownPkgs.containsKey(packageName)) return; 782 783 this.knownPkgs.put(packageName, this); 784 785 char[] completion; 786 if(this.resolvingImports) { 787 if(this.resolvingStaticImports) { 788 completion = CharOperation.concat(packageName, new char[] { '.' }); 789 } else { 790 completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' }); 791 } 792 } else { 793 completion = packageName; 794 } 795 796 int relevance = computeBaseRelevance(); 797 relevance += computeRelevanceForResolution(); 798 relevance += computeRelevanceForInterestingProposal(); 799 relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName); 800 if(!this.resolvingImports) { 801 relevance += computeRelevanceForQualification(true); 802 } 803 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 804 805 this.noProposal = false; 806 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 807 CompletionProposal proposal = this.createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition); 808 proposal.setDeclarationSignature(packageName); 809 proposal.setPackageName(packageName); 810 proposal.setCompletion(completion); 811 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 812 proposal.setRelevance(relevance); 813 this.requestor.accept(proposal); 814 if(DEBUG) { 815 this.printDebug(proposal); 816 } 817 } 818 } 819 820 private void buildContext( 821 ASTNode astNode, 822 ASTNode astNodeParent, 823 Binding qualifiedBinding, 824 Scope scope) { 825 CompletionContext context = new CompletionContext(); 826 827 if (this.expectedTypesPtr > -1) { 829 int length = this.expectedTypesPtr + 1; 830 char[][] expTypes = new char[length][]; 831 char[][] expKeys = new char[length][]; 832 for (int i = 0; i < length; i++) { 833 expTypes[i] = getSignature(this.expectedTypes[i]); 834 expKeys[i] = this.expectedTypes[i].computeUniqueKey(); 835 } 836 context.setExpectedTypesSignatures(expTypes); 837 context.setExpectedTypesKeys(expKeys); 838 } 839 840 context.setOffset(this.actualCompletionPosition + 1 - this.offset); 841 842 if (astNode instanceof CompletionOnJavadoc) { 844 this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags(); 845 context.setJavadoc(this.assistNodeInJavadoc); 846 } 847 848 if (!(astNode instanceof CompletionOnJavadoc)) { 849 CompletionScanner scanner = (CompletionScanner)this.parser.scanner; 850 context.setToken(scanner.completionIdentifier); 851 context.setTokenRange( 852 scanner.completedIdentifierStart - this.offset, 853 scanner.completedIdentifierEnd - this.offset, 854 scanner.endOfEmptyToken - this.offset); 855 } else if(astNode instanceof CompletionOnJavadocTag) { 856 CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode; 857 context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token)); 858 context.setTokenRange( 859 javadocTag.tagSourceStart - this.offset, 860 javadocTag.tagSourceEnd - this.offset, 861 ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset); 862 } else { 863 CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner; 864 context.setToken(scanner.completionIdentifier); 865 context.setTokenRange( 866 scanner.completedIdentifierStart - this.offset, 867 scanner.completedIdentifierEnd - this.offset, 868 scanner.endOfEmptyToken - this.offset); 869 } 870 871 if(astNode instanceof CompletionOnStringLiteral) { 872 context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL); 873 } else { 874 context.setTokenKind(CompletionContext.TOKEN_KIND_NAME); 875 } 876 877 if(DEBUG) { 878 System.out.println(context.toString()); 879 } 880 this.requestor.acceptContext(context); 881 } 882 883 private boolean complete(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation) { 884 885 setSourceRange(astNode.sourceStart, astNode.sourceEnd); 886 887 scope = computeForbiddenBindings(astNode, astNodeParent, scope); 888 computeUninterestingBindings(astNodeParent, scope); 889 if(astNodeParent != null) { 890 if(!isValidParent(astNodeParent, astNode, scope)) return false; 891 computeExpectedTypes(astNodeParent, astNode, scope); 892 } 893 894 buildContext(astNode, astNodeParent, qualifiedBinding, scope); 895 896 if (astNode instanceof CompletionOnFieldType) { 897 898 CompletionOnFieldType field = (CompletionOnFieldType) astNode; 899 CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type; 900 this.completionToken = type.token; 901 setSourceRange(type.sourceStart, type.sourceEnd); 902 903 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 904 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 905 findKeywordsForMember(this.completionToken, field.modifiers); 906 } 907 908 if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) { 909 SourceTypeBinding enclosingType = scope.enclosingSourceType(); 910 if (!enclosingType.isAnnotationType()) { 911 if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 912 findMethods(this.completionToken,null,null,enclosingType,scope,new ObjectVector(),false,false,true,null,null,false,false,true,null, null, null, false); 913 } 914 if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 915 proposeNewMethod(this.completionToken, enclosingType); 916 } 917 } 918 } 919 } else if (astNode instanceof CompletionOnMethodReturnType) { 920 921 CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode; 922 SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType; 923 this.completionToken = type.token; 924 setSourceRange(type.sourceStart, type.sourceEnd); 925 findTypesAndPackages(this.completionToken, scope.parent, new ObjectVector()); 926 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 927 findKeywordsForMember(this.completionToken, method.modifiers); 928 } 929 930 if (method.modifiers == ClassFileConstants.AccDefault) { 931 SourceTypeBinding enclosingType = scope.enclosingSourceType(); 932 if (!enclosingType.isAnnotationType()) { 933 if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 934 findMethods(this.completionToken,null,null,scope.enclosingSourceType(),scope,new ObjectVector(),false,false,true,null,null,false,false,true,null, null, null, false); 935 } 936 if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 937 proposeNewMethod(this.completionToken, scope.enclosingSourceType()); 938 } 939 } 940 } 941 } else if (astNode instanceof CompletionOnSingleNameReference) { 942 943 CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode; 944 this.completionToken = singleNameReference.token; 945 SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null; 946 if (switchStatement != null 947 && switchStatement.expression.resolvedType != null 948 && switchStatement.expression.resolvedType.isEnum()) { 949 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 950 this.assistNodeIsEnum = true; 951 this.findEnumConstant(this.completionToken, (SwitchStatement) astNodeParent); 952 } 953 } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) { 954 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 955 } else { 956 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 957 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference); 958 959 findUnresolvedReference( 960 singleNameReference.sourceStart, 961 singleNameReference.sourceEnd, 962 (BlockScope)scope, 963 alreadyDefinedName); 964 } 965 findVariablesAndMethods( 966 this.completionToken, 967 scope, 968 singleNameReference, 969 scope, 970 insideTypeAnnotation, 971 singleNameReference.isInsideAnnotationAttribute); 972 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 974 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 975 if (this.completionToken != null && this.completionToken.length != 0) { 976 findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false); 977 } else { 978 findTrueOrFalseKeywords(singleNameReference.possibleKeywords); 979 } 980 } 981 if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){ 982 if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) { 983 ReferenceBinding ref = scope.enclosingSourceType(); 984 findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference); 985 } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) { 986 ReferenceBinding ref = scope.enclosingSourceType(); 987 findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference); 988 } 989 } 990 } 991 992 } else if (astNode instanceof CompletionOnSingleTypeReference) { 993 994 CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode; 995 996 this.completionToken = singleRef.token; 997 998 this.assistNodeIsClass = singleRef.isClass(); 999 this.assistNodeIsException = singleRef.isException(); 1000 this.assistNodeIsInterface = singleRef.isInterface(); 1001 this.assistNodeIsConstructor = singleRef.isConstructorType; 1002 this.assistNodeIsSuperType = singleRef.isSuperType(); 1003 1004 if (qualifiedBinding == null) { 1006 if (this.completionToken.length == 0 && 1007 (astNodeParent instanceof ParameterizedSingleTypeReference || 1008 astNodeParent instanceof ParameterizedQualifiedTypeReference)) { 1009 this.setSourceRange(astNode.sourceStart, astNode.sourceStart - 1, false); 1010 1011 findParameterizedType((TypeReference)astNodeParent, scope); 1012 } else { 1013 ObjectVector typesFound = new ObjectVector(); 1014 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 1015 findExceptionFromTryStatement( 1016 this.completionToken, 1017 null, 1018 scope.enclosingSourceType(), 1019 (BlockScope)scope, 1020 typesFound); 1021 } 1022 findTypesAndPackages(this.completionToken, scope, typesFound); 1023 } 1024 } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 1025 findMemberTypes( 1026 this.completionToken, 1027 (ReferenceBinding) qualifiedBinding, 1028 scope, 1029 scope.enclosingSourceType(), 1030 false, 1031 false, 1032 false, 1033 false, 1034 !this.assistNodeIsConstructor, 1035 null, 1036 new ObjectVector()); 1037 } 1038 } else if (astNode instanceof CompletionOnQualifiedNameReference) { 1039 1040 this.insideQualifiedReference = true; 1041 CompletionOnQualifiedNameReference ref = 1042 (CompletionOnQualifiedNameReference) astNode; 1043 this.completionToken = ref.completionIdentifier; 1044 long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1]; 1045 1046 if (qualifiedBinding.problemId() == ProblemReasons.NotFound) { 1047 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1048 if (this.assistNodeInJavadoc == 0 && 1056 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 1057 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) { 1058 if(ref.tokens.length == 1) { 1059 findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation); 1060 } 1061 } 1062 } else if (qualifiedBinding instanceof VariableBinding) { 1063 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1064 TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type; 1065 if (receiverType != null) { 1066 findFieldsAndMethods(this.completionToken, receiverType.capture(scope, ref.sourceEnd), scope, ref, scope,false,false, null, null, null, false); 1067 } else if (this.assistNodeInJavadoc == 0 && 1068 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 1069 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) { 1070 boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF); 1071 boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF); 1072 if (proposeField || proposeMethod) { 1073 if (qualifiedBinding instanceof LocalVariableBinding) { 1074 LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding; 1082 1083 findFieldsAndMethodsFromMissingType( 1084 this.completionToken, 1085 localVariableBinding.declaration.type, 1086 localVariableBinding.declaringScope, 1087 ref, 1088 scope); 1089 } 1090 } 1091 } 1092 1093 } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 1094 boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute; 1095 ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding; 1096 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1097 1098 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 1099 findMemberTypes( 1100 this.completionToken, 1101 receiverType, 1102 scope, 1103 scope.enclosingSourceType(), 1104 false, 1105 true, 1106 new ObjectVector()); 1107 } 1108 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 1109 findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope); 1110 } 1111 1112 MethodScope methodScope = null; 1113 if (!isInsideAnnotationAttribute && 1114 !this.requestor.isIgnored(CompletionProposal.KEYWORD) && 1115 ((scope instanceof MethodScope && !((MethodScope)scope).isStatic) 1116 || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) { 1117 if (this.completionToken.length > 0) { 1118 findKeywords(this.completionToken, new char[][]{Keywords.THIS}, false, true); 1119 } else { 1120 int relevance = computeBaseRelevance(); 1121 relevance += computeRelevanceForResolution(); 1122 relevance += computeRelevanceForInterestingProposal(); 1123 relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS); 1124 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); relevance += R_NON_INHERITED; 1126 1127 this.noProposal = false; 1128 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 1129 CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 1130 proposal.setName(Keywords.THIS); 1131 proposal.setCompletion(Keywords.THIS); 1132 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 1133 proposal.setRelevance(relevance); 1134 this.requestor.accept(proposal); 1135 if (DEBUG) { 1136 this.printDebug(proposal); 1137 } 1138 } 1139 } 1140 } 1141 1142 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 1143 findFields( 1144 this.completionToken, 1145 receiverType, 1146 scope, 1147 new ObjectVector(), 1148 new ObjectVector(), 1149 true, 1150 ref, 1151 scope, 1152 false, 1153 false, 1154 null, 1155 null, 1156 null, 1157 false); 1158 } 1159 1160 if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1161 findMethods( 1162 this.completionToken, 1163 null, 1164 null, 1165 receiverType, 1166 scope, 1167 new ObjectVector(), 1168 true, 1169 false, 1170 false, 1171 ref, 1172 scope, 1173 false, 1174 false, 1175 false, 1176 null, 1177 null, 1178 null, 1179 false); 1180 } 1181 1182 } else if (qualifiedBinding instanceof PackageBinding) { 1183 1184 setSourceRange(astNode.sourceStart, (int) completionPosition); 1185 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 1187 } 1188 } else if (astNode instanceof CompletionOnQualifiedTypeReference) { 1189 1190 this.insideQualifiedReference = true; 1191 1192 CompletionOnQualifiedTypeReference ref = 1193 (CompletionOnQualifiedTypeReference) astNode; 1194 1195 this.assistNodeIsClass = ref.isClass(); 1196 this.assistNodeIsException = ref.isException(); 1197 this.assistNodeIsInterface = ref.isInterface(); 1198 this.assistNodeIsSuperType = ref.isSuperType(); 1199 1200 this.completionToken = ref.completionIdentifier; 1201 long completionPosition = ref.sourcePositions[ref.tokens.length]; 1202 1203 if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 1205 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 1206 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1207 1208 ObjectVector typesFound = new ObjectVector(); 1209 1210 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 1211 findExceptionFromTryStatement( 1212 this.completionToken, 1213 (ReferenceBinding)qualifiedBinding, 1214 scope.enclosingSourceType(), 1215 (BlockScope)scope, 1216 typesFound); 1217 } 1218 1219 findMemberTypes( 1220 this.completionToken, 1221 (ReferenceBinding) qualifiedBinding, 1222 scope, 1223 scope.enclosingSourceType(), 1224 false, 1225 false, 1226 typesFound); 1227 } 1228 } else if (qualifiedBinding instanceof PackageBinding) { 1229 1230 setSourceRange(astNode.sourceStart, (int) completionPosition); 1231 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 1233 } 1234 } else if (astNode instanceof CompletionOnMemberAccess) { 1235 this.insideQualifiedReference = true; 1236 CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode; 1237 long completionPosition = access.nameSourcePosition; 1238 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1239 1240 this.completionToken = access.token; 1241 1242 if (qualifiedBinding.problemId() == ProblemReasons.NotFound) { 1243 if (this.assistNodeInJavadoc == 0 && 1251 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 1252 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) { 1253 ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding; 1254 findFieldsAndMethodsFromMissingReturnType( 1255 problemMethodBinding.selector, 1256 problemMethodBinding.parameters, 1257 scope, 1258 access, 1259 insideTypeAnnotation); 1260 } 1261 } else { 1262 if (!access.isInsideAnnotation) { 1263 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 1264 findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false); 1265 } 1266 1267 findFieldsAndMethods( 1268 this.completionToken, 1269 ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd), 1270 scope, 1271 access, 1272 scope, 1273 false, 1274 access.receiver instanceof SuperReference, 1275 null, 1276 null, 1277 null, 1278 false); 1279 } 1280 } 1281 1282 } else if (astNode instanceof CompletionOnMessageSend) { 1283 setSourceRange(astNode.sourceStart, astNode.sourceEnd, false); 1284 1285 CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode; 1286 TypeBinding[] argTypes = computeTypes(messageSend.arguments); 1287 this.completionToken = messageSend.selector; 1288 if (qualifiedBinding == null) { 1289 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1290 findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope); 1291 } 1292 } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1293 findMethods( 1294 this.completionToken, 1295 null, 1296 argTypes, 1297 (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd), 1298 scope, 1299 new ObjectVector(), 1300 false, 1301 true, 1302 false, 1303 messageSend, 1304 scope, 1305 false, 1306 messageSend.receiver instanceof SuperReference, 1307 false, 1308 null, 1309 null, 1310 null, 1311 false); 1312 } 1313 } else if (astNode instanceof CompletionOnExplicitConstructorCall) { 1314 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1315 setSourceRange(astNode.sourceStart, astNode.sourceEnd, false); 1316 1317 CompletionOnExplicitConstructorCall constructorCall = 1318 (CompletionOnExplicitConstructorCall) astNode; 1319 TypeBinding[] argTypes = computeTypes(constructorCall.arguments); 1320 findConstructors( 1321 (ReferenceBinding) qualifiedBinding, 1322 argTypes, 1323 scope, 1324 constructorCall, 1325 false); 1326 } 1327 } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) { 1328 setSourceRange(astNode.sourceStart, astNode.sourceEnd, false); 1329 1330 CompletionOnQualifiedAllocationExpression allocExpression = 1331 (CompletionOnQualifiedAllocationExpression) astNode; 1332 TypeBinding[] argTypes = computeTypes(allocExpression.arguments); 1333 1334 ReferenceBinding ref = (ReferenceBinding) qualifiedBinding; 1335 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) 1336 && ref.isClass() 1337 && !ref.isAbstract()) { 1338 findConstructors( 1339 ref, 1340 argTypes, 1341 scope, 1342 allocExpression, 1343 false); 1344 } 1345 if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION) 1346 && !ref.isFinal() 1347 && !ref.isEnum()){ 1348 findAnonymousType( 1349 ref, 1350 argTypes, 1351 scope, 1352 allocExpression); 1353 } 1354 } else if (astNode instanceof CompletionOnClassLiteralAccess) { 1355 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 1356 CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode; 1357 setSourceRange(access.classStart, access.sourceEnd); 1358 1359 this.completionToken = access.completionIdentifier; 1360 1361 findClassField(this.completionToken, (TypeBinding) qualifiedBinding, scope); 1362 } 1363 } else if (astNode instanceof CompletionOnMethodName) { 1364 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 1365 CompletionOnMethodName method = (CompletionOnMethodName) astNode; 1366 1367 setSourceRange(method.sourceStart, method.selectorEnd); 1368 1369 FieldBinding[] fields = scope.enclosingSourceType().fields(); 1370 char[][] excludeNames = new char[fields.length][]; 1371 for(int i = 0 ; i < fields.length ; i++){ 1372 excludeNames[i] = fields[i].name; 1373 } 1374 1375 this.completionToken = method.selector; 1376 1377 findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers); 1378 } 1379 } else if (astNode instanceof CompletionOnFieldName) { 1380 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 1381 CompletionOnFieldName field = (CompletionOnFieldName) astNode; 1382 1383 FieldBinding[] fields = scope.enclosingSourceType().fields(); 1384 char[][] excludeNames = new char[fields.length][]; 1385 for(int i = 0 ; i < fields.length ; i++){ 1386 excludeNames[i] = fields[i].name; 1387 } 1388 1389 this.completionToken = field.realName; 1390 1391 findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers); 1392 } 1393 } else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) { 1394 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 1395 LocalDeclaration variable = (LocalDeclaration) astNode; 1396 1397 int kind; 1398 if (variable instanceof CompletionOnLocalName){ 1399 this.completionToken = ((CompletionOnLocalName) variable).realName; 1400 kind = LOCAL; 1401 } else { 1402 CompletionOnArgumentName arg = (CompletionOnArgumentName) variable; 1403 this.completionToken = arg.realName; 1404 kind = arg.isCatchArgument ? LOCAL : ARGUMENT; 1405 } 1406 1407 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable); 1408 1409 char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName); 1410 1411 LocalVariableBinding[] locals = ((BlockScope)scope).locals; 1412 char[][] discouragedNames = new char[locals.length][]; 1413 int localCount = 0; 1414 for(int i = 0 ; i < locals.length ; i++){ 1415 if (locals[i] != null) { 1416 discouragedNames[localCount++] = locals[i].name; 1417 } 1418 } 1419 1420 System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount); 1421 1422 findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers); 1423 } 1424 } else if (astNode instanceof CompletionOnKeyword) { 1425 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 1426 CompletionOnKeyword keyword = (CompletionOnKeyword)astNode; 1427 findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false); 1428 } 1429 } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) { 1430 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 1431 CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode; 1432 1433 this.insideQualifiedReference = true; 1434 1435 this.assistNodeIsClass = ref.isClass(); 1436 this.assistNodeIsException = ref.isException(); 1437 this.assistNodeIsInterface = ref.isInterface(); 1438 this.assistNodeIsSuperType = ref.isSuperType(); 1439 1440 this.completionToken = ref.completionIdentifier; 1441 long completionPosition = ref.sourcePositions[ref.tokens.length]; 1442 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1443 1444 ObjectVector typesFound = new ObjectVector(); 1445 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 1446 findExceptionFromTryStatement( 1447 this.completionToken, 1448 (ReferenceBinding)qualifiedBinding, 1449 scope.enclosingSourceType(), 1450 (BlockScope)scope, 1451 typesFound); 1452 } 1453 1454 findMemberTypes( 1455 this.completionToken, 1456 (ReferenceBinding) qualifiedBinding, 1457 scope, 1458 scope.enclosingSourceType(), 1459 false, 1460 false, 1461 typesFound); 1462 } 1463 } else if (astNode instanceof CompletionOnMarkerAnnotationName) { 1464 CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode; 1465 1466 CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext(); 1467 if (fakeType.annotations[0] == annot) { 1468 if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) { 1471 this.targetedElement = computeTargetedElement(fakeType); 1472 } 1473 1474 } 1475 1476 this.assistNodeIsAnnotation = true; 1477 if (annot.type instanceof CompletionOnSingleTypeReference) { 1478 CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type; 1479 this.completionToken = type.token; 1480 setSourceRange(type.sourceStart, type.sourceEnd); 1481 1482 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 1483 } else if (annot.type instanceof CompletionOnQualifiedTypeReference) { 1484 this.insideQualifiedReference = true; 1485 1486 CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type; 1487 this.completionToken = type.completionIdentifier; 1488 long completionPosition = type.sourcePositions[type.tokens.length]; 1489 if (qualifiedBinding instanceof PackageBinding) { 1490 1491 setSourceRange(astNode.sourceStart, (int) completionPosition); 1492 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 1494 } else { 1495 setSourceRange((int) (completionPosition >>> 32), (int) completionPosition); 1496 1497 findMemberTypes( 1498 this.completionToken, 1499 (ReferenceBinding) qualifiedBinding, 1500 scope, 1501 scope.enclosingSourceType(), 1502 false, 1503 false, 1504 new ObjectVector()); 1505 } 1506 } 1507 } else if (astNode instanceof CompletionOnMemberValueName) { 1508 CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode; 1509 Annotation annotation = (Annotation) astNodeParent; 1510 1511 this.completionToken = memberValuePair.name; 1512 1513 ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType; 1514 1515 if (annotationType != null && annotationType.isAnnotationType()) { 1516 if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) { 1517 this.findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType); 1518 } 1519 if (this.assistNodeCanBeSingleMemberAnnotation) { 1520 if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) { 1521 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 1522 } else { 1523 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 1524 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite); 1525 1526 findUnresolvedReference( 1527 memberValuePair.sourceStart, 1528 memberValuePair.sourceEnd, 1529 (BlockScope)scope, 1530 alreadyDefinedName); 1531 } 1532 findVariablesAndMethods( 1533 this.completionToken, 1534 scope, 1535 FakeInvocationSite, 1536 scope, 1537 insideTypeAnnotation, 1538 true); 1539 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 1541 } 1542 } 1543 } 1544 } else if(astNode instanceof CompletionOnBrankStatementLabel) { 1545 if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) { 1546 CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode; 1547 1548 this.completionToken = label.label; 1549 1550 this.findLabels(this.completionToken, label.possibleLabels); 1551 } 1552 } else if(astNode instanceof CompletionOnMessageSendName) { 1553 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1554 CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode; 1555 1556 this.insideQualifiedReference = true; 1557 this.completionToken = messageSend.selector; 1558 boolean onlyStatic = false; 1559 TypeBinding receiverType = null; 1560 if(qualifiedBinding instanceof VariableBinding) { 1561 receiverType = ((VariableBinding)qualifiedBinding).type; 1562 } else if(qualifiedBinding instanceof MethodBinding) { 1563 receiverType = ((MethodBinding)qualifiedBinding).returnType; 1564 } else if(qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 1565 onlyStatic = true; 1566 receiverType = (TypeBinding)qualifiedBinding; 1567 } 1568 if(receiverType != null && receiverType instanceof ReferenceBinding) { 1569 TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments); 1570 if(typeArgTypes != null) { 1571 this.findMethods( 1572 this.completionToken, 1573 typeArgTypes, 1574 null, 1575 (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd), 1576 scope, 1577 new ObjectVector(), 1578 onlyStatic, 1579 false, 1580 false, 1581 messageSend, 1582 scope, 1583 false, 1584 false, 1585 false, 1586 null, 1587 null, 1588 null, 1589 false); 1590 } 1591 } 1592 } 1593 } else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) { 1595 if (astNode instanceof CompletionOnJavadocSingleTypeReference) { 1596 1597 CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode; 1598 this.completionToken = typeRef.token; 1599 this.javadocTagPosition = typeRef.tagSourceStart; 1600 setSourceRange(typeRef.sourceStart, typeRef.sourceEnd); 1601 findTypesAndPackages(this.completionToken, scope, new ObjectVector()); 1602 1603 } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) { 1604 1605 this.insideQualifiedReference = true; 1606 1607 CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode; 1608 this.completionToken = typeRef.completionIdentifier; 1609 long completionPosition = typeRef.sourcePositions[typeRef.tokens.length]; 1610 this.javadocTagPosition = typeRef.tagSourceStart; 1611 1612 if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 1614 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 1615 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) { 1616 int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32); 1617 setSourceRange(rangeStart, (int) completionPosition); 1618 findMemberTypes(this.completionToken, 1619 (ReferenceBinding) qualifiedBinding, 1620 scope, 1621 scope.enclosingSourceType(), 1622 false, 1623 false, 1624 new ObjectVector()); 1625 } 1626 } else if (qualifiedBinding instanceof PackageBinding) { 1627 1628 setSourceRange(astNode.sourceStart, (int) completionPosition); 1629 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 1631 } 1632 } else if (astNode instanceof CompletionOnJavadocFieldReference) { 1633 1634 this.insideQualifiedReference = true; 1635 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode; 1636 this.completionToken = fieldRef.token; 1637 long completionPosition = fieldRef.nameSourcePosition; 1638 this.javadocTagPosition = fieldRef.tagSourceStart; 1639 1640 if (fieldRef.receiverType != null && fieldRef.receiverType.isValidBinding()) { 1641 ReferenceBinding receiverType = (ReferenceBinding) fieldRef.receiverType; 1642 int rangeStart = (int) (completionPosition >>> 32); 1643 if (fieldRef.receiver.isThis()) { 1644 if (fieldRef.completeInText()) { 1645 rangeStart = fieldRef.separatorPosition; 1646 } 1647 } else if (fieldRef.completeInText()) { 1648 rangeStart = fieldRef.receiver.sourceStart; 1649 } 1650 setSourceRange(rangeStart, (int) completionPosition); 1651 1652 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF) 1653 || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) { 1654 findFields(this.completionToken, 1655 receiverType, 1656 scope, 1657 new ObjectVector(), 1658 new ObjectVector(), 1659 false, 1660 fieldRef, 1661 scope, 1662 false, 1663 true, 1664 null, 1665 null, 1666 null, 1667 false); 1668 } 1669 1670 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) 1671 || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 1672 findMethods(this.completionToken, 1673 null, 1674 null, 1675 receiverType, 1676 scope, 1677 new ObjectVector(), 1678 false, 1679 false, 1680 false, 1681 fieldRef, 1682 scope, 1683 false, 1684 false, 1685 true, 1686 null, 1687 null, 1688 null, 1689 false); 1690 if (fieldRef.receiverType instanceof ReferenceBinding) { 1691 ReferenceBinding refBinding = (ReferenceBinding)fieldRef.receiverType; 1692 if (this.completionToken == null 1693 || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName) 1694 || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) { 1695 findConstructors(refBinding, null, scope, fieldRef, false); 1696 } 1697 } 1698 } 1699 } 1700 } else if (astNode instanceof CompletionOnJavadocMessageSend) { 1701 1702 CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode; 1703 TypeBinding[] argTypes = null; this.completionToken = messageSend.selector; 1705 this.javadocTagPosition = messageSend.tagSourceStart; 1706 1707 int rangeStart = astNode.sourceStart; 1709 if (messageSend.receiver.isThis()) { 1710 if (messageSend.completeInText()) { 1711 rangeStart = messageSend.separatorPosition; 1712 } 1713 } else if (messageSend.completeInText()) { 1714 rangeStart = messageSend.receiver.sourceStart; 1715 } 1716 setSourceRange(rangeStart, astNode.sourceEnd, false); 1717 1718 if (qualifiedBinding == null) { 1719 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1720 findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope); 1721 } 1722 } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 1723 findMethods( 1724 this.completionToken, 1725 null, 1726 argTypes, 1727 (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd), 1728 scope, 1729 new ObjectVector(), 1730 false, 1731 false, 1732 false, 1733 messageSend, 1734 scope, 1735 false, 1736 messageSend.receiver instanceof SuperReference, 1737 true, 1738 null, 1739 null, 1740 null, 1741 false); 1742 } 1743 } else if (astNode instanceof CompletionOnJavadocAllocationExpression) { 1744 1746 CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode; 1747 this.javadocTagPosition = allocExpression.tagSourceStart; 1748 int rangeStart = astNode.sourceStart; 1749 if (allocExpression.type.isThis()) { 1750 if (allocExpression.completeInText()) { 1751 rangeStart = allocExpression.separatorPosition; 1752 } 1753 } else if (allocExpression.completeInText()) { 1754 rangeStart = allocExpression.type.sourceStart; 1755 } 1756 setSourceRange(rangeStart, astNode.sourceEnd, false); 1757 TypeBinding[] argTypes = computeTypes(allocExpression.arguments); 1758 1759 ReferenceBinding ref = (ReferenceBinding) qualifiedBinding; 1760 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) { 1761 findConstructors(ref, argTypes, scope, allocExpression, false); 1762 } 1763 } else if (astNode instanceof CompletionOnJavadocParamNameReference) { 1764 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 1765 CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode; 1766 setSourceRange(paramRef.tagSourceStart, paramRef.tagSourceEnd); 1767 findJavadocParamNames(paramRef.token, paramRef.missingParams, false); 1768 findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true); 1769 } 1770 } else if (astNode instanceof CompletionOnJavadocTypeParamReference) { 1771 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 1772 CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode; 1773 setSourceRange(paramRef.tagSourceStart, paramRef.tagSourceEnd); 1774 findJavadocParamNames(paramRef.token, paramRef.missingParams, true); 1775 } 1776 } else if (astNode instanceof CompletionOnJavadocTag) { 1777 CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode; 1778 setSourceRange(javadocTag.tagSourceStart, javadocTag.sourceEnd); 1779 findJavadocBlockTags(javadocTag); 1780 findJavadocInlineTags(javadocTag); 1781 } 1782 } 1783 return true; 1784 } 1785 1786 public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){ 1787 if(this.requestor != null){ 1788 this.requestor.beginReporting(); 1789 } 1790 boolean contextAccepted = false; 1791 IType topLevelType = type; 1792 while(topLevelType.getDeclaringType() != null) { 1793 topLevelType = topLevelType.getDeclaringType(); 1794 } 1795 1796 this.fileName = topLevelType.getParent().getElementName().toCharArray(); 1797 CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit); 1798 1799 CompilationUnitDeclaration compilationUnit = null; 1800 1801 try { 1802 TypeDeclaration typeDeclaration = null; 1805 if (type instanceof SourceType) { 1806 SourceType sourceType = (SourceType) type; 1807 ISourceType info = (ISourceType) sourceType.getElementInfo(); 1808 compilationUnit = SourceTypeConverter.buildCompilationUnit( 1809 new ISourceType[] {info}, SourceTypeConverter.FIELD_AND_METHOD | SourceTypeConverter.MEMBER_TYPE, this.problemReporter, 1814 compilationResult); 1815 if (compilationUnit.types != null) 1816 typeDeclaration = compilationUnit.types[0]; 1817 } else { 1818 compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0); 1819 typeDeclaration = BinaryTypeConverter.buildTypeDeclaration(type, compilationUnit, compilationResult); 1820 } 1821 1822 if(typeDeclaration != null) { 1823 Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic); 1825 1826 FieldDeclaration[] oldFields = typeDeclaration.fields; 1828 FieldDeclaration[] newFields = null; 1829 if (oldFields != null) { 1830 newFields = new FieldDeclaration[oldFields.length + 1]; 1831 System.arraycopy(oldFields, 0, newFields, 0, oldFields.length); 1832 newFields[oldFields.length] = fakeInitializer; 1833 } else { 1834 newFields = new FieldDeclaration[] {fakeInitializer}; 1835 } 1836 typeDeclaration.fields = newFields; 1837 1838 if(DEBUG) { 1839 System.out.println("SNIPPET COMPLETION AST :"); System.out.println(compilationUnit.toString()); 1841 } 1842 1843 if (compilationUnit.types != null) { 1844 try { 1845 this.lookupEnvironment.buildTypeBindings(compilationUnit, null ); 1846 1847 if ((this.unitScope = compilationUnit.scope) != null) { 1848 this.lookupEnvironment.completeTypeBindings(compilationUnit, true); 1849 compilationUnit.scope.faultInTypes(); 1850 compilationUnit.resolve(); 1851 } 1852 } catch (CompletionNodeFound e) { 1853 if (e.astNode != null) { 1855 contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation); 1857 } 1858 } 1859 } 1860 if(this.noProposal && this.problem != null) { 1861 if(!contextAccepted) { 1862 contextAccepted = true; 1863 this.requestor.acceptContext(new CompletionContext()); 1864 } 1865 this.requestor.completionFailure(this.problem); 1866 if(DEBUG) { 1867 this.printDebug(this.problem); 1868 } 1869 } 1870 } 1871 } catch (IndexOutOfBoundsException e) { if(DEBUG) { 1873 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 1875 } 1876 } catch (InvalidCursorLocation e) { if(DEBUG) { 1878 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 1880 } 1881 } catch (AbortCompilation e) { if(DEBUG) { 1883 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 1885 } 1886 } catch (CompletionNodeFound e){ if(DEBUG) { 1888 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 1890 } 1891 } catch(JavaModelException e) { 1892 } 1894 if(!contextAccepted) { 1895 contextAccepted = true; 1896 this.requestor.acceptContext(new CompletionContext()); 1897 } 1898 if(this.requestor != null){ 1899 this.requestor.endReporting(); 1900 } 1901 } 1902 1903 private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){ 1904 StringBuffer prefix = new StringBuffer (); 1905 prefix.append("public class FakeType {\n "); if(isStatic) { 1907 prefix.append("static "); } 1909 prefix.append("{\n"); for (int i = 0; i < localVariableTypeNames.length; i++) { 1911 ASTNode.printModifiers(localVariableModifiers[i], prefix); 1912 prefix.append(' '); 1913 prefix.append(localVariableTypeNames[i]); 1914 prefix.append(' '); 1915 prefix.append(localVariableNames[i]); 1916 prefix.append(';'); 1917 } 1918 1919 char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray()); this.offset = prefix.length(); 1921 1922 String encoding = this.compilerOptions.defaultEncoding; 1923 BasicCompilationUnit fakeUnit = new BasicCompilationUnit( 1924 fakeSource, 1925 null, 1926 "FakeType.java", encoding); 1928 1929 this.actualCompletionPosition = prefix.length() + position - 1; 1930 1931 CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); 1932 CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition); 1933 1934 parseBlockStatements(fakeAST, this.actualCompletionPosition); 1935 1936 return (Initializer)fakeAST.types[0].fields[0]; 1937 } 1938 1939 1953 public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos) { 1954 1955 if(DEBUG) { 1956 System.out.print("COMPLETION IN "); System.out.print(sourceUnit.getFileName()); 1958 System.out.print(" AT POSITION "); System.out.println(completionPosition); 1960 System.out.println("COMPLETION - Source :"); System.out.println(sourceUnit.getContents()); 1962 } 1963 this.requestor.beginReporting(); 1964 boolean contextAccepted = false; 1965 try { 1966 this.fileName = sourceUnit.getFileName(); 1967 this.actualCompletionPosition = completionPosition - 1; 1968 this.offset = pos; 1969 CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); 1971 CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition); 1972 1973 if (parsedUnit != null) { 1975 if(DEBUG) { 1976 System.out.println("COMPLETION - Diet AST :"); System.out.println(parsedUnit.toString()); 1978 } 1979 1980 if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) { 1982 contextAccepted = true; 1983 this.buildContext(parsedUnit.currentPackage, null, null, null); 1984 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 1985 findPackages((CompletionOnPackageReference) parsedUnit.currentPackage); 1986 } 1987 if(this.noProposal && this.problem != null) { 1988 this.requestor.completionFailure(this.problem); 1989 if(DEBUG) { 1990 this.printDebug(this.problem); 1991 } 1992 } 1993 return; 1994 } 1995 1996 ImportReference[] imports = parsedUnit.imports; 1997 if (imports != null) { 1998 for (int i = 0, length = imports.length; i < length; i++) { 1999 ImportReference importReference = imports[i]; 2000 if (importReference instanceof CompletionOnImportReference) { 2001 this.lookupEnvironment.buildTypeBindings(parsedUnit, null ); 2002 if ((this.unitScope = parsedUnit.scope) != null) { 2003 contextAccepted = true; 2004 this.buildContext(importReference, null, null, null); 2005 2006 setSourceRange( 2007 importReference.sourceStart, 2008 importReference.declarationSourceEnd); 2009 2010 char[][] oldTokens = importReference.tokens; 2011 int tokenCount = oldTokens.length; 2012 if (tokenCount == 1) { 2013 findImports((CompletionOnImportReference)importReference, true); 2014 } else if(tokenCount > 1){ 2015 this.insideQualifiedReference = true; 2016 2017 char[] lastToken = oldTokens[tokenCount - 1]; 2018 char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1); 2019 2020 Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens); 2021 if(binding != null) { 2022 if(binding instanceof PackageBinding) { 2023 findImports((CompletionOnImportReference)importReference, false); 2024 } else { 2025 ReferenceBinding ref = (ReferenceBinding) binding; 2026 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 2027 this.findImportsOfMemberTypes(lastToken, ref, importReference.isStatic()); 2028 } 2029 if(importReference.isStatic()) { 2030 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 2031 long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1]; 2032 setSourceRange((int) (positions >>> 32), (int) positions); 2033 this.findImportsOfStaticFields(lastToken, ref); 2034 setSourceRange(importReference.sourceStart, importReference.declarationSourceEnd); 2035 } 2036 if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) { 2037 this.findImportsOfStaticMethods(lastToken, ref); 2038 } 2039 } 2040 } 2041 } 2042 } 2043 2044 if(this.noProposal && this.problem != null) { 2045 this.requestor.completionFailure(this.problem); 2046 if(DEBUG) { 2047 this.printDebug(this.problem); 2048 } 2049 } 2050 } 2051 return; 2052 } else if(importReference instanceof CompletionOnKeyword) { 2053 contextAccepted = true; 2054 this.buildContext(importReference, null, null, null); 2055 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2056 setSourceRange(importReference.sourceStart, importReference.sourceEnd); 2057 CompletionOnKeyword keyword = (CompletionOnKeyword)importReference; 2058 findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false); 2059 } 2060 if(this.noProposal && this.problem != null) { 2061 this.requestor.completionFailure(this.problem); 2062 if(DEBUG) { 2063 this.printDebug(this.problem); 2064 } 2065 } 2066 return; 2067 } 2068 } 2069 } 2070 2071 if (parsedUnit.types != null) { 2072 try { 2073 this.lookupEnvironment.buildTypeBindings(parsedUnit, null ); 2074 2075 if ((this.unitScope = parsedUnit.scope) != null) { 2076 this.source = sourceUnit.getContents(); 2077 this.lookupEnvironment.completeTypeBindings(parsedUnit, true); 2078 parsedUnit.scope.faultInTypes(); 2079 parseBlockStatements(parsedUnit, this.actualCompletionPosition); 2080 if(DEBUG) { 2081 System.out.println("COMPLETION - AST :"); System.out.println(parsedUnit.toString()); 2083 } 2084 parsedUnit.resolve(); 2085 } 2086 } catch (CompletionNodeFound e) { 2087 if (e.astNode != null) { 2089 if(DEBUG) { 2090 System.out.print("COMPLETION - Completion node : "); System.out.println(e.astNode.toString()); 2092 if(this.parser.assistNodeParent != null) { 2093 System.out.print("COMPLETION - Parent Node : "); System.out.println(this.parser.assistNodeParent); 2095 } 2096 } 2097 contextAccepted = complete(e.astNode, this.parser.assistNodeParent, e.qualifiedBinding, e.scope, e.insideTypeAnnotation); 2099 } 2100 } 2101 } 2102 } 2103 2104 if(this.noProposal && this.problem != null) { 2105 if(!contextAccepted) { 2106 contextAccepted = true; 2107 CompletionContext context = new CompletionContext(); 2108 context.setOffset(completionPosition - this.offset); 2109 context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN); 2110 this.requestor.acceptContext(context); 2111 } 2112 this.requestor.completionFailure(this.problem); 2113 if(DEBUG) { 2114 this.printDebug(this.problem); 2115 } 2116 } 2117 2128 } catch (IndexOutOfBoundsException e) { if(DEBUG) { 2130 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 2132 } 2133 } catch (InvalidCursorLocation e) { if(DEBUG) { 2135 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 2137 } 2138 } catch (AbortCompilation e) { if(DEBUG) { 2140 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 2142 } 2143 } catch (CompletionNodeFound e){ if(DEBUG) { 2145 System.out.println("Exception caught by CompletionEngine:"); e.printStackTrace(System.out); 2147 } 2148 } finally { 2149 reset(); 2150 if(!contextAccepted) { 2151 contextAccepted = true; 2152 CompletionContext context = new CompletionContext(); 2153 context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN); 2154 context.setOffset(completionPosition - this.offset); 2155 this.requestor.acceptContext(context); 2156 } 2157 this.requestor.endReporting(); 2158 } 2159 } 2160 2161 private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) { 2162 ASTNode annotatedElement = fakeNode.potentialAnnotatedNode; 2163 2164 if (annotatedElement instanceof TypeDeclaration) { 2165 TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement; 2166 if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) { 2167 return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType; 2168 } 2169 return TagBits.AnnotationForType; 2170 } else if (annotatedElement instanceof FieldDeclaration) { 2171 if (fakeNode.isParameter) { 2172 return TagBits.AnnotationForParameter; 2173 } 2174 return TagBits.AnnotationForField; 2175 } else if (annotatedElement instanceof MethodDeclaration) { 2176 return TagBits.AnnotationForMethod; 2177 } else if (annotatedElement instanceof Argument) { 2178 return TagBits.AnnotationForParameter; 2179 } else if (annotatedElement instanceof ConstructorDeclaration) { 2180 return TagBits.AnnotationForConstructor; 2181 } else if (annotatedElement instanceof LocalDeclaration) { 2182 return TagBits.AnnotationForLocalVariable; 2183 } else if (annotatedElement instanceof ImportReference) { 2184 return TagBits.AnnotationForPackage; 2185 } 2186 return 0; 2187 } 2188 2189 private TypeBinding[] computeTypes(Expression[] arguments) { 2190 if (arguments == null) return null; 2191 int argsLength = arguments.length; 2192 TypeBinding[] argTypes = new TypeBinding[argsLength]; 2193 for (int a = argsLength; --a >= 0;) { 2194 argTypes[a] = arguments[a].resolvedType; 2195 } 2196 return argTypes; 2197 } 2198 2199 private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) { 2200 if (arguments == null) return null; 2201 int argsLength = arguments.length; 2202 TypeBinding[] argTypes = new TypeBinding[argsLength]; 2203 for (int a = argsLength; --a >= 0;) { 2204 TypeBinding typeBinding = arguments[a].resolvedType; 2205 if(typeBinding == null || !typeBinding.isValidBinding()) return null; 2206 argTypes[a] = typeBinding; 2207 } 2208 return argTypes; 2209 } 2210 2211 private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) { 2212 MethodBinding[] methods = annotation.availableMethods(); 2213 nextAttribute: for (int i = 0; i < methods.length; i++) { 2214 MethodBinding method = methods[i]; 2215 2216 if(!CharOperation.prefixEquals(token, method.selector, false) 2217 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute; 2218 2219 int length = attributesFound == null ? 0 : attributesFound.length; 2220 for (int j = 0; j < length; j++) { 2221 if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute; 2222 } 2223 2224 int relevance = computeBaseRelevance(); 2225 relevance += computeRelevanceForResolution(); 2226 relevance += computeRelevanceForInterestingProposal(method); 2227 relevance += computeRelevanceForCaseMatching(token, method.selector); 2228 relevance += computeRelevanceForQualification(false); 2229 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2230 2231 this.noProposal = false; 2232 if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) { 2233 CompletionProposal proposal = this.createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition); 2234 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 2235 proposal.setSignature(getSignature(method.returnType)); 2236 proposal.setName(method.selector); 2237 proposal.setCompletion(method.selector); 2238 proposal.setFlags(method.modifiers); 2239 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 2240 proposal.setRelevance(relevance); 2241 this.requestor.accept(proposal); 2242 if(DEBUG) { 2243 this.printDebug(proposal); 2244 } 2245 } 2246 } 2247 } 2248 private void findAnonymousType( 2249 ReferenceBinding currentType, 2250 TypeBinding[] argTypes, 2251 Scope scope, 2252 InvocationSite invocationSite) { 2253 2254 if (currentType.isInterface()) { 2255 char[] completion = CharOperation.NO_CHAR; 2256 int relevance = computeBaseRelevance(); 2257 relevance += computeRelevanceForResolution(); 2258 relevance += computeRelevanceForInterestingProposal(); 2259 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2260 2261 this.noProposal = false; 2262 if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) { 2263 CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition); 2264 proposal.setDeclarationSignature(getSignature(currentType)); 2265 proposal.setDeclarationKey(currentType.computeUniqueKey()); 2266 proposal.setSignature( 2267 createMethodSignature( 2268 CharOperation.NO_CHAR_CHAR, 2269 CharOperation.NO_CHAR_CHAR, 2270 CharOperation.NO_CHAR, 2271 CharOperation.NO_CHAR)); 2272 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 2275 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 2276 proposal.setCompletion(completion); 2281 proposal.setFlags(Flags.AccPublic); 2282 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 2283 proposal.setRelevance(relevance); 2284 this.requestor.accept(proposal); 2285 if(DEBUG) { 2286 this.printDebug(proposal); 2287 } 2288 } 2289 } else { 2290 findConstructors( 2291 currentType, 2292 argTypes, 2293 scope, 2294 invocationSite, 2295 true); 2296 } 2297 } 2298 2299 private void findClassField(char[] token, TypeBinding receiverType, Scope scope) { 2300 2301 if (token == null) return; 2302 2303 if (token.length <= classField.length 2304 && CharOperation.prefixEquals(token, classField, false 2305 )) { 2306 int relevance = computeBaseRelevance(); 2307 relevance += computeRelevanceForResolution(); 2308 relevance += computeRelevanceForInterestingProposal(); 2309 relevance += computeRelevanceForCaseMatching(token, classField); 2310 relevance += computeRelevanceForExpectingType(scope.getJavaLangClass()); 2311 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); relevance += R_NON_INHERITED; 2313 2314 this.noProposal = false; 2315 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 2316 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 2317 char[] signature = 2319 createNonGenericTypeSignature( 2320 CharOperation.concatWith(JAVA_LANG, '.'), 2321 CLASS); 2322 if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) { 2323 char[] typeArgument = getTypeSignature(receiverType); 2325 int oldLength = signature.length; 2326 int argumentLength = typeArgument.length; 2327 int newLength = oldLength + argumentLength + 2; 2328 System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1); 2329 signature[oldLength - 1] = '<'; 2330 System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength); 2331 signature[newLength - 2] = '>'; 2332 signature[newLength - 1] = ';'; 2333 } 2334 proposal.setSignature(signature); 2335 proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.')); 2338 proposal.setTypeName(CLASS); 2339 proposal.setName(classField); 2340 proposal.setCompletion(classField); 2341 proposal.setFlags(Flags.AccStatic | Flags.AccPublic); 2342 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 2343 proposal.setRelevance(relevance); 2344 this.requestor.accept(proposal); 2345 if(DEBUG) { 2346 this.printDebug(proposal); 2347 } 2348 } 2349 } 2350 } 2351 private void findEnumConstant(char[] enumConstantName, SwitchStatement switchStatement) { 2352 TypeBinding expressionType = switchStatement.expression.resolvedType; 2353 if(expressionType != null && expressionType.isEnum()) { 2354 ReferenceBinding enumType = (ReferenceBinding) expressionType; 2355 2356 CaseStatement[] cases = switchStatement.cases; 2357 2358 char[][] alreadyUsedConstants = new char[switchStatement.caseCount][]; 2359 int alreadyUsedConstantCount = 0; 2360 for (int i = 0; i < switchStatement.caseCount; i++) { 2361 Expression caseExpression = cases[i].constantExpression; 2362 if((caseExpression instanceof SingleNameReference) 2363 && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) { 2364 alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token; 2365 } 2366 } 2367 2368 FieldBinding[] fields = enumType.fields(); 2369 2370 int enumConstantLength = enumConstantName.length; 2371 next : for (int f = fields.length; --f >= 0;) { 2372 FieldBinding field = fields[f]; 2373 2374 if (field.isSynthetic()) continue next; 2375 2376 if ((field.modifiers & Flags.AccEnum) == 0) continue next; 2377 2378 if (enumConstantLength > field.name.length) continue next; 2379 2380 if (!CharOperation.prefixEquals(enumConstantName, field.name, false ) 2381 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name))) continue next; 2382 2383 char[] completion = field.name; 2384 2385 for (int i = 0; i < alreadyUsedConstantCount; i++) { 2386 if(CharOperation.equals(alreadyUsedConstants[i], completion)) continue next; 2387 } 2388 2389 int relevance = computeBaseRelevance(); 2390 relevance += computeRelevanceForInterestingProposal(field); 2391 relevance += computeRelevanceForEnum(); 2392 relevance += computeRelevanceForCaseMatching(enumConstantName, field.name); 2393 relevance += computeRelevanceForExpectingType(field.type); 2394 relevance += computeRelevanceForQualification(false); 2395 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2396 2397 this.noProposal = false; 2398 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 2399 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 2400 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 2401 proposal.setSignature(getSignature(field.type)); 2402 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 2403 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 2404 proposal.setPackageName(field.type.qualifiedPackageName()); 2405 proposal.setTypeName(field.type.qualifiedSourceName()); 2406 proposal.setName(field.name); 2407 proposal.setCompletion(completion); 2408 proposal.setFlags(field.modifiers); 2409 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 2410 proposal.setRelevance(relevance); 2411 this.requestor.accept(proposal); 2412 if(DEBUG) { 2413 this.printDebug(proposal); 2414 } 2415 } 2416 } 2417 } 2418 } 2419 2420 private void findExceptionFromTryStatement( 2421 char[] typeName, 2422 ReferenceBinding exceptionType, 2423 ReferenceBinding receiverType, 2424 SourceTypeBinding invocationType, 2425 BlockScope scope, 2426 ObjectVector typesFound, 2427 boolean searchSuperClasses) { 2428 2429 if (searchSuperClasses) { 2430 ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable(); 2431 if (exceptionType != javaLangThrowable) { 2432 ReferenceBinding superClass = exceptionType.superclass(); 2433 while(superClass != null && superClass != javaLangThrowable) { 2434 findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false); 2435 superClass = superClass.superclass(); 2436 } 2437 } 2438 } 2439 2440 if (typeName.length > exceptionType.sourceName.length) 2441 return; 2442 2443 if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false) 2444 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName))) 2445 return; 2446 2447 if (this.options.checkDeprecation && 2448 exceptionType.isViewedAsDeprecated() && 2449 !scope.isDefinedInSameUnit(exceptionType)) 2450 return; 2451 2452 if (this.options.checkVisibility) { 2453 if (invocationType != null) { 2454 if (receiverType != null) { 2455 if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return; 2456 } else { 2457 if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return; 2458 } 2459 } else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) { 2460 return; 2461 } 2462 } 2463 2464 for (int j = typesFound.size; --j >= 0;) { 2465 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 2466 2467 if (exceptionType == otherType) 2468 return; 2469 2470 if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) { 2471 2472 if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType())) 2473 return; 2474 2475 if (otherType.enclosingType().isInterface()) 2476 if (exceptionType.enclosingType() 2477 .implementsInterface(otherType.enclosingType(), true)) 2478 return; 2479 2480 if (exceptionType.enclosingType().isInterface()) 2481 if (otherType.enclosingType() 2482 .implementsInterface(exceptionType.enclosingType(), true)) 2483 return; 2484 } 2485 } 2486 2487 typesFound.add(exceptionType); 2488 2489 char[] completionName = exceptionType.sourceName(); 2490 2491 boolean isQualified = false; 2492 2493 if(!this.insideQualifiedReference) { 2494 isQualified = true; 2495 2496 char[] memberPackageName = exceptionType.qualifiedPackageName(); 2497 char[] memberTypeName = exceptionType.sourceName(); 2498 char[] memberEnclosingTypeNames = null; 2499 2500 ReferenceBinding enclosingType = exceptionType.enclosingType(); 2501 if (enclosingType != null) { 2502 memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName(); 2503 } 2504 2505 Scope currentScope = scope; 2506 done : while (currentScope != null) { 2508 switch (currentScope.kind) { 2509 2510 case Scope.METHOD_SCOPE : 2511 case Scope.BLOCK_SCOPE : 2512 BlockScope blockScope = (BlockScope) currentScope; 2513 2514 for (int j = 0, length = blockScope.subscopeCount; j < length; j++) { 2515 2516 if (blockScope.subscopes[j] instanceof ClassScope) { 2517 SourceTypeBinding localType = 2518 ((ClassScope) blockScope.subscopes[j]).referenceContext.binding; 2519 2520 if (localType == exceptionType) { 2521 isQualified = false; 2522 break done; 2523 } 2524 } 2525 } 2526 break; 2527 2528 case Scope.CLASS_SCOPE : 2529 SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding; 2530 ReferenceBinding[] memberTypes = type.memberTypes(); 2531 if (memberTypes != null) { 2532 for (int j = 0; j < memberTypes.length; j++) { 2533 if (memberTypes[j] == exceptionType) { 2534 isQualified = false; 2535 break done; 2536 } 2537 } 2538 } 2539 2540 2541 break; 2542 2543 case Scope.COMPILATION_UNIT_SCOPE : 2544 SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes; 2545 if (types != null) { 2546 for (int j = 0; j < types.length; j++) { 2547 if (types[j] == exceptionType) { 2548 isQualified = false; 2549 break done; 2550 } 2551 } 2552 } 2553 break done; 2554 } 2555 currentScope = currentScope.parent; 2556 } 2557 2558 if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) { 2559 if (memberPackageName == null || memberPackageName.length == 0) 2560 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 2561 return; } else { 2563 isQualified = false; 2564 } 2565 2566 if (isQualified) { 2567 completionName = 2568 CharOperation.concat( 2569 memberPackageName, 2570 CharOperation.concat( 2571 memberEnclosingTypeNames, 2572 memberTypeName, 2573 '.'), 2574 '.'); 2575 } 2576 } 2577 2578 int relevance = computeBaseRelevance(); 2579 relevance += computeRelevanceForResolution(); 2580 relevance += computeRelevanceForInterestingProposal(); 2581 relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName); 2582 relevance += computeRelevanceForExpectingType(exceptionType); 2583 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2584 if(!insideQualifiedReference) { 2585 relevance += computeRelevanceForQualification(isQualified); 2586 } 2587 relevance += computeRelevanceForClass(); 2588 relevance += computeRelevanceForException(); 2589 2590 this.noProposal = false; 2591 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 2592 createTypeProposal(exceptionType, exceptionType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance); 2593 } 2594 } 2595 2596 private void findExceptionFromTryStatement( 2597 char[] typeName, 2598 ReferenceBinding receiverType, 2599 SourceTypeBinding invocationType, 2600 BlockScope scope, 2601 ObjectVector typesFound) { 2602 2603 for (int i = 0; i <= this.expectedTypesPtr; i++) { 2604 ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i]; 2605 2606 findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true); 2607 } 2608 } 2609 private void findExplicitConstructors( 2610 char[] name, 2611 ReferenceBinding currentType, 2612 MethodScope scope, 2613 InvocationSite invocationSite) { 2614 2615 ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext; 2616 MethodBinding enclosingConstructor = constructorDeclaration.binding; 2617 2618 MethodBinding[] methods = currentType.availableMethods(); 2620 if(methods != null) { 2621 next : for (int f = methods.length; --f >= 0;) { 2622 MethodBinding constructor = methods[f]; 2623 if (constructor != enclosingConstructor && constructor.isConstructor()) { 2624 2625 if (constructor.isSynthetic()) continue next; 2626 2627 if (this.options.checkDeprecation && 2628 constructor.isViewedAsDeprecated() && 2629 !scope.isDefinedInSameUnit(constructor.declaringClass)) 2630 continue next; 2631 2632 if (this.options.checkVisibility 2633 && !constructor.canBeSeenBy(invocationSite, scope)) continue next; 2634 2635 TypeBinding[] parameters = constructor.parameters; 2636 int paramLength = parameters.length; 2637 2638 char[][] parameterPackageNames = new char[paramLength][]; 2639 char[][] parameterTypeNames = new char[paramLength][]; 2640 for (int i = 0; i < paramLength; i++) { 2641 TypeBinding type = parameters[i]; 2642 parameterPackageNames[i] = type.qualifiedPackageName(); 2643 parameterTypeNames[i] = type.qualifiedSourceName(); 2644 } 2645 char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames); 2646 2647 char[] completion = CharOperation.NO_CHAR; 2648 if (this.source != null 2649 && this.source.length > this.endPosition 2650 && this.source[this.endPosition] == '(') 2651 completion = name; 2652 else 2653 completion = CharOperation.concat(name, new char[] { '(', ')' }); 2654 2655 int relevance = computeBaseRelevance(); 2656 relevance += computeRelevanceForResolution(); 2657 relevance += computeRelevanceForInterestingProposal(); 2658 relevance += computeRelevanceForCaseMatching(this.completionToken, name); 2659 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2660 2661 this.noProposal = false; 2662 if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 2663 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 2664 proposal.setDeclarationSignature(getSignature(currentType)); 2665 proposal.setSignature(getSignature(constructor)); 2666 MethodBinding original = constructor.original(); 2667 if(original != constructor) { 2668 proposal.setOriginalSignature(getSignature(original)); 2669 } 2670 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 2671 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 2672 proposal.setParameterPackageNames(parameterPackageNames); 2673 proposal.setParameterTypeNames(parameterTypeNames); 2674 proposal.setName(name); 2677 proposal.setIsContructor(true); 2678 proposal.setCompletion(completion); 2679 proposal.setFlags(constructor.modifiers); 2680 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 2681 proposal.setRelevance(relevance); 2682 if(parameterNames != null) proposal.setParameterNames(parameterNames); 2683 this.requestor.accept(proposal); 2684 if(DEBUG) { 2685 this.printDebug(proposal); 2686 } 2687 } 2688 } 2689 } 2690 } 2691 } 2692 private void findConstructors( 2693 ReferenceBinding currentType, 2694 TypeBinding[] argTypes, 2695 Scope scope, 2696 InvocationSite invocationSite, 2697 boolean forAnonymousType) { 2698 2699 MethodBinding[] methods = currentType.availableMethods(); 2701 if(methods != null) { 2702 int minArgLength = argTypes == null ? 0 : argTypes.length; 2703 next : for (int f = methods.length; --f >= 0;) { 2704 MethodBinding constructor = methods[f]; 2705 if (constructor.isConstructor()) { 2706 2707 if (constructor.isSynthetic()) continue next; 2708 2709 if (this.options.checkDeprecation && 2710 constructor.isViewedAsDeprecated() && 2711 !scope.isDefinedInSameUnit(constructor.declaringClass)) 2712 continue next; 2713 2714 if (this.options.checkVisibility 2715 && !constructor.canBeSeenBy(invocationSite, scope)) { 2716 if(!forAnonymousType || !constructor.isProtected()) 2717 continue next; 2718 } 2719 2720 TypeBinding[] parameters = constructor.parameters; 2721 int paramLength = parameters.length; 2722 if (minArgLength > paramLength) 2723 continue next; 2724 for (int a = minArgLength; --a >= 0;) 2725 if (argTypes[a] != null) { if (!argTypes[a].isCompatibleWith(constructor.parameters[a])) 2727 continue next; 2728 } 2729 2730 char[][] parameterPackageNames = new char[paramLength][]; 2731 char[][] parameterTypeNames = new char[paramLength][]; 2732 for (int i = 0; i < paramLength; i++) { 2733 TypeBinding type = parameters[i]; 2734 parameterPackageNames[i] = type.qualifiedPackageName(); 2735 parameterTypeNames[i] = type.qualifiedSourceName(); 2736 } 2737 char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames); 2738 2739 char[] completion = CharOperation.NO_CHAR; 2740 if(forAnonymousType){ 2741 int relevance = computeBaseRelevance(); 2742 relevance += computeRelevanceForResolution(); 2743 relevance += computeRelevanceForInterestingProposal(); 2744 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2745 2746 this.noProposal = false; 2747 if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) { 2748 CompletionProposal proposal = this.createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition); 2749 proposal.setDeclarationSignature(getSignature(currentType)); 2750 proposal.setDeclarationKey(currentType.computeUniqueKey()); 2751 proposal.setSignature(getSignature(constructor)); 2752 MethodBinding original = constructor.original(); 2753 if(original != constructor) { 2754 proposal.setOriginalSignature(getSignature(original)); 2755 } 2756 proposal.setKey(constructor.computeUniqueKey()); 2757 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 2758 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 2759 proposal.setParameterPackageNames(parameterPackageNames); 2760 proposal.setParameterTypeNames(parameterTypeNames); 2761 proposal.setCompletion(completion); 2764 proposal.setFlags(constructor.modifiers); 2765 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 2766 proposal.setRelevance(relevance); 2767 if(parameterNames != null) proposal.setParameterNames(parameterNames); 2768 this.requestor.accept(proposal); 2769 if(DEBUG) { 2770 this.printDebug(proposal); 2771 } 2772 } 2773 } else { 2774 int relevance = computeBaseRelevance(); 2775 relevance += computeRelevanceForResolution(); 2776 relevance += computeRelevanceForInterestingProposal(); 2777 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 2778 2779 if (this.assistNodeInJavadoc > 0) { 2781 Expression receiver = null; 2782 char[] selector = null; 2783 if (invocationSite instanceof CompletionOnJavadocAllocationExpression) { 2784 CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite; 2785 receiver = alloc.type; 2786 } else if (invocationSite instanceof CompletionOnJavadocFieldReference) { 2787 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 2788 receiver = fieldRef.receiver; 2789 } 2790 if (receiver != null) { 2791 StringBuffer javadocCompletion = new StringBuffer (); 2792 if (receiver.isThis()) { 2793 selector = (((JavadocImplicitTypeReference)receiver).token); 2794 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 2795 javadocCompletion.append('#'); 2796 } 2797 } else if (receiver instanceof JavadocSingleTypeReference) { 2798 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver; 2799 selector = typeRef.token; 2800 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 2801 javadocCompletion.append(typeRef.token); 2802 javadocCompletion.append('#'); 2803 } 2804 } else if (receiver instanceof JavadocQualifiedTypeReference) { 2805 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver; 2806 selector = typeRef.tokens[typeRef.tokens.length-1]; 2807 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 2808 javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.')); 2809 javadocCompletion.append('#'); 2810 } 2811 } 2812 javadocCompletion.append(selector); 2814 javadocCompletion.append('('); 2815 if (constructor.parameters != null) { 2816 boolean isVarargs = constructor.isVarargs(); 2817 for (int p=0, ln=constructor.parameters.length; p<ln; p++) { 2818 if (p>0) javadocCompletion.append(", "); TypeBinding argTypeBinding = constructor.parameters[p]; 2820 if (isVarargs && p == ln - 1) { 2821 createVargsType(argTypeBinding.erasure(), javadocCompletion); 2822 } else { 2823 createType(argTypeBinding.erasure(), javadocCompletion); 2824 } 2825 } 2826 } 2827 javadocCompletion.append(')'); 2828 completion = javadocCompletion.toString().toCharArray(); 2829 } 2830 } 2831 2832 this.noProposal = false; 2834 if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 2835 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 2836 proposal.setDeclarationSignature(getSignature(currentType)); 2837 proposal.setSignature(getSignature(constructor)); 2838 MethodBinding original = constructor.original(); 2839 if(original != constructor) { 2840 proposal.setOriginalSignature(getSignature(original)); 2841 } 2842 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 2843 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 2844 proposal.setParameterPackageNames(parameterPackageNames); 2845 proposal.setParameterTypeNames(parameterTypeNames); 2846 proposal.setName(currentType.sourceName()); 2849 proposal.setIsContructor(true); 2850 proposal.setCompletion(completion); 2851 proposal.setFlags(constructor.modifiers); 2852 int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition; 2853 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 2854 proposal.setRelevance(relevance); 2855 if(parameterNames != null) proposal.setParameterNames(parameterNames); 2856 this.requestor.accept(proposal); 2857 if(DEBUG) { 2858 this.printDebug(proposal); 2859 } 2860 } 2861 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 2862 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 2863 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition); 2864 proposal.setDeclarationSignature(getSignature(currentType)); 2865 proposal.setSignature(getSignature(constructor)); 2866 MethodBinding original = constructor.original(); 2867 if(original != constructor) { 2868 proposal.setOriginalSignature(getSignature(original)); 2869 } 2870 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 2871 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 2872 proposal.setParameterPackageNames(parameterPackageNames); 2873 proposal.setParameterTypeNames(parameterTypeNames); 2874 proposal.setName(currentType.sourceName()); 2877 proposal.setIsContructor(true); 2878 proposal.setCompletion(javadocCompletion); 2879 proposal.setFlags(constructor.modifiers); 2880 int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition; 2881 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0) start = this.javadocTagPosition; 2882 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 2883 proposal.setRelevance(relevance+R_INLINE_TAG); 2884 if(parameterNames != null) proposal.setParameterNames(parameterNames); 2885 this.requestor.accept(proposal); 2886 if(DEBUG) { 2887 this.printDebug(proposal); 2888 } 2889 } 2890 } 2891 } 2892 } 2893 } 2894 } 2895 2896 private char[][] findEnclosingTypeNames(Scope scope){ 2897 char[][] excludedNames = new char[10][]; 2898 int excludedNameCount = 0; 2899 2900 Scope currentScope = scope; 2901 while(currentScope != null) { 2902 switch (currentScope.kind) { 2903 case Scope.CLASS_SCOPE : 2904 ClassScope classScope = (ClassScope) currentScope; 2905 2906 TypeDeclaration typeDeclaration = classScope.referenceContext; 2907 2908 if(excludedNameCount == excludedNames.length) { 2909 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 2910 } 2911 excludedNames[excludedNameCount++] = typeDeclaration.name; 2912 2913 TypeParameter[] classTypeParameters = typeDeclaration.typeParameters; 2914 if(classTypeParameters != null) { 2915 for (int i = 0; i < classTypeParameters.length; i++) { 2916 TypeParameter typeParameter = classTypeParameters[i]; 2917 if(excludedNameCount == excludedNames.length) { 2918 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 2919 } 2920 excludedNames[excludedNameCount++] = typeParameter.name; 2921 } 2922 } 2923 break; 2924 case Scope.METHOD_SCOPE : 2925 MethodScope methodScope = (MethodScope) currentScope; 2926 if(methodScope.referenceContext instanceof AbstractMethodDeclaration) { 2927 TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters(); 2928 if(methodTypeParameters != null) { 2929 for (int i = 0; i < methodTypeParameters.length; i++) { 2930 TypeParameter typeParameter = methodTypeParameters[i]; 2931 if(excludedNameCount == excludedNames.length) { 2932 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 2933 } 2934 excludedNames[excludedNameCount++] = typeParameter.name; 2935 } 2936 } 2937 } 2938 break; 2939 } 2940 2941 currentScope = currentScope.parent; 2942 } 2943 2944 if(excludedNameCount == 0) { 2945 return CharOperation.NO_CHAR_CHAR; 2946 } 2947 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount); 2948 return excludedNames; 2949 } 2950 2951 private void findFields( 2953 char[] fieldName, 2954 FieldBinding[] fields, 2955 Scope scope, 2956 ObjectVector fieldsFound, 2957 ObjectVector localsFound, 2958 boolean onlyStaticFields, 2959 ReferenceBinding receiverType, 2960 InvocationSite invocationSite, 2961 Scope invocationScope, 2962 boolean implicitCall, 2963 boolean canBePrefixed, 2964 Binding[] missingElements, 2965 int[] missingElementsStarts, 2966 int[] missingElementsEnds, 2967 boolean missingElementsHaveProblems) { 2968 2969 ObjectVector newFieldsFound = new ObjectVector(); 2970 2973 int fieldLength = fieldName.length; 2974 next : for (int f = fields.length; --f >= 0;) { 2975 FieldBinding field = fields[f]; 2976 2977 if (field.isSynthetic()) continue next; 2978 2979 if (onlyStaticFields && !field.isStatic()) continue next; 2980 2981 if (fieldLength > field.name.length) continue next; 2982 2983 if (!CharOperation.prefixEquals(fieldName, field.name, false ) 2984 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next; 2985 2986 if (this.options.checkDeprecation && 2987 field.isViewedAsDeprecated() && 2988 !scope.isDefinedInSameUnit(field.declaringClass)) 2989 continue next; 2990 2991 if (this.options.checkVisibility 2992 && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 2993 2994 boolean prefixRequired = false; 2995 2996 for (int i = fieldsFound.size; --i >= 0;) { 2997 Object [] other = (Object [])fieldsFound.elementAt(i); 2998 FieldBinding otherField = (FieldBinding) other[0]; 2999 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 3000 if (field == otherField && receiverType == otherReceiverType) 3001 continue next; 3002 if (CharOperation.equals(field.name, otherField.name, true)) { 3003 if (field.declaringClass.isSuperclassOf(otherField.declaringClass)) 3004 continue next; 3005 if (otherField.declaringClass.isInterface()) { 3006 if (field.declaringClass == scope.getJavaLangObject()) 3007 continue next; 3008 if (field.declaringClass.implementsInterface(otherField.declaringClass, true)) 3009 continue next; 3010 } 3011 if (field.declaringClass.isInterface()) 3012 if (otherField.declaringClass.implementsInterface(field.declaringClass, true)) 3013 continue next; 3014 if(canBePrefixed) { 3015 prefixRequired = true; 3016 } else { 3017 continue next; 3018 } 3019 } 3020 } 3021 3022 for (int l = localsFound.size; --l >= 0;) { 3023 LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l); 3024 3025 if (CharOperation.equals(field.name, local.name, true)) { 3026 SourceTypeBinding declarationType = scope.enclosingSourceType(); 3027 if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) { 3028 continue next; 3029 } 3030 if(canBePrefixed) { 3031 prefixRequired = true; 3032 } else { 3033 continue next; 3034 } 3035 break; 3036 } 3037 } 3038 3039 newFieldsFound.add(new Object []{field, receiverType}); 3040 3041 char[] completion = field.name; 3042 3043 if(prefixRequired || this.options.forceImplicitQualification){ 3044 char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic()); 3045 completion = CharOperation.concat(prefix,completion,'.'); 3046 } 3047 3048 if (this.assistNodeInJavadoc > 0) { 3050 if (invocationSite instanceof CompletionOnJavadocFieldReference) { 3051 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 3052 if (fieldRef.receiver.isThis()) { 3053 if (fieldRef.completeInText()) { 3054 completion = CharOperation.concat(new char[] { '#' }, field.name); 3055 } 3056 } else if (fieldRef.completeInText()) { 3057 if (fieldRef.receiver instanceof JavadocSingleTypeReference) { 3058 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver; 3059 completion = CharOperation.concat(typeRef.token, field.name, '#'); 3060 } else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) { 3061 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver; 3062 completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#'); 3063 } 3064 } 3065 } 3066 } 3067 3068 int relevance = computeBaseRelevance(); 3069 relevance += computeRelevanceForResolution(); 3070 relevance += computeRelevanceForInterestingProposal(field); 3071 if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name); 3072 relevance += computeRelevanceForExpectingType(field.type); 3073 relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic()); 3074 relevance += computeRelevanceForQualification(prefixRequired); 3075 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 3076 if (onlyStaticFields && this.insideQualifiedReference) { 3077 relevance += computeRelevanceForInheritance(receiverType, field.declaringClass); 3078 } 3079 if (missingElements != null) { 3080 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 3081 } 3082 3083 this.noProposal = false; 3084 if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 3086 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 3087 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 3088 proposal.setSignature(getSignature(field.type)); 3089 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3090 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3091 proposal.setPackageName(field.type.qualifiedPackageName()); 3092 proposal.setTypeName(field.type.qualifiedSourceName()); 3093 proposal.setName(field.name); 3094 if (missingElements != null) { 3095 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 3096 for (int i = 0; i < missingElements.length; i++) { 3097 subProposals[i] = 3098 createRequiredTypeProposal( 3099 missingElements[i], 3100 missingElementsStarts[i], 3101 missingElementsEnds[i], 3102 relevance); 3103 } 3104 proposal.setRequiredProposals(subProposals); 3105 } 3106 proposal.setCompletion(completion); 3107 proposal.setFlags(field.modifiers); 3108 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3109 proposal.setRelevance(relevance); 3110 this.requestor.accept(proposal); 3111 if(DEBUG) { 3112 this.printDebug(proposal); 3113 } 3114 } 3115 3116 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) { 3118 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 3119 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition); 3120 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 3121 proposal.setSignature(getSignature(field.type)); 3122 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3123 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3124 proposal.setPackageName(field.type.qualifiedPackageName()); 3125 proposal.setTypeName(field.type.qualifiedSourceName()); 3126 proposal.setName(field.name); 3127 proposal.setCompletion(javadocCompletion); 3128 proposal.setFlags(field.modifiers); 3129 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 3130 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 3131 proposal.setRelevance(relevance+R_INLINE_TAG); 3132 this.requestor.accept(proposal); 3133 if(DEBUG) { 3134 this.printDebug(proposal); 3135 } 3136 if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) { 3138 javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE); 3139 CompletionProposal valueProposal = this.createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition); 3140 valueProposal.setDeclarationSignature(getSignature(field.declaringClass)); 3141 valueProposal.setSignature(getSignature(field.type)); 3142 valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3143 valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3144 valueProposal.setPackageName(field.type.qualifiedPackageName()); 3145 valueProposal.setTypeName(field.type.qualifiedSourceName()); 3146 valueProposal.setName(field.name); 3147 valueProposal.setCompletion(javadocCompletion); 3148 valueProposal.setFlags(field.modifiers); 3149 valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 3150 valueProposal.setRelevance(relevance+R_VALUE_TAG); 3151 this.requestor.accept(valueProposal); 3152 if(DEBUG) { 3153 this.printDebug(valueProposal); 3154 } 3155 } 3156 } 3157 } 3158 3159 fieldsFound.addAll(newFieldsFound); 3160 } 3161 3162 private void findFields( 3163 char[] fieldName, 3164 ReferenceBinding receiverType, 3165 Scope scope, 3166 ObjectVector fieldsFound, 3167 ObjectVector localsFound, 3168 boolean onlyStaticFields, 3169 InvocationSite invocationSite, 3170 Scope invocationScope, 3171 boolean implicitCall, 3172 boolean canBePrefixed, 3173 Binding[] missingElements, 3174 int[] missingElementsStarts, 3175 int[] missingElementsEnds, 3176 boolean missingElementsHaveProblems) { 3177 3178 boolean notInJavadoc = this.assistNodeInJavadoc == 0; 3179 if (fieldName == null && notInJavadoc) 3180 return; 3181 3182 ReferenceBinding currentType = receiverType; 3183 ReferenceBinding[] interfacesToVisit = null; 3184 int nextPosition = 0; 3185 do { 3186 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 3187 if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) { 3188 if (interfacesToVisit == null) { 3189 interfacesToVisit = itsInterfaces; 3190 nextPosition = interfacesToVisit.length; 3191 } else { 3192 int itsLength = itsInterfaces.length; 3193 if (nextPosition + itsLength >= interfacesToVisit.length) 3194 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 3195 nextInterface : for (int a = 0; a < itsLength; a++) { 3196 ReferenceBinding next = itsInterfaces[a]; 3197 for (int b = 0; b < nextPosition; b++) 3198 if (next == interfacesToVisit[b]) continue nextInterface; 3199 interfacesToVisit[nextPosition++] = next; 3200 } 3201 } 3202 } 3203 3204 FieldBinding[] fields = currentType.availableFields(); 3205 if(fields != null && fields.length > 0) { 3206 findFields( 3207 fieldName, 3208 fields, 3209 scope, 3210 fieldsFound, 3211 localsFound, 3212 onlyStaticFields, 3213 receiverType, 3214 invocationSite, 3215 invocationScope, 3216 implicitCall, 3217 canBePrefixed, 3218 missingElements, 3219 missingElementsStarts, 3220 missingElementsEnds, 3221 missingElementsHaveProblems); 3222 } 3223 currentType = currentType.superclass(); 3224 } while (notInJavadoc && currentType != null); 3225 3226 if (notInJavadoc && interfacesToVisit != null) { 3227 for (int i = 0; i < nextPosition; i++) { 3228 ReferenceBinding anInterface = interfacesToVisit[i]; 3229 FieldBinding[] fields = anInterface.availableFields(); 3230 if(fields != null) { 3231 findFields( 3232 fieldName, 3233 fields, 3234 scope, 3235 fieldsFound, 3236 localsFound, 3237 onlyStaticFields, 3238 receiverType, 3239 invocationSite, 3240 invocationScope, 3241 implicitCall, 3242 canBePrefixed, 3243 missingElements, 3244 missingElementsStarts, 3245 missingElementsEnds, 3246 missingElementsHaveProblems); 3247 } 3248 3249 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 3250 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 3251 int itsLength = itsInterfaces.length; 3252 if (nextPosition + itsLength >= interfacesToVisit.length) 3253 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 3254 nextInterface : for (int a = 0; a < itsLength; a++) { 3255 ReferenceBinding next = itsInterfaces[a]; 3256 for (int b = 0; b < nextPosition; b++) 3257 if (next == interfacesToVisit[b]) continue nextInterface; 3258 interfacesToVisit[nextPosition++] = next; 3259 } 3260 } 3261 } 3262 } 3263 } 3264 3265 protected void findFieldsAndMethods( 3266 char[] token, 3267 TypeBinding receiverType, 3268 Scope scope, 3269 InvocationSite invocationSite, 3270 Scope invocationScope, 3271 boolean implicitCall, 3272 boolean superCall, 3273 Binding[] missingElements, 3274 int[] missingElementsStarts, 3275 int[] missingElementsEnds, 3276 boolean missingElementsHaveProblems) { 3277 3278 if (token == null) 3279 return; 3280 3281 if (receiverType.isBaseType()) 3282 return; 3284 boolean proposeField = !this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null); 3285 boolean proposeMethod = !this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null); 3286 3287 ObjectVector methodsFound = new ObjectVector(); 3288 3289 if (receiverType.isArrayType()) { 3290 if (proposeField 3291 && token.length <= lengthField.length 3292 && CharOperation.prefixEquals(token, lengthField, false 3293 )) { 3294 3295 int relevance = computeBaseRelevance(); 3296 relevance += computeRelevanceForResolution(); 3297 relevance += computeRelevanceForInterestingProposal(); 3298 relevance += computeRelevanceForCaseMatching(token,lengthField); 3299 relevance += computeRelevanceForExpectingType(TypeBinding.INT); 3300 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); if (missingElements != null) { 3302 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 3303 } 3304 this.noProposal = false; 3305 if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) { 3306 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 3307 proposal.setDeclarationSignature(getSignature(receiverType)); 3308 proposal.setSignature(INT_SIGNATURE); 3309 proposal.setTypeName(INT); 3313 proposal.setName(lengthField); 3314 if (missingElements != null) { 3315 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 3316 for (int i = 0; i < missingElements.length; i++) { 3317 subProposals[i] = 3318 createRequiredTypeProposal( 3319 missingElements[i], 3320 missingElementsStarts[i], 3321 missingElementsEnds[i], 3322 relevance); 3323 } 3324 proposal.setRequiredProposals(subProposals); 3325 } 3326 proposal.setCompletion(lengthField); 3327 proposal.setFlags(Flags.AccPublic); 3328 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3329 proposal.setRelevance(relevance); 3330 this.requestor.accept(proposal); 3331 if(DEBUG) { 3332 this.printDebug(proposal); 3333 } 3334 } 3335 } 3336 if (proposeMethod 3337 && token.length <= cloneMethod.length 3338 && CharOperation.prefixEquals(token, cloneMethod, false ) 3339 ) { 3340 ReferenceBinding objectRef = scope.getJavaLangObject(); 3341 3342 int relevance = computeBaseRelevance(); 3343 relevance += computeRelevanceForResolution(); 3344 relevance += computeRelevanceForInterestingProposal(); 3345 relevance += computeRelevanceForCaseMatching(token, cloneMethod); 3346 relevance += computeRelevanceForExpectingType(objectRef); 3347 relevance += computeRelevanceForStatic(false, false); 3348 relevance += computeRelevanceForQualification(false); 3349 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); if (missingElements != null) { 3351 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 3352 } 3353 char[] completion; 3354 if (this.source != null 3355 && this.source.length > this.endPosition 3356 && this.source[this.endPosition] == '(') { 3357 completion = cloneMethod; 3358 } else { 3359 completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' }); 3360 } 3361 this.noProposal = false; 3362 if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) { 3363 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 3364 proposal.setDeclarationSignature(getSignature(receiverType)); 3365 proposal.setSignature( 3366 this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ? 3367 createMethodSignature( 3368 CharOperation.NO_CHAR_CHAR, 3369 CharOperation.NO_CHAR_CHAR, 3370 getSignature(receiverType)) : 3371 createMethodSignature( 3372 CharOperation.NO_CHAR_CHAR, 3373 CharOperation.NO_CHAR_CHAR, 3374 CharOperation.concatWith(JAVA_LANG, '.'), 3375 OBJECT)); 3376 proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.')); 3382 proposal.setTypeName(OBJECT); 3383 proposal.setName(cloneMethod); 3384 if (missingElements != null) { 3385 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 3386 for (int i = 0; i < missingElements.length; i++) { 3387 subProposals[i] = 3388 createRequiredTypeProposal( 3389 missingElements[i], 3390 missingElementsStarts[i], 3391 missingElementsEnds[i], 3392 relevance); 3393 } 3394 proposal.setRequiredProposals(subProposals); 3395 } 3396 proposal.setCompletion(completion); 3397 proposal.setFlags(Flags.AccPublic); 3398 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3399 proposal.setRelevance(relevance); 3400 this.requestor.accept(proposal); 3401 if(DEBUG) { 3402 this.printDebug(proposal); 3403 } 3404 } 3405 methodsFound.add(new Object []{objectRef.getMethods(cloneMethod)[0], objectRef}); 3406 } 3407 3408 receiverType = scope.getJavaLangObject(); 3409 } 3410 3411 if(proposeField) { 3412 findFields( 3413 token, 3414 (ReferenceBinding) receiverType, 3415 scope, 3416 new ObjectVector(), 3417 new ObjectVector(), 3418 false, 3419 invocationSite, 3420 invocationScope, 3421 implicitCall, 3422 false, 3423 missingElements, 3424 missingElementsStarts, 3425 missingElementsEnds, 3426 missingElementsHaveProblems); 3427 } 3428 3429 if(proposeMethod) { 3430 findMethods( 3431 token, 3432 null, 3433 null, 3434 (ReferenceBinding) receiverType, 3435 scope, 3436 methodsFound, 3437 false, 3438 false, 3439 false, 3440 invocationSite, 3441 invocationScope, 3442 implicitCall, 3443 superCall, 3444 false, 3445 missingElements, 3446 missingElementsStarts, 3447 missingElementsEnds, 3448 missingElementsHaveProblems); 3449 } 3450 } 3451 3452 private void findFieldsAndMethodsFromFavorites( 3453 char[] token, 3454 Scope scope, 3455 InvocationSite invocationSite, 3456 Scope invocationScope, 3457 ObjectVector localsFound, 3458 ObjectVector fieldsFound, 3459 ObjectVector methodsFound) { 3460 3461 ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope); 3462 3463 if (favoriteBindings != null && favoriteBindings.length > 0) { 3464 for (int i = 0; i < favoriteBindings.length; i++) { 3465 ImportBinding favoriteBinding = favoriteBindings[i]; 3466 switch (favoriteBinding.resolvedImport.kind()) { 3467 case Binding.FIELD: 3468 FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport; 3469 findFieldsFromFavorites( 3470 token, 3471 new FieldBinding[]{fieldBinding}, 3472 scope, 3473 fieldsFound, 3474 localsFound, 3475 fieldBinding.declaringClass, 3476 invocationSite, 3477 invocationScope); 3478 break; 3479 case Binding.METHOD: 3480 MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport; 3481 MethodBinding[] methods = methodBinding.declaringClass.availableMethods(); 3482 long range; 3483 if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) { 3484 int start = (int) range, end = (int) (range >> 32); 3485 int length = end - start + 1; 3486 System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length); 3487 } else { 3488 methods = Binding.NO_METHODS; 3489 } 3490 findLocalMethodsFromFavorites( 3491 token, 3492 methods, 3493 scope, 3494 methodsFound, 3495 methodBinding.declaringClass, 3496 invocationSite, 3497 invocationScope); 3498 break; 3499 case Binding.TYPE: 3500 ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport; 3501 if(favoriteBinding.onDemand) { 3502 findFieldsFromFavorites( 3503 token, 3504 referenceBinding.availableFields(), 3505 scope, 3506 fieldsFound, 3507 localsFound, 3508 referenceBinding, 3509 invocationSite, 3510 invocationScope); 3511 3512 findLocalMethodsFromFavorites( 3513 token, 3514 referenceBinding.availableMethods(), 3515 scope, 3516 methodsFound, 3517 referenceBinding, 3518 invocationSite, 3519 invocationScope); 3520 } 3521 break; 3522 } 3523 } 3524 } 3525 } 3526 3527 private void findFieldsAndMethodsFromMissingFieldType( 3528 char[] token, 3529 Scope scope, 3530 InvocationSite invocationSite, 3531 boolean insideTypeAnnotation) { 3532 3533 boolean staticsOnly = false; 3534 Scope currentScope = scope; 3535 3536 done : while (true) { 3538 switch (currentScope.kind) { 3539 3540 case Scope.METHOD_SCOPE : 3541 MethodScope methodScope = (MethodScope) currentScope; 3543 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 3544 3545 case Scope.BLOCK_SCOPE : 3546 break; 3547 3548 case Scope.CLASS_SCOPE : 3549 ClassScope classScope = (ClassScope) currentScope; 3550 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 3551 if(!insideTypeAnnotation) { 3552 3553 FieldDeclaration[] fields = classScope.referenceContext.fields; 3554 3555 int fieldsCount = fields == null ? 0 : fields.length; 3556 for (int i = 0; i < fieldsCount; i++) { 3557 FieldDeclaration fieldDeclaration = fields[i]; 3558 if (CharOperation.equals(fieldDeclaration.name, token)) { 3559 if (fieldDeclaration.binding == null) { 3560 findFieldsAndMethodsFromMissingType( 3561 this.completionToken, 3562 fieldDeclaration.type, 3563 currentScope, 3564 invocationSite, 3565 scope); 3566 } 3567 break done; 3568 } 3569 } 3570 } 3571 staticsOnly |= enclosingType.isStatic(); 3572 insideTypeAnnotation = false; 3573 break; 3574 case Scope.COMPILATION_UNIT_SCOPE : 3575 break done; 3576 } 3577 currentScope = currentScope.parent; 3578 } 3579 } 3580 3581 private void findFieldsAndMethodsFromMissingReturnType( 3582 char[] token, 3583 TypeBinding[] arguments, 3584 Scope scope, 3585 InvocationSite invocationSite, 3586 boolean insideTypeAnnotation) { 3587 3588 boolean staticsOnly = false; 3589 Scope currentScope = scope; 3590 3591 done : while (true) { 3593 switch (currentScope.kind) { 3594 3595 case Scope.METHOD_SCOPE : 3596 MethodScope methodScope = (MethodScope) currentScope; 3598 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 3599 3600 case Scope.BLOCK_SCOPE : 3601 break; 3602 3603 case Scope.CLASS_SCOPE : 3604 ClassScope classScope = (ClassScope) currentScope; 3605 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 3606 if(!insideTypeAnnotation) { 3607 3608 AbstractMethodDeclaration[] methods = classScope.referenceContext.methods; 3609 3610 int methodsCount = methods == null ? 0 : methods.length; 3611 for (int i = 0; i < methodsCount; i++) { 3612 AbstractMethodDeclaration methodDeclaration = methods[i]; 3613 if (methodDeclaration instanceof MethodDeclaration && 3614 CharOperation.equals(methodDeclaration.selector, token)) { 3615 MethodDeclaration method = (MethodDeclaration) methodDeclaration; 3616 if (methodDeclaration.binding == null) { 3617 Argument[] parameters = method.arguments; 3618 int parametersLength = parameters == null ? 0 : parameters.length; 3619 int argumentsLength = arguments == null ? 0 : arguments.length; 3620 3621 if (parametersLength == 0) { 3622 if (argumentsLength == 0) { 3623 findFieldsAndMethodsFromMissingType( 3624 this.completionToken, 3625 method.returnType, 3626 currentScope, 3627 invocationSite, 3628 scope); 3629 break done; 3630 } 3631 } else { 3632 TypeBinding[] parametersBindings = new TypeBinding[parametersLength]; 3633 for (int j = 0; j < parametersLength; j++) { 3634 parametersBindings[j] = parameters[j].type.resolvedType; 3635 } 3636 if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) { 3637 findFieldsAndMethodsFromMissingType( 3638 this.completionToken, 3639 method.returnType, 3640 currentScope, 3641 invocationSite, 3642 scope); 3643 break done; 3644 } 3645 } 3646 } 3647 3648 } 3649 } 3650 } 3651 staticsOnly |= enclosingType.isStatic(); 3652 insideTypeAnnotation = false; 3653 break; 3654 case Scope.COMPILATION_UNIT_SCOPE : 3655 break done; 3656 } 3657 currentScope = currentScope.parent; 3658 } 3659 } 3660 3661 private void findFieldsAndMethodsFromMissingType( 3662 final char[] token, 3663 TypeReference typeRef, 3664 final Scope scope, 3665 final InvocationSite invocationSite, 3666 final Scope invocationScope) { 3667 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 3668 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 3669 new MissingTypesGuesser.GuessedTypeRequestor() { 3670 public void accept( 3671 TypeBinding guessedType, 3672 Binding[] missingElements, 3673 int[] missingElementsStarts, 3674 int[] missingElementsEnds, 3675 boolean hasProblems) { 3676 findFieldsAndMethods( 3677 CompletionEngine.this.completionToken, 3678 guessedType, 3679 scope, 3680 invocationSite, 3681 invocationScope, 3682 false, 3683 false, 3684 missingElements, 3685 missingElementsStarts, 3686 missingElementsEnds, 3687 hasProblems); 3688 3689 } 3690 }; 3691 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 3692 } 3693 3694 private void findFieldsFromFavorites( 3695 char[] fieldName, 3696 FieldBinding[] fields, 3697 Scope scope, 3698 ObjectVector fieldsFound, 3699 ObjectVector localsFound, 3700 ReferenceBinding receiverType, 3701 InvocationSite invocationSite, 3702 Scope invocationScope) { 3703 3704 char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.'); 3705 3706 int fieldLength = fieldName.length; 3707 next : for (int f = fields.length; --f >= 0;) { 3708 FieldBinding field = fields[f]; 3709 3710 if (field.isSynthetic()) continue next; 3711 3712 if (!field.isStatic()) continue next; 3714 3715 if (fieldLength > field.name.length) continue next; 3716 3717 if (!CharOperation.prefixEquals(fieldName, field.name, false ) 3718 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next; 3719 3720 if (this.options.checkDeprecation && 3721 field.isViewedAsDeprecated() && 3722 !scope.isDefinedInSameUnit(field.declaringClass)) 3723 continue next; 3724 3725 if (this.options.checkVisibility 3726 && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 3727 3728 for (int i = fieldsFound.size; --i >= 0;) { 3729 Object [] other = (Object [])fieldsFound.elementAt(i); 3730 FieldBinding otherField = (FieldBinding) other[0]; 3731 3732 if (field == otherField) continue next; 3733 } 3734 3735 fieldsFound.add(new Object []{field, receiverType}); 3736 3737 int relevance = computeBaseRelevance(); 3738 relevance += computeRelevanceForResolution(); 3739 relevance += computeRelevanceForInterestingProposal(field); 3740 if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name); 3741 relevance += computeRelevanceForExpectingType(field.type); 3742 relevance += computeRelevanceForStatic(true, true); 3743 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 3744 3745 CompilationUnitDeclaration cu = this.unitScope.referenceContext; 3746 int importStart = cu.types[0].declarationSourceStart; 3747 int importEnd = importStart; 3748 3749 this.noProposal = false; 3750 3751 if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 || 3752 !this.options.suggestStaticImport) { 3753 if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) { 3754 char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.'); 3755 3756 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 3757 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 3758 proposal.setSignature(getSignature(field.type)); 3759 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3760 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3761 proposal.setPackageName(field.type.qualifiedPackageName()); 3762 proposal.setTypeName(field.type.qualifiedSourceName()); 3763 proposal.setName(field.name); 3764 proposal.setCompletion(completion); 3765 proposal.setFlags(field.modifiers); 3766 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3767 proposal.setRelevance(relevance); 3768 3769 char[] typeImportCompletion = createImportCharArray(typeName, false, false); 3770 3771 CompletionProposal typeImportProposal = this.createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition); 3772 typeImportProposal.nameLookup = this.nameEnvironment.nameLookup; 3773 typeImportProposal.completionEngine = this; 3774 char[] packageName = receiverType.qualifiedPackageName(); 3775 typeImportProposal.setDeclarationSignature(packageName); 3776 typeImportProposal.setSignature(getSignature(receiverType)); 3777 typeImportProposal.setPackageName(packageName); 3778 typeImportProposal.setTypeName(receiverType.qualifiedSourceName()); 3779 typeImportProposal.setCompletion(typeImportCompletion); 3780 typeImportProposal.setFlags(receiverType.modifiers); 3781 typeImportProposal.setAdditionalFlags(CompletionFlags.Default); 3782 typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 3783 typeImportProposal.setRelevance(relevance); 3784 3785 proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal}); 3786 3787 this.requestor.accept(proposal); 3788 if(DEBUG) { 3789 this.printDebug(proposal); 3790 } 3791 } 3792 } else { 3793 if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) { 3794 char[] completion = field.name; 3795 3796 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 3797 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 3798 proposal.setSignature(getSignature(field.type)); 3799 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3800 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3801 proposal.setPackageName(field.type.qualifiedPackageName()); 3802 proposal.setTypeName(field.type.qualifiedSourceName()); 3803 proposal.setName(field.name); 3804 proposal.setCompletion(completion); 3805 proposal.setFlags(field.modifiers); 3806 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3807 proposal.setRelevance(relevance); 3808 3809 char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false); 3810 3811 CompletionProposal fieldImportProposal = this.createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition); 3812 fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass)); 3813 fieldImportProposal.setSignature(getSignature(field.type)); 3814 fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3815 fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3816 fieldImportProposal.setPackageName(field.type.qualifiedPackageName()); 3817 fieldImportProposal.setTypeName(field.type.qualifiedSourceName()); 3818 fieldImportProposal.setName(field.name); 3819 fieldImportProposal.setCompletion(fieldImportCompletion); 3820 fieldImportProposal.setFlags(field.modifiers); 3821 fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport); 3822 fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 3823 fieldImportProposal.setRelevance(relevance); 3824 3825 proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal}); 3826 3827 this.requestor.accept(proposal); 3828 if(DEBUG) { 3829 this.printDebug(proposal); 3830 } 3831 } 3832 } 3833 } 3834 } 3835 3836 private void findImports(CompletionOnImportReference importReference, boolean findMembers) { 3837 char[][] tokens = importReference.tokens; 3838 3839 char[] importName = CharOperation.concatWith(tokens, '.'); 3840 3841 if (importName.length == 0) 3842 return; 3843 3844 char[] lastToken = tokens[tokens.length - 1]; 3845 if(lastToken != null && lastToken.length == 0) 3846 importName = CharOperation.concat(importName, new char[]{'.'}); 3847 3848 this.resolvingImports = true; 3849 this.resolvingStaticImports = importReference.isStatic(); 3850 3851 this.completionToken = importName; 3852 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 3854 this.nameEnvironment.findPackages(importName, this); 3855 } 3856 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 3857 this.nameEnvironment.findTypes( 3858 importName, 3859 findMembers, 3860 this.options.camelCaseMatch, 3861 IJavaSearchConstants.TYPE, 3862 this); 3863 acceptTypes(null); 3864 } 3865 } 3866 3867 private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) { 3868 ReferenceBinding[] memberTypes = ref.memberTypes(); 3869 3870 int typeLength = typeName.length; 3871 next : for (int m = memberTypes.length; --m >= 0;) { 3872 ReferenceBinding memberType = memberTypes[m]; 3873 3876 if (onlyStatic && !memberType.isStatic()) 3877 continue next; 3878 3879 if (typeLength > memberType.sourceName.length) 3880 continue next; 3881 3882 if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false) 3883 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName))) 3884 continue next; 3885 3886 if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next; 3887 3888 if (this.options.checkVisibility 3889 && !memberType.canBeSeenBy(this.unitScope.fPackage)) 3890 continue next; 3891 3892 char[] completionName = CharOperation.concat( 3893 memberType.qualifiedPackageName(), 3894 memberType.qualifiedSourceName(), 3895 '.'); 3896 3897 completionName = CharOperation.concat(completionName, SEMICOLON); 3898 3899 int relevance = computeBaseRelevance(); 3900 relevance += computeRelevanceForResolution(); 3901 relevance += computeRelevanceForInterestingProposal(); 3902 relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName); 3903 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 3904 3905 if (memberType.isClass()) { 3906 relevance += computeRelevanceForClass(); 3907 } else if(memberType.isEnum()) { 3908 relevance += computeRelevanceForEnum(); 3909 } else if (memberType.isInterface()) { 3910 relevance += computeRelevanceForInterface(); 3911 } 3912 this.noProposal = false; 3913 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 3914 createTypeProposal(memberType, memberType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance); 3915 } 3916 } 3917 } 3918 3919 private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) { 3920 FieldBinding[] fields = ref.fields(); 3921 3922 int fieldLength = fieldName.length; 3923 next : for (int m = fields.length; --m >= 0;) { 3924 FieldBinding field = fields[m]; 3925 3926 if (fieldLength > field.name.length) 3927 continue next; 3928 3929 if (field.isSynthetic()) 3930 continue next; 3931 3932 if (!field.isStatic()) 3933 continue next; 3934 3935 if (!CharOperation.prefixEquals(fieldName, field.name, false) 3936 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) 3937 continue next; 3938 3939 if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next; 3940 3941 if (this.options.checkVisibility 3942 && !field.canBeSeenBy(this.unitScope.fPackage)) 3943 continue next; 3944 3945 char[] completionName = CharOperation.concat(field.name, SEMICOLON); 3946 3947 int relevance = computeBaseRelevance(); 3948 relevance += computeRelevanceForResolution(); 3949 relevance += computeRelevanceForInterestingProposal(); 3950 relevance += computeRelevanceForCaseMatching(fieldName, field.name); 3951 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 3952 3953 this.noProposal = false; 3954 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 3955 CompletionProposal proposal = this.createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 3956 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 3957 proposal.setSignature(getSignature(field.type)); 3958 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 3959 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 3960 proposal.setPackageName(field.type.qualifiedPackageName()); 3961 proposal.setTypeName(field.type.qualifiedSourceName()); 3962 proposal.setName(field.name); 3963 proposal.setCompletion(completionName); 3964 proposal.setFlags(field.modifiers); 3965 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 3966 proposal.setRelevance(relevance); 3967 this.requestor.accept(proposal); 3968 if(DEBUG) { 3969 this.printDebug(proposal); 3970 } 3971 } 3972 } 3973 } 3974 3975 private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) { 3976 MethodBinding[] methods = ref.methods(); 3977 3978 int methodLength = methodName.length; 3979 next : for (int m = methods.length; --m >= 0;) { 3980 MethodBinding method = methods[m]; 3981 3982 if (method.isSynthetic()) continue next; 3983 3984 if (method.isDefaultAbstract()) continue next; 3985 3986 if (method.isConstructor()) continue next; 3987 3988 if (!method.isStatic()) continue next; 3989 3990 if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next; 3991 3992 if (this.options.checkVisibility 3993 && !method.canBeSeenBy(this.unitScope.fPackage)) continue next; 3994 3995 if (methodLength > method.selector.length) 3996 continue next; 3997 3998 if (!CharOperation.prefixEquals(methodName, method.selector, false) 3999 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) 4000 continue next; 4001 4002 int length = method.parameters.length; 4003 char[][] parameterPackageNames = new char[length][]; 4004 char[][] parameterTypeNames = new char[length][]; 4005 4006 for (int i = 0; i < length; i++) { 4007 TypeBinding type = method.original().parameters[i]; 4008 parameterPackageNames[i] = type.qualifiedPackageName(); 4009 parameterTypeNames[i] = type.qualifiedSourceName(); 4010 } 4011 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 4012 4013 4014 char[] completionName = CharOperation.concat( 4015 method.declaringClass.qualifiedPackageName(), 4016 '.', 4017 method.declaringClass.qualifiedSourceName(), 4018 '.', 4019 method.selector); 4020 4021 completionName = CharOperation.concat(completionName, SEMICOLON); 4022 4023 int relevance = computeBaseRelevance(); 4024 relevance += computeRelevanceForResolution(); 4025 relevance += computeRelevanceForInterestingProposal(); 4026 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 4027 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 4028 4029 this.noProposal = false; 4030 if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) { 4031 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition); 4032 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 4033 proposal.setSignature(getSignature(method)); 4034 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 4035 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 4036 proposal.setParameterPackageNames(parameterPackageNames); 4037 proposal.setParameterTypeNames(parameterTypeNames); 4038 proposal.setPackageName(method.returnType.qualifiedPackageName()); 4039 proposal.setTypeName(method.returnType.qualifiedSourceName()); 4040 proposal.setName(method.selector); 4041 proposal.setCompletion(completionName); 4042 proposal.setFlags(method.modifiers); 4043 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4044 proposal.setRelevance(relevance); 4045 if(parameterNames != null) proposal.setParameterNames(parameterNames); 4046 this.requestor.accept(proposal); 4047 if(DEBUG) { 4048 this.printDebug(proposal); 4049 } 4050 } 4051 } 4052 } 4053 4054 4057 private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) { 4058 char[][] possibleTags = javadocTag.getPossibleBlockTags(); 4059 if (possibleTags == null) return; 4060 int length = possibleTags.length; 4061 for (int i=0; i<length; i++) { 4062 int relevance = computeBaseRelevance(); 4063 relevance += computeRelevanceForInterestingProposal(); 4064 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 4066 this.noProposal = false; 4067 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) { 4068 char[] possibleTag = possibleTags[i]; 4069 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition); 4070 proposal.setName(possibleTag); 4071 int tagLength = possibleTag.length; 4072 char[] completion = new char[1+tagLength]; 4073 completion[0] = '@'; 4074 System.arraycopy(possibleTag, 0, completion, 1, tagLength); 4075 proposal.setCompletion(completion); 4076 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4077 proposal.setRelevance(relevance); 4078 this.requestor.accept(proposal); 4079 if (DEBUG) { 4080 this.printDebug(proposal); 4081 } 4082 } 4083 } 4084 } 4085 4086 4089 private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) { 4090 char[][] possibleTags = javadocTag.getPossibleInlineTags(); 4091 if (possibleTags == null) return; 4092 int length = possibleTags.length; 4093 for (int i=0; i<length; i++) { 4094 int relevance = computeBaseRelevance(); 4095 relevance += computeRelevanceForInterestingProposal(); 4096 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 4098 this.noProposal = false; 4099 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) { 4100 char[] possibleTag = possibleTags[i]; 4101 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition); 4102 proposal.setName(possibleTag); 4103 int tagLength = possibleTag.length; 4104 char[] completion = new char[2+tagLength+1]; 4106 completion[0] = '{'; 4107 completion[1] = '@'; 4108 System.arraycopy(possibleTag, 0, completion, 2, tagLength); 4109 completion[tagLength+2] = '}'; 4112 proposal.setCompletion(completion); 4113 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4114 proposal.setRelevance(relevance); 4115 this.requestor.accept(proposal); 4116 if (DEBUG) { 4117 this.printDebug(proposal); 4118 } 4119 } 4120 } 4121 } 4122 4123 private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) { 4126 if(choices == null || choices.length == 0) return; 4127 4128 int length = keyword.length; 4129 if (canCompleteEmptyToken || length > 0) 4130 for (int i = 0; i < choices.length; i++) 4131 if (length <= choices[i].length 4132 && CharOperation.prefixEquals(keyword, choices[i], false 4133 )){ 4134 int relevance = computeBaseRelevance(); 4135 relevance += computeRelevanceForResolution(); 4136 relevance += computeRelevanceForInterestingProposal(); 4137 relevance += computeRelevanceForCaseMatching(keyword, choices[i]); 4138 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; 4140 4141 if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) { 4142 relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); 4143 relevance += computeRelevanceForQualification(false); 4144 } 4145 this.noProposal = false; 4146 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 4147 CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 4148 proposal.setName(choices[i]); 4149 proposal.setCompletion(choices[i]); 4150 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4151 proposal.setRelevance(relevance); 4152 this.requestor.accept(proposal); 4153 if(DEBUG) { 4154 this.printDebug(proposal); 4155 } 4156 } 4157 } 4158 } 4159 private void findTrueOrFalseKeywords(char[][] choices) { 4160 if(choices == null || choices.length == 0) return; 4161 4162 if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return; 4163 4164 for (int i = 0; i < choices.length; i++) { 4165 if (CharOperation.equals(choices[i], Keywords.TRUE) || 4166 CharOperation.equals(choices[i], Keywords.FALSE) 4167 ){ 4168 int relevance = computeBaseRelevance(); 4169 relevance += computeRelevanceForResolution(); 4170 relevance += computeRelevanceForInterestingProposal(); 4171 relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]); 4172 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); 4174 relevance += computeRelevanceForQualification(false); 4175 relevance += R_TRUE_OR_FALSE; 4176 4177 this.noProposal = false; 4178 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 4179 CompletionProposal proposal = this.createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 4180 proposal.setName(choices[i]); 4181 proposal.setCompletion(choices[i]); 4182 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4183 proposal.setRelevance(relevance); 4184 this.requestor.accept(proposal); 4185 if(DEBUG) { 4186 this.printDebug(proposal); 4187 } 4188 } 4189 } 4190 } 4191 } 4192 4193 private void findKeywordsForMember(char[] token, int modifiers) { 4194 char[][] keywords = new char[Keywords.COUNT][]; 4195 int count = 0; 4196 4197 if((modifiers & ClassFileConstants.AccPrivate) == 0 4199 && (modifiers & ClassFileConstants.AccProtected) == 0 4200 && (modifiers & ClassFileConstants.AccPublic) == 0) { 4201 keywords[count++] = Keywords.PROTECTED; 4202 keywords[count++] = Keywords.PUBLIC; 4203 if((modifiers & ClassFileConstants.AccAbstract) == 0) { 4204 keywords[count++] = Keywords.PRIVATE; 4205 } 4206 } 4207 4208 if((modifiers & ClassFileConstants.AccAbstract) == 0) { 4209 if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) { 4211 keywords[count++] = Keywords.ABSTRACT; 4212 } 4213 4214 if((modifiers & ClassFileConstants.AccFinal) == 0) { 4216 keywords[count++] = Keywords.FINAL; 4217 } 4218 4219 if((modifiers & ClassFileConstants.AccStatic) == 0) { 4221 keywords[count++] = Keywords.STATIC; 4222 } 4223 4224 boolean canBeField = true; 4225 boolean canBeMethod = true; 4226 boolean canBeType = true; 4227 if((modifiers & ClassFileConstants.AccNative) != 0 4228 || (modifiers & ClassFileConstants.AccStrictfp) != 0 4229 || (modifiers & ClassFileConstants.AccSynchronized) != 0) { 4230 canBeField = false; 4231 canBeType = false; 4232 } 4233 4234 if((modifiers & ClassFileConstants.AccTransient) != 0 4235 || (modifiers & ClassFileConstants.AccVolatile) != 0) { 4236 canBeMethod = false; 4237 canBeType = false; 4238 } 4239 4240 if(canBeField) { 4241 if((modifiers & ClassFileConstants.AccTransient) == 0) { 4243 keywords[count++] = Keywords.TRANSIENT; 4244 } 4245 4246 if((modifiers & ClassFileConstants.AccVolatile) == 0) { 4248 keywords[count++] = Keywords.VOLATILE; 4249 } 4250 } 4251 4252 if(canBeMethod) { 4253 if((modifiers & ClassFileConstants.AccNative) == 0) { 4255 keywords[count++] = Keywords.NATIVE; 4256 } 4257 4258 if((modifiers & ClassFileConstants.AccStrictfp) == 0) { 4260 keywords[count++] = Keywords.STRICTFP; 4261 } 4262 4263 if((modifiers & ClassFileConstants.AccSynchronized) == 0) { 4265 keywords[count++] = Keywords.SYNCHRONIZED; 4266 } 4267 } 4268 4269 if(canBeType) { 4270 keywords[count++] = Keywords.CLASS; 4271 keywords[count++] = Keywords.INTERFACE; 4272 } 4273 } else { 4274 keywords[count++] = Keywords.CLASS; 4276 keywords[count++] = Keywords.INTERFACE; 4277 } 4278 System.arraycopy(keywords, 0, keywords = new char[count][], 0, count); 4279 4280 findKeywords(token, keywords, false, false); 4281 } 4282 4283 private void findMemberTypes( 4285 char[] typeName, 4286 ReferenceBinding[] memberTypes, 4287 ObjectVector typesFound, 4288 ReferenceBinding receiverType, 4289 SourceTypeBinding invocationType, 4290 boolean staticOnly, 4291 boolean staticFieldsAndMethodOnly, 4292 boolean fromStaticImport, 4293 boolean checkQualification, 4294 Scope scope) { 4295 4296 int typeLength = typeName.length; 4299 next : for (int m = memberTypes.length; --m >= 0;) { 4300 ReferenceBinding memberType = memberTypes[m]; 4301 4304 if (staticOnly && !memberType.isStatic()) continue next; 4305 4306 if (isForbidden(memberType)) continue next; 4307 4308 if (typeLength > memberType.sourceName.length) 4309 continue next; 4310 4311 if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false) 4312 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName))) 4313 continue next; 4314 4315 if (this.options.checkDeprecation && 4316 memberType.isViewedAsDeprecated() && 4317 !scope.isDefinedInSameUnit(memberType)) 4318 continue next; 4319 4320 if (this.options.checkVisibility) { 4321 if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) { 4322 continue next; 4323 } else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) { 4324 continue next; 4325 } 4326 } 4327 4328 for (int i = typesFound.size; --i >= 0;) { 4329 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i); 4330 4331 if (memberType == otherType) 4332 continue next; 4333 4334 if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) { 4335 4336 if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType())) 4337 continue next; 4338 4339 if (otherType.enclosingType().isInterface()) 4340 if (memberType.enclosingType() 4341 .implementsInterface(otherType.enclosingType(), true)) 4342 continue next; 4343 4344 if (memberType.enclosingType().isInterface()) 4345 if (otherType.enclosingType() 4346 .implementsInterface(memberType.enclosingType(), true)) 4347 continue next; 4348 } 4349 } 4350 4351 typesFound.add(memberType); 4352 4353 if(!this.insideQualifiedReference) { 4354 if(this.assistNodeIsClass) { 4355 if(!memberType.isClass()) continue next; 4356 } else if(this.assistNodeIsInterface) { 4357 if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next; 4358 } else if (this.assistNodeIsAnnotation) { 4359 if(!memberType.isAnnotationType()) continue next; 4360 } 4361 } 4362 4363 char[] completionName = memberType.sourceName(); 4364 4365 boolean isQualified = false; 4366 if(checkQualification && !fromStaticImport) { 4367 char[] memberPackageName = memberType.qualifiedPackageName(); 4368 char[] memberTypeName = memberType.sourceName(); 4369 char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName(); 4370 if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) { 4371 if (memberPackageName == null || memberPackageName.length == 0) 4372 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 4373 break next; isQualified = true; 4375 completionName = 4376 CharOperation.concat( 4377 memberPackageName, 4378 CharOperation.concat( 4379 memberEnclosingTypeNames, 4380 memberTypeName, 4381 '.'), 4382 '.'); 4383 } 4384 } 4385 4386 int relevance = computeBaseRelevance(); 4387 relevance += computeRelevanceForResolution(); 4388 relevance += computeRelevanceForInterestingProposal(); 4389 relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName); 4390 relevance += computeRelevanceForExpectingType(memberType); 4391 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 4392 if(!insideQualifiedReference) { 4393 relevance += computeRelevanceForQualification(isQualified); 4394 } 4395 if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; 4397 if (memberType.isAnnotationType()) { 4398 relevance += computeRelevanceForAnnotation(); 4399 relevance += computeRelevanceForAnnotationTarget(memberType); 4400 } else if (memberType.isClass()) { 4401 relevance += computeRelevanceForClass(); 4402 relevance += computeRelevanceForException(memberType.sourceName); 4403 } else if(memberType.isEnum()) { 4404 relevance += computeRelevanceForEnum(); 4405 } else if(memberType.isInterface()) { 4406 relevance += computeRelevanceForInterface(); 4407 } 4408 4409 this.noProposal = false; 4410 createTypeProposal(memberType, memberType.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, completionName, relevance); 4411 } 4412 } 4413 4414 private void findMemberTypes( 4415 char[] typeName, 4416 ReferenceBinding receiverType, 4417 Scope scope, 4418 SourceTypeBinding typeInvocation, 4419 boolean staticOnly, 4420 boolean staticFieldsAndMethodOnly, 4421 ObjectVector typesFound) { 4422 findMemberTypes( 4423 typeName, 4424 receiverType, 4425 scope, 4426 typeInvocation, 4427 staticOnly, 4428 staticFieldsAndMethodOnly, 4429 false, 4430 false, 4431 false, 4432 null, 4433 typesFound); 4434 } 4435 private void findMemberTypes( 4436 char[] typeName, 4437 ReferenceBinding receiverType, 4438 Scope scope, 4439 SourceTypeBinding typeInvocation, 4440 boolean staticOnly, 4441 boolean staticFieldsAndMethodOnly, 4442 boolean fromStaticImport, 4443 boolean checkQualification, 4444 boolean proposeAllMemberTypes, 4445 SourceTypeBinding typeToIgnore, 4446 ObjectVector typesFound) { 4447 4448 ReferenceBinding currentType = receiverType; 4449 if (typeName == null) 4450 return; 4451 4452 if (this.assistNodeIsSuperType && !this.insideQualifiedReference) return; 4454 if (currentType.superInterfaces() == null) return; 4455 4456 if (this.insideQualifiedReference 4457 || typeName.length == 0) { 4459 findMemberTypes( 4460 typeName, 4461 currentType.memberTypes(), 4462 typesFound, 4463 receiverType, 4464 typeInvocation, 4465 staticOnly, 4466 staticFieldsAndMethodOnly, 4467 fromStaticImport, 4468 checkQualification, 4469 scope); 4470 return; 4471 } 4472 4473 ReferenceBinding[] interfacesToVisit = null; 4474 int nextPosition = 0; 4475 4476 do { 4477 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 4478 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 4479 if (interfacesToVisit == null) { 4480 interfacesToVisit = itsInterfaces; 4481 nextPosition = interfacesToVisit.length; 4482 } else { 4483 int itsLength = itsInterfaces.length; 4484 if (nextPosition + itsLength >= interfacesToVisit.length) 4485 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 4486 nextInterface : for (int a = 0; a < itsLength; a++) { 4487 ReferenceBinding next = itsInterfaces[a]; 4488 for (int b = 0; b < nextPosition; b++) 4489 if (next == interfacesToVisit[b]) continue nextInterface; 4490 interfacesToVisit[nextPosition++] = next; 4491 } 4492 } 4493 } 4494 4495 findMemberTypes( 4496 typeName, 4497 currentType.memberTypes(), 4498 typesFound, 4499 receiverType, 4500 typeInvocation, 4501 staticOnly, 4502 staticFieldsAndMethodOnly, 4503 fromStaticImport, 4504 checkQualification, 4505 scope); 4506 4507 currentType = currentType.superclass(); 4508 } while (currentType != null); 4509 4510 if(proposeAllMemberTypes) { 4511 ReferenceBinding[] memberTypes = receiverType.memberTypes(); 4512 for (int i = 0; i < memberTypes.length; i++) { 4513 if(memberTypes[i] != typeToIgnore) { 4514 findSubMemberTypes( 4515 typeName, 4516 memberTypes[i], 4517 scope, 4518 typeInvocation, 4519 staticOnly, 4520 staticFieldsAndMethodOnly, 4521 fromStaticImport, 4522 typesFound); 4523 } 4524 } 4525 } 4526 4527 if (interfacesToVisit != null) { 4528 for (int i = 0; i < nextPosition; i++) { 4529 ReferenceBinding anInterface = interfacesToVisit[i]; 4530 findMemberTypes( 4531 typeName, 4532 anInterface.memberTypes(), 4533 typesFound, 4534 receiverType, 4535 typeInvocation, 4536 staticOnly, 4537 staticFieldsAndMethodOnly, 4538 fromStaticImport, 4539 checkQualification, 4540 scope); 4541 4542 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 4543 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 4544 int itsLength = itsInterfaces.length; 4545 if (nextPosition + itsLength >= interfacesToVisit.length) 4546 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 4547 nextInterface : for (int a = 0; a < itsLength; a++) { 4548 ReferenceBinding next = itsInterfaces[a]; 4549 for (int b = 0; b < nextPosition; b++) 4550 if (next == interfacesToVisit[b]) continue nextInterface; 4551 interfacesToVisit[nextPosition++] = next; 4552 } 4553 } 4554 } 4555 } 4556 } 4557 4558 4561 private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) { 4562 4563 if (missingParams == null) return; 4564 4565 int relevance = computeBaseRelevance(); 4567 relevance += computeRelevanceForInterestingProposal(); 4568 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); if (!isTypeParam) relevance += R_INTERESTING; 4570 4571 int length = missingParams.length; 4573 relevance += length; 4574 for (int i=0; i<length; i++) { 4575 char[] argName = missingParams[i]; 4576 if (token == null || CharOperation.prefixEquals(token, argName)) { 4577 4578 this.noProposal = false; 4579 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 4580 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition); 4581 proposal.setName(argName); 4582 char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName; 4583 proposal.setCompletion(completion); 4584 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 4585 proposal.setRelevance(--relevance); 4586 this.requestor.accept(proposal); 4587 if (DEBUG) { 4588 this.printDebug(proposal); 4589 } 4590 } 4591 } 4592 } 4593 } 4594 4595 private void findSubMemberTypes( 4596 char[] typeName, 4597 ReferenceBinding receiverType, 4598 Scope scope, 4599 SourceTypeBinding typeInvocation, 4600 boolean staticOnly, 4601 boolean staticFieldsAndMethodOnly, 4602 boolean fromStaticImport, 4603 ObjectVector typesFound) { 4604 4605 ReferenceBinding currentType = receiverType; 4606 if (typeName == null || typeName.length == 0) 4607 return; 4608 4609 if (this.assistNodeIsSuperType && !this.insideQualifiedReference) return; 4611 if (currentType.superInterfaces() == null) return; 4612 4613 findMemberTypes( 4614 typeName, 4615 currentType.memberTypes(), 4616 typesFound, 4617 receiverType, 4618 typeInvocation, 4619 staticOnly, 4620 staticFieldsAndMethodOnly, 4621 fromStaticImport, 4622 true, 4623 scope); 4624 4625 ReferenceBinding[] memberTypes = receiverType.memberTypes(); 4626 next : for (int i = 0; i < memberTypes.length; i++) { 4627 if (this.options.checkVisibility) { 4628 if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) { 4629 continue next; 4630 } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) { 4631 continue next; 4632 } 4633 } 4634 findSubMemberTypes( 4635 typeName, 4636 memberTypes[i], 4637 scope, 4638 typeInvocation, 4639 staticOnly, 4640 staticFieldsAndMethodOnly, 4641 fromStaticImport, 4642 typesFound); 4643 } 4644 } 4645 4646 private void findInterfacesMethods( 4647 char[] selector, 4648 TypeBinding[] typeArgTypes, 4649 TypeBinding[] argTypes, 4650 ReferenceBinding receiverType, 4651 ReferenceBinding[] itsInterfaces, 4652 Scope scope, 4653 ObjectVector methodsFound, 4654 boolean onlyStaticMethods, 4655 boolean exactMatch, 4656 boolean isCompletingDeclaration, 4657 InvocationSite invocationSite, 4658 Scope invocationScope, 4659 boolean implicitCall, 4660 boolean superCall, 4661 boolean canBePrefixed, 4662 Binding[] missingElements, 4663 int[] missingElementssStarts, 4664 int[] missingElementsEnds, 4665 boolean missingElementsHaveProblems) { 4666 4667 if (selector == null) 4668 return; 4669 4670 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 4671 ReferenceBinding[] interfacesToVisit = itsInterfaces; 4672 int nextPosition = interfacesToVisit.length; 4673 4674 for (int i = 0; i < nextPosition; i++) { 4675 ReferenceBinding currentType = interfacesToVisit[i]; 4676 MethodBinding[] methods = currentType.availableMethods(); 4677 if(methods != null) { 4678 if(isCompletingDeclaration) { 4679 findLocalMethodDeclarations( 4680 selector, 4681 methods, 4682 scope, 4683 methodsFound, 4684 exactMatch, 4685 receiverType); 4686 } else { 4687 findLocalMethods( 4688 selector, 4689 typeArgTypes, 4690 argTypes, 4691 methods, 4692 scope, 4693 methodsFound, 4694 onlyStaticMethods, 4695 exactMatch, 4696 receiverType, 4697 invocationSite, 4698 invocationScope, 4699 implicitCall, 4700 superCall, 4701 canBePrefixed, 4702 missingElements, 4703 missingElementssStarts, 4704 missingElementsEnds, 4705 missingElementsHaveProblems); 4706 } 4707 } 4708 4709 if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 4710 int itsLength = itsInterfaces.length; 4711 if (nextPosition + itsLength >= interfacesToVisit.length) 4712 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 4713 nextInterface : for (int a = 0; a < itsLength; a++) { 4714 ReferenceBinding next = itsInterfaces[a]; 4715 for (int b = 0; b < nextPosition; b++) 4716 if (next == interfacesToVisit[b]) continue nextInterface; 4717 interfacesToVisit[nextPosition++] = next; 4718 } 4719 } 4720 } 4721 } 4722 } 4723 4724 private void findImplicitMessageSends( 4725 char[] token, 4726 TypeBinding[] argTypes, 4727 Scope scope, 4728 InvocationSite invocationSite, 4729 Scope invocationScope) { 4730 4731 if (token == null) 4732 return; 4733 4734 boolean staticsOnly = false; 4735 ObjectVector methodsFound = new ObjectVector(); 4737 4738 done : while (true) { 4740 switch (scope.kind) { 4741 4742 case Scope.METHOD_SCOPE : 4743 MethodScope methodScope = (MethodScope) scope; 4745 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 4746 break; 4747 4748 case Scope.CLASS_SCOPE : 4749 ClassScope classScope = (ClassScope) scope; 4750 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 4751 findMethods( 4752 token, 4753 null, 4754 argTypes, 4755 enclosingType, 4756 classScope, 4757 methodsFound, 4758 staticsOnly, 4759 true, 4760 false, 4761 invocationSite, 4762 invocationScope, 4763 true, 4764 false, 4765 true, 4766 null, 4767 null, 4768 null, 4769 false); 4770 staticsOnly |= enclosingType.isStatic(); 4771 break; 4772 4773 case Scope.COMPILATION_UNIT_SCOPE : 4774 break done; 4775 } 4776 scope = scope.parent; 4777 } 4778 } 4779 4780 private void findLocalMethods( 4782 char[] methodName, 4783 TypeBinding[] typeArgTypes, 4784 TypeBinding[] argTypes, 4785 MethodBinding[] methods, 4786 Scope scope, 4787 ObjectVector methodsFound, 4788 boolean onlyStaticMethods, 4789 boolean exactMatch, 4790 ReferenceBinding receiverType, 4791 InvocationSite invocationSite, 4792 Scope invocationScope, 4793 boolean implicitCall, 4794 boolean superCall, 4795 boolean canBePrefixed, 4796 Binding[] missingElements, 4797 int[] missingElementsStarts, 4798 int[] missingElementsEnds, 4799 boolean missingElementsHaveProblems) { 4800 4801 ObjectVector newMethodsFound = new ObjectVector(); 4802 4805 int methodLength = methodName.length; 4806 int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length; 4807 int minArgLength = argTypes == null ? 0 : argTypes.length; 4808 4809 next : for (int f = methods.length; --f >= 0;) { 4810 MethodBinding method = methods[f]; 4811 4812 if (method.isSynthetic()) continue next; 4813 4814 if (method.isDefaultAbstract()) continue next; 4815 4816 if (method.isConstructor()) continue next; 4817 4818 if (this.options.checkDeprecation && 4819 method.isViewedAsDeprecated() && 4820 !scope.isDefinedInSameUnit(method.declaringClass)) 4821 continue next; 4822 4823 4826 if (onlyStaticMethods && !method.isStatic()) continue next; 4827 4828 if (this.options.checkVisibility 4829 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 4830 4831 if(superCall && method.isAbstract()) { 4832 methodsFound.add(new Object []{method, receiverType}); 4833 continue next; 4834 } 4835 4836 if (exactMatch) { 4837 if (!CharOperation.equals(methodName, method.selector, false )) { 4838 continue next; 4839 } 4840 } else { 4841 if (methodLength > method.selector.length) continue next; 4842 if (!CharOperation.prefixEquals(methodName, method.selector, false ) 4843 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) { 4844 continue next; 4845 } 4846 } 4847 4848 if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length) 4849 continue next; 4850 4851 if (minTypeArgLength != 0) { 4852 method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes); 4853 } 4854 4855 if (minArgLength > method.parameters.length) 4856 continue next; 4857 4858 for (int a = minArgLength; --a >= 0;){ 4859 if (argTypes[a] != null) { if (!argTypes[a].isCompatibleWith(method.parameters[a])) { 4861 continue next; 4862 } 4863 } 4864 } 4865 4866 boolean prefixRequired = false; 4867 4868 for (int i = methodsFound.size; --i >= 0;) { 4869 Object [] other = (Object []) methodsFound.elementAt(i); 4870 MethodBinding otherMethod = (MethodBinding) other[0]; 4871 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 4872 if (method == otherMethod && receiverType == otherReceiverType) 4873 continue next; 4874 4875 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 4876 if (receiverType == otherReceiverType) { 4877 if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) { 4878 if (!superCall || !otherMethod.declaringClass.isInterface()) { 4879 continue next; 4880 } 4881 } 4882 } else { 4883 if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) { 4884 if(receiverType.isAnonymousType()) continue next; 4885 4886 if(!superCall) { 4887 if(!canBePrefixed) continue next; 4888 4889 prefixRequired = true; 4890 } 4891 } 4892 } 4893 } 4894 } 4895 4896 newMethodsFound.add(new Object []{method, receiverType}); 4897 4898 ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeWithSameErasure(method.declaringClass); 4899 if (method.declaringClass != superTypeWithSameErasure) { 4900 MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector); 4901 for (int i = 0; i < otherMethods.length; i++) { 4902 if(otherMethods[i].original() == method.original()) { 4903 method = otherMethods[i]; 4904 } 4905 } 4906 } 4907 4908 int length = method.parameters.length; 4909 char[][] parameterPackageNames = new char[length][]; 4910 char[][] parameterTypeNames = new char[length][]; 4911 4912 for (int i = 0; i < length; i++) { 4913 TypeBinding type = method.original().parameters[i]; 4914 parameterPackageNames[i] = type.qualifiedPackageName(); 4915 parameterTypeNames[i] = type.qualifiedSourceName(); 4916 } 4917 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 4918 4919 char[] completion = CharOperation.NO_CHAR; 4920 4921 int previousStartPosition = this.startPosition; 4922 4923 if (this.assistNodeInJavadoc > 0) { 4925 Expression receiver = null; 4926 if (invocationSite instanceof CompletionOnJavadocMessageSend) { 4927 CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite; 4928 receiver = msg.receiver; 4929 } else if (invocationSite instanceof CompletionOnJavadocFieldReference) { 4930 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 4931 receiver = fieldRef.receiver; 4932 } 4933 if (receiver != null) { 4934 StringBuffer javadocCompletion = new StringBuffer (); 4935 if (receiver.isThis()) { 4936 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 4937 javadocCompletion.append('#'); 4938 } 4939 } else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 4940 if (receiver instanceof JavadocSingleTypeReference) { 4941 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver; 4942 javadocCompletion.append(typeRef.token); 4943 javadocCompletion.append('#'); 4944 } else if (receiver instanceof JavadocQualifiedTypeReference) { 4945 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver; 4946 completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#'); 4947 for (int t=0,nt =typeRef.tokens.length; t<nt; t++) { 4948 if (t>0) javadocCompletion.append('.'); 4949 javadocCompletion.append(typeRef.tokens[t]); 4950 } 4951 javadocCompletion.append('#'); 4952 } 4953 } 4954 javadocCompletion.append(method.selector); 4955 javadocCompletion.append('('); 4957 if (method.parameters != null) { 4958 boolean isVarargs = method.isVarargs(); 4959 for (int p=0, ln=method.parameters.length; p<ln; p++) { 4960 if (p>0) javadocCompletion.append(", "); TypeBinding argTypeBinding = method.parameters[p]; 4962 if (isVarargs && p == ln - 1) { 4963 createVargsType(argTypeBinding.erasure(), javadocCompletion); 4964 } else { 4965 createType(argTypeBinding.erasure(), javadocCompletion); 4966 } 4967 } 4968 } 4969 javadocCompletion.append(')'); 4970 completion = javadocCompletion.toString().toCharArray(); 4971 } 4972 } else { 4973 if (!exactMatch) { 4975 if (this.source != null 4976 && this.source.length > this.endPosition 4977 && this.source[this.endPosition] == '(') 4978 completion = method.selector; 4979 else 4980 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 4981 } else { 4982 if(prefixRequired && (this.source != null)) { 4983 completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition); 4984 } else { 4985 this.startPosition = this.endPosition; 4986 } 4987 } 4988 4989 if(prefixRequired || this.options.forceImplicitQualification){ 4990 char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic()); 4991 completion = CharOperation.concat(prefix,completion,'.'); 4992 } 4993 } 4994 4995 int relevance = computeBaseRelevance(); 4996 relevance += computeRelevanceForResolution(); 4997 relevance += computeRelevanceForInterestingProposal(); 4998 if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector); 4999 relevance += computeRelevanceForExpectingType(method.returnType); 5000 relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic()); 5001 relevance += computeRelevanceForQualification(prefixRequired); 5002 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5003 if (onlyStaticMethods && this.insideQualifiedReference) { 5004 relevance += computeRelevanceForInheritance(receiverType, method.declaringClass); 5005 } 5006 if (missingElements != null) { 5007 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 5008 } 5009 5010 this.noProposal = false; 5011 if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 5013 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 5014 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5015 proposal.setSignature(getSignature(method)); 5016 MethodBinding original = method.original(); 5017 if(original != method) { 5018 proposal.setOriginalSignature(getSignature(original)); 5019 } 5020 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5021 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5022 proposal.setParameterPackageNames(parameterPackageNames); 5023 proposal.setParameterTypeNames(parameterTypeNames); 5024 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5025 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5026 proposal.setName(method.selector); 5027 if (missingElements != null) { 5028 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 5029 for (int i = 0; i < missingElements.length; i++) { 5030 subProposals[i] = 5031 createRequiredTypeProposal( 5032 missingElements[i], 5033 missingElementsStarts[i], 5034 missingElementsEnds[i], 5035 relevance); 5036 } 5037 proposal.setRequiredProposals(subProposals); 5038 } 5039 proposal.setCompletion(completion); 5040 proposal.setFlags(method.modifiers); 5041 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5042 proposal.setRelevance(relevance); 5043 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5044 this.requestor.accept(proposal); 5045 if(DEBUG) { 5046 this.printDebug(proposal); 5047 } 5048 } 5049 5050 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 5052 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 5053 CompletionProposal proposal = this.createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition); 5054 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5055 proposal.setSignature(getSignature(method)); 5056 MethodBinding original = method.original(); 5057 if(original != method) { 5058 proposal.setOriginalSignature(getSignature(original)); 5059 } 5060 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5061 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5062 proposal.setParameterPackageNames(parameterPackageNames); 5063 proposal.setParameterTypeNames(parameterTypeNames); 5064 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5065 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5066 proposal.setName(method.selector); 5067 proposal.setCompletion(javadocCompletion); 5068 proposal.setFlags(method.modifiers); 5069 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 5070 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 5071 proposal.setRelevance(relevance+R_INLINE_TAG); 5072 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5073 this.requestor.accept(proposal); 5074 if(DEBUG) { 5075 this.printDebug(proposal); 5076 } 5077 } 5078 this.startPosition = previousStartPosition; 5079 } 5080 5081 methodsFound.addAll(newMethodsFound); 5082 } 5083 5084 private void findLocalMethodsFromFavorites( 5085 char[] methodName, 5086 MethodBinding[] methods, 5087 Scope scope, 5088 ObjectVector methodsFound, 5089 ReferenceBinding receiverType, 5090 InvocationSite invocationSite, 5091 Scope invocationScope) { 5092 5093 char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.'); 5094 5095 int methodLength = methodName.length; 5096 5097 next : for (int f = methods.length; --f >= 0;) { 5098 MethodBinding method = methods[f]; 5099 5100 if (method.isSynthetic()) continue next; 5101 5102 if (method.isDefaultAbstract()) continue next; 5103 5104 if (method.isConstructor()) continue next; 5105 5106 if (this.options.checkDeprecation && 5107 method.isViewedAsDeprecated() && 5108 !scope.isDefinedInSameUnit(method.declaringClass)) 5109 continue next; 5110 5111 if (!method.isStatic()) continue next; 5112 5113 if (this.options.checkVisibility 5114 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 5115 5116 if (methodLength > method.selector.length) continue next; 5117 5118 if (!CharOperation.prefixEquals(methodName, method.selector, false ) 5119 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) { 5120 continue next; 5121 } 5122 5123 for (int i = methodsFound.size; --i >= 0;) { 5124 Object [] other = (Object []) methodsFound.elementAt(i); 5125 MethodBinding otherMethod = (MethodBinding) other[0]; 5126 5127 if (method == otherMethod) continue next; 5128 5129 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 5130 if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) { 5131 continue next; 5132 } 5133 } 5134 } 5135 5136 boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) && 5137 this.options.suggestStaticImport; 5138 5139 boolean isAlreadyImported = false; 5140 if (!proposeStaticImport) { 5141 if(!this.importCachesInitialized) { 5142 this.initializeImportCaches(); 5143 } 5144 for (int j = 0; j < this.importCacheCount; j++) { 5145 char[][] importName = this.importsCache[j]; 5146 if(CharOperation.equals(receiverType.sourceName, importName[0])) { 5147 if (!CharOperation.equals(typeName, importName[1])) { 5148 continue next; 5149 } else { 5150 isAlreadyImported = true; 5151 } 5152 } 5153 } 5154 } 5155 5156 methodsFound.add(new Object []{method, receiverType}); 5157 5158 ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeWithSameErasure(method.declaringClass); 5159 if (method.declaringClass != superTypeWithSameErasure) { 5160 MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector); 5161 for (int i = 0; i < otherMethods.length; i++) { 5162 if(otherMethods[i].original() == method.original()) { 5163 method = otherMethods[i]; 5164 } 5165 } 5166 } 5167 5168 int length = method.parameters.length; 5169 char[][] parameterPackageNames = new char[length][]; 5170 char[][] parameterTypeNames = new char[length][]; 5171 5172 for (int i = 0; i < length; i++) { 5173 TypeBinding type = method.original().parameters[i]; 5174 parameterPackageNames[i] = type.qualifiedPackageName(); 5175 parameterTypeNames[i] = type.qualifiedSourceName(); 5176 } 5177 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 5178 5179 char[] completion = CharOperation.NO_CHAR; 5180 5181 int previousStartPosition = this.startPosition; 5182 5183 if (this.source != null 5184 && this.source.length > this.endPosition 5185 && this.source[this.endPosition] == '(') { 5186 completion = method.selector; 5187 } else { 5188 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 5189 } 5190 5191 int relevance = computeBaseRelevance(); 5192 relevance += computeRelevanceForResolution(); 5193 relevance += computeRelevanceForInterestingProposal(); 5194 if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector); 5195 relevance += computeRelevanceForExpectingType(method.returnType); 5196 relevance += computeRelevanceForStatic(true, method.isStatic()); 5197 relevance += computeRelevanceForQualification(true); 5198 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5199 5200 CompilationUnitDeclaration cu = this.unitScope.referenceContext; 5201 int importStart = cu.types[0].declarationSourceStart; 5202 int importEnd = importStart; 5203 5204 this.noProposal = false; 5205 5206 if (!proposeStaticImport) { 5207 if (isAlreadyImported) { 5208 if (!isIgnored(CompletionProposal.METHOD_REF)) { 5209 completion = CharOperation.concat(receiverType.sourceName, completion, '.'); 5210 5211 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 5212 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5213 proposal.setSignature(getSignature(method)); 5214 MethodBinding original = method.original(); 5215 if(original != method) { 5216 proposal.setOriginalSignature(getSignature(original)); 5217 } 5218 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5219 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5220 proposal.setParameterPackageNames(parameterPackageNames); 5221 proposal.setParameterTypeNames(parameterTypeNames); 5222 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5223 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5224 proposal.setName(method.selector); 5225 proposal.setCompletion(completion); 5226 proposal.setFlags(method.modifiers); 5227 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5228 proposal.setRelevance(relevance); 5229 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5230 5231 this.requestor.accept(proposal); 5232 if(DEBUG) { 5233 this.printDebug(proposal); 5234 } 5235 } 5236 } else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) { 5237 completion = CharOperation.concat(receiverType.sourceName, completion, '.'); 5238 5239 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 5240 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5241 proposal.setSignature(getSignature(method)); 5242 MethodBinding original = method.original(); 5243 if(original != method) { 5244 proposal.setOriginalSignature(getSignature(original)); 5245 } 5246 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5247 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5248 proposal.setParameterPackageNames(parameterPackageNames); 5249 proposal.setParameterTypeNames(parameterTypeNames); 5250 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5251 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5252 proposal.setName(method.selector); 5253 proposal.setCompletion(completion); 5254 proposal.setFlags(method.modifiers); 5255 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5256 proposal.setRelevance(relevance); 5257 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5258 5259 char[] typeImportCompletion = createImportCharArray(typeName, false, false); 5260 5261 CompletionProposal typeImportProposal = this.createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition); 5262 typeImportProposal.nameLookup = this.nameEnvironment.nameLookup; 5263 typeImportProposal.completionEngine = this; 5264 char[] packageName = receiverType.qualifiedPackageName(); 5265 typeImportProposal.setDeclarationSignature(packageName); 5266 typeImportProposal.setSignature(getSignature(receiverType)); 5267 typeImportProposal.setPackageName(packageName); 5268 typeImportProposal.setTypeName(receiverType.qualifiedSourceName()); 5269 typeImportProposal.setCompletion(typeImportCompletion); 5270 typeImportProposal.setFlags(receiverType.modifiers); 5271 typeImportProposal.setAdditionalFlags(CompletionFlags.Default); 5272 typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 5273 typeImportProposal.setRelevance(relevance); 5274 5275 proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal}); 5276 5277 this.requestor.accept(proposal); 5278 if(DEBUG) { 5279 this.printDebug(proposal); 5280 } 5281 } 5282 } else { 5283 if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) { 5284 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 5285 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5286 proposal.setSignature(getSignature(method)); 5287 MethodBinding original = method.original(); 5288 if(original != method) { 5289 proposal.setOriginalSignature(getSignature(original)); 5290 } 5291 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5292 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5293 proposal.setParameterPackageNames(parameterPackageNames); 5294 proposal.setParameterTypeNames(parameterTypeNames); 5295 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5296 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5297 proposal.setName(method.selector); 5298 proposal.setCompletion(completion); 5299 proposal.setFlags(method.modifiers); 5300 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5301 proposal.setRelevance(relevance); 5302 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5303 5304 char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false); 5305 5306 CompletionProposal methodImportProposal = this.createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition); 5307 methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass)); 5308 methodImportProposal.setSignature(getSignature(method)); 5309 if(original != method) { 5310 proposal.setOriginalSignature(getSignature(original)); 5311 } 5312 methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5313 methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5314 methodImportProposal.setParameterPackageNames(parameterPackageNames); 5315 methodImportProposal.setParameterTypeNames(parameterTypeNames); 5316 methodImportProposal.setPackageName(method.returnType.qualifiedPackageName()); 5317 methodImportProposal.setTypeName(method.returnType.qualifiedSourceName()); 5318 methodImportProposal.setName(method.selector); 5319 methodImportProposal.setCompletion(methodImportCompletion); 5320 methodImportProposal.setFlags(method.modifiers); 5321 methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport); 5322 methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 5323 methodImportProposal.setRelevance(relevance); 5324 if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames); 5325 5326 proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal}); 5327 5328 this.requestor.accept(proposal); 5329 if(DEBUG) { 5330 this.printDebug(proposal); 5331 } 5332 } 5333 } 5334 5335 this.startPosition = previousStartPosition; 5336 } 5337 } 5338 5339 private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) { 5340 CompletionProposal proposal = null; 5341 if (binding instanceof ReferenceBinding) { 5342 ReferenceBinding typeBinding = (ReferenceBinding) binding; 5343 5344 char[] packageName = typeBinding.qualifiedPackageName(); 5345 char[] typeName = typeBinding.qualifiedSourceName(); 5346 char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.'); 5347 5348 proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 5349 proposal.nameLookup = this.nameEnvironment.nameLookup; 5350 proposal.completionEngine = this; 5351 proposal.setDeclarationSignature(packageName); 5352 proposal.setSignature(getSignature(typeBinding)); 5353 proposal.setPackageName(packageName); 5354 proposal.setTypeName(typeName); 5355 proposal.setCompletion(fullyQualifiedName); 5356 proposal.setFlags(typeBinding.modifiers); 5357 proposal.setReplaceRange(start - this.offset, end - this.offset); 5358 proposal.setRelevance(relevance); 5359 } else if (binding instanceof PackageBinding) { 5360 PackageBinding packageBinding = (PackageBinding) binding; 5361 5362 char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.'); 5363 5364 proposal = this.createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition); 5365 proposal.setDeclarationSignature(packageName); 5366 proposal.setPackageName(packageName); 5367 proposal.setCompletion(packageName); 5368 proposal.setReplaceRange(start - this.offset, end - this.offset); 5369 proposal.setRelevance(relevance); 5370 } 5371 return proposal; 5372 } 5373 5374 private void findLocalMethodsOfStaticImports( 5376 char[] methodName, 5377 MethodBinding[] methods, 5378 Scope scope, 5379 ObjectVector methodsFound, 5380 ReferenceBinding receiverType, 5381 InvocationSite invocationSite) { 5382 5383 ObjectVector newMethodsFound = new ObjectVector(); 5384 5385 next : for (int f = methods.length; --f >= 0;) { 5386 MethodBinding method = methods[f]; 5387 5388 if (method.isSynthetic()) continue next; 5389 5390 if (method.isDefaultAbstract()) continue next; 5391 5392 if (method.isConstructor()) continue next; 5393 5394 if (!method.isStatic()) continue next; 5395 5396 if (this.options.checkDeprecation && 5397 method.isViewedAsDeprecated() && 5398 !scope.isDefinedInSameUnit(method.declaringClass)) 5399 continue next; 5400 5401 if (this.options.checkVisibility 5402 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 5403 5404 if (!CharOperation.equals(methodName, method.selector, false ) 5405 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) 5406 continue next; 5407 5408 for (int i = methodsFound.size; --i >= 0;) { 5409 Object [] other = (Object []) methodsFound.elementAt(i); 5410 MethodBinding otherMethod = (MethodBinding) other[0]; 5411 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 5412 if (method == otherMethod && receiverType == otherReceiverType) 5413 continue next; 5414 5415 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 5416 if (lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) { 5417 continue next; 5418 } 5419 } 5420 } 5421 5422 newMethodsFound.add(new Object []{method, receiverType}); 5423 5424 int length = method.parameters.length; 5425 char[][] parameterPackageNames = new char[length][]; 5426 char[][] parameterTypeNames = new char[length][]; 5427 5428 for (int i = 0; i < length; i++) { 5429 TypeBinding type = method.original().parameters[i]; 5430 parameterPackageNames[i] = type.qualifiedPackageName(); 5431 parameterTypeNames[i] = type.qualifiedSourceName(); 5432 } 5433 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 5434 5435 char[] completion = CharOperation.NO_CHAR; 5436 5437 int previousStartPosition = this.startPosition; 5438 5439 if (this.source != null 5441 && this.source.length > this.endPosition 5442 && this.source[this.endPosition] == '(') { 5443 completion = method.selector; 5444 } else { 5445 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 5446 } 5447 5448 int relevance = computeBaseRelevance(); 5449 relevance += computeRelevanceForResolution(); 5450 relevance += computeRelevanceForInterestingProposal(); 5451 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 5452 relevance += computeRelevanceForExpectingType(method.returnType); 5453 relevance += computeRelevanceForStatic(true, method.isStatic()); 5454 relevance += computeRelevanceForQualification(false); 5455 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5456 5457 this.noProposal = false; 5458 if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 5459 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 5460 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5461 proposal.setSignature(getSignature(method)); 5462 MethodBinding original = method.original(); 5463 if(original != method) { 5464 proposal.setOriginalSignature(getSignature(original)); 5465 } 5466 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5467 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5468 proposal.setParameterPackageNames(parameterPackageNames); 5469 proposal.setParameterTypeNames(parameterTypeNames); 5470 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5471 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5472 proposal.setName(method.selector); 5473 proposal.setCompletion(completion); 5474 proposal.setFlags(method.modifiers); 5475 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5476 proposal.setRelevance(relevance); 5477 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5478 this.requestor.accept(proposal); 5479 if(DEBUG) { 5480 this.printDebug(proposal); 5481 } 5482 } 5483 this.startPosition = previousStartPosition; 5484 } 5485 5486 methodsFound.addAll(newMethodsFound); 5487 } 5488 int computeRelevanceForCaseMatching(char[] token, char[] proposalName){ 5489 if (this.options.camelCaseMatch) { 5490 if(CharOperation.equals(token, proposalName, true )) { 5491 return R_CASE + R_EXACT_NAME; 5492 } else if (CharOperation.prefixEquals(token, proposalName, true )) { 5493 return R_CASE; 5494 } else if (CharOperation.camelCaseMatch(token, proposalName)){ 5495 return R_CAMEL_CASE; 5496 } else if(CharOperation.equals(token, proposalName, false )) { 5497 return R_EXACT_NAME; 5498 } 5499 } else if (CharOperation.prefixEquals(token, proposalName, true )) { 5500 if(CharOperation.equals(token, proposalName, true )) { 5501 return R_CASE + R_EXACT_NAME; 5502 } else { 5503 return R_CASE; 5504 } 5505 } else if(CharOperation.equals(token, proposalName, false )) { 5506 return R_EXACT_NAME; 5507 } 5508 return 0; 5509 } 5510 private int computeRelevanceForAnnotation(){ 5511 if(this.assistNodeIsAnnotation) { 5512 return R_ANNOTATION; 5513 } 5514 return 0; 5515 } 5516 private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){ 5517 if (this.assistNodeIsAnnotation && 5518 (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) { 5519 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 5520 if(target == 0 || (target & this.targetedElement) != 0) { 5521 return R_TARGET; 5522 } 5523 } 5524 return 0; 5525 } 5526 private int computeRelevanceForClass(){ 5527 if(this.assistNodeIsClass) { 5528 return R_CLASS; 5529 } 5530 return 0; 5531 } 5532 private int computeRelevanceForEnum(){ 5533 if(this.assistNodeIsEnum) { 5534 return R_ENUM; 5535 } 5536 return 0; 5537 } 5538 private int computeRelevanceForInterface(){ 5539 if(this.assistNodeIsInterface) { 5540 return R_INTERFACE; 5541 } 5542 return 0; 5543 } 5544 private int computeRelevanceForMissingElements(boolean hasProblems) { 5545 if (!hasProblems) { 5546 return R_NO_PROBLEMS; 5547 } 5548 return 0; 5549 } 5550 int computeRelevanceForQualification(boolean prefixRequired) { 5551 if(!prefixRequired && !this.insideQualifiedReference) { 5552 return R_UNQUALIFIED; 5553 } 5554 5555 if(prefixRequired && this.insideQualifiedReference) { 5556 return R_QUALIFIED; 5557 } 5558 return 0; 5559 } 5560 int computeRelevanceForRestrictions(int accessRuleKind) { 5561 if(accessRuleKind == IAccessRule.K_ACCESSIBLE) { 5562 return R_NON_RESTRICTED; 5563 } 5564 return 0; 5565 } 5566 private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) { 5567 if(this.insideQualifiedReference && !onlyStatic && !isStatic) { 5568 return R_NON_STATIC; 5569 } 5570 return 0; 5571 } 5572 private int computeRelevanceForException(){ 5573 if (this.assistNodeIsException) { 5574 return R_EXCEPTION; 5575 } 5576 return 0; 5577 } 5578 private int computeRelevanceForException(char[] proposalName){ 5579 5580 if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&& 5581 (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) || 5582 CharOperation.match(ERROR_PATTERN, proposalName, false))) { 5583 return R_EXCEPTION; 5584 } 5585 return 0; 5586 } 5587 private int computeRelevanceForExpectingType(TypeBinding proposalType){ 5588 if(this.expectedTypes != null && proposalType != null) { 5589 for (int i = 0; i <= this.expectedTypesPtr; i++) { 5590 int relevance = R_EXPECTED_TYPE; 5591 if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) && 5592 CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) { 5593 relevance = R_EXACT_EXPECTED_TYPE; 5594 } 5595 if((this.expectedTypesFilter & SUBTYPE) != 0 5596 && proposalType.isCompatibleWith(this.expectedTypes[i])) { 5597 return relevance; 5598 } 5599 if((this.expectedTypesFilter & SUPERTYPE) != 0 5600 && this.expectedTypes[i].isCompatibleWith(proposalType)) { 5601 return relevance; 5602 } 5603 } 5604 } 5605 return 0; 5606 } 5607 private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){ 5608 if(this.expectedTypes != null) { 5609 for (int i = 0; i <= this.expectedTypesPtr; i++) { 5610 if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) && 5611 CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) { 5612 return R_EXACT_EXPECTED_TYPE; 5613 } 5614 } 5615 if(this.hasJavaLangObjectAsExpectedType) { 5616 return R_EXPECTED_TYPE; 5617 } 5618 } 5619 return 0; 5620 } 5621 5622 private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) { 5623 if (receiverType == declaringClass) return R_NON_INHERITED; 5624 return 0; 5625 } 5626 5627 int computeRelevanceForInterestingProposal(){ 5628 return computeRelevanceForInterestingProposal(null); 5629 } 5630 private int computeRelevanceForInterestingProposal(Binding binding){ 5631 if(this.uninterestingBindings != null) { 5632 for (int i = 0; i <= this.uninterestingBindingsPtr; i++) { 5633 if(this.uninterestingBindings[i] == binding) { 5634 return 0; 5635 } 5636 } 5637 } 5638 return R_INTERESTING; 5639 } 5640 private void computeUninterestingBindings(ASTNode parent, Scope scope){ 5641 if(parent instanceof LocalDeclaration) { 5642 addUninterestingBindings(((LocalDeclaration)parent).binding); 5643 } else if (parent instanceof FieldDeclaration) { 5644 addUninterestingBindings(((FieldDeclaration)parent).binding); 5645 } 5646 } 5647 5648 private void findLabels(char[] label, char[][] choices) { 5649 if(choices == null || choices.length == 0) return; 5650 5651 int length = label.length; 5652 for (int i = 0; i < choices.length; i++) { 5653 if (length <= choices[i].length 5654 && CharOperation.prefixEquals(label, choices[i], false 5655 )){ 5656 int relevance = computeBaseRelevance(); 5657 relevance += computeRelevanceForResolution(); 5658 relevance += computeRelevanceForInterestingProposal(); 5659 relevance += computeRelevanceForCaseMatching(label, choices[i]); 5660 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5662 this.noProposal = false; 5663 if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) { 5664 CompletionProposal proposal = this.createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition); 5665 proposal.setName(choices[i]); 5666 proposal.setCompletion(choices[i]); 5667 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5668 proposal.setRelevance(relevance); 5669 this.requestor.accept(proposal); 5670 if(DEBUG) { 5671 this.printDebug(proposal); 5672 } 5673 } 5674 } 5675 } 5676 } 5677 5678 private void findLocalMethodDeclarations( 5680 char[] methodName, 5681 MethodBinding[] methods, 5682 Scope scope, 5683 ObjectVector methodsFound, 5684 boolean exactMatch, 5686 ReferenceBinding receiverType) { 5687 5688 ObjectVector newMethodsFound = new ObjectVector(); 5689 int methodLength = methodName.length; 5692 next : for (int f = methods.length; --f >= 0;) { 5693 5694 MethodBinding method = methods[f]; 5695 if (method.isSynthetic()) continue next; 5696 5697 if (method.isDefaultAbstract()) continue next; 5698 5699 if (method.isConstructor()) continue next; 5700 5701 if (method.isFinal()) { 5702 newMethodsFound.add(method); 5703 continue next; 5704 } 5705 5706 if (this.options.checkDeprecation && 5707 method.isViewedAsDeprecated() && 5708 !scope.isDefinedInSameUnit(method.declaringClass)) 5709 continue next; 5710 5711 if(method.isStatic()) continue next; 5713 5714 if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next; 5715 5716 if (exactMatch) { 5717 if (!CharOperation.equals(methodName, method.selector, false 5718 )) 5719 continue next; 5720 5721 } else { 5722 5723 if (methodLength > method.selector.length) 5724 continue next; 5725 5726 if (!CharOperation.prefixEquals(methodName, method.selector, false) 5727 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) 5728 continue next; 5729 } 5730 5731 for (int i = methodsFound.size; --i >= 0;) { 5732 MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i); 5733 if (method == otherMethod) 5734 continue next; 5735 5736 if (CharOperation.equals(method.selector, otherMethod.selector, true) 5737 && lookupEnvironment.methodVerifier().doesMethodOverride(otherMethod, method)) { 5738 continue next; 5739 } 5740 } 5741 5742 newMethodsFound.add(method); 5743 5744 int length = method.parameters.length; 5745 char[][] parameterPackageNames = new char[length][]; 5746 char[][] parameterFullTypeNames = new char[length][]; 5747 5748 for (int i = 0; i < length; i++) { 5749 TypeBinding type = method.parameters[i]; 5750 parameterPackageNames[i] = type.qualifiedPackageName(); 5751 parameterFullTypeNames[i] = type.qualifiedSourceName(); 5752 } 5753 5754 char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames); 5755 5756 if(method.typeVariables != null && method.typeVariables.length > 0) { 5757 char[][] excludedNames = findEnclosingTypeNames(scope); 5758 char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames); 5759 if(substituedParameterNames != null) { 5760 method = new ParameterizedMethodBinding( 5761 method.declaringClass, 5762 method, 5763 substituedParameterNames, 5764 scope.environment()); 5765 } 5766 } 5767 5768 StringBuffer completion = new StringBuffer (10); 5769 if (!exactMatch) { 5770 createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, completion); 5771 } 5772 5773 int relevance = computeBaseRelevance(); 5774 relevance += computeRelevanceForResolution(); 5775 relevance += computeRelevanceForInterestingProposal(); 5776 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 5777 relevance += R_METHOD_OVERIDE; 5778 if(method.isAbstract()) relevance += R_ABSTRACT_METHOD; 5779 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5780 5781 this.noProposal = false; 5782 if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 5783 CompletionProposal proposal = this.createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition); 5784 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5785 proposal.setDeclarationKey(method.declaringClass.computeUniqueKey()); 5786 proposal.setSignature(getSignature(method)); 5787 MethodBinding original = method.original(); 5788 if(original != method) { 5789 proposal.setOriginalSignature(getSignature(original)); 5790 } 5791 proposal.setKey(method.computeUniqueKey()); 5792 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 5793 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 5794 proposal.setParameterPackageNames(parameterPackageNames); 5795 proposal.setParameterTypeNames(parameterFullTypeNames); 5796 proposal.setPackageName(method.returnType.qualifiedPackageName()); 5797 proposal.setTypeName(method.returnType.qualifiedSourceName()); 5798 proposal.setCompletion(completion.toString().toCharArray()); 5799 proposal.setName(method.selector); 5800 proposal.setFlags(method.modifiers); 5801 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5802 proposal.setRelevance(relevance); 5803 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5804 this.requestor.accept(proposal); 5805 if(DEBUG) { 5806 this.printDebug(proposal); 5807 } 5808 } 5809 } 5810 methodsFound.addAll(newMethodsFound); 5811 } 5812 5813 private void createTypeVariable(TypeVariableBinding typeVariable, StringBuffer completion) { 5814 completion.append(typeVariable.sourceName); 5815 5816 if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) { 5817 completion.append(' '); 5818 completion.append(EXTENDS); 5819 completion.append(' '); 5820 createType(typeVariable.superclass, completion); 5821 } 5822 if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) { 5823 if (typeVariable.firstBound != typeVariable.superclass) { 5824 completion.append(' '); 5825 completion.append(EXTENDS); 5826 completion.append(' '); 5827 } 5828 for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) { 5829 if (i > 0 || typeVariable.firstBound == typeVariable.superclass) { 5830 completion.append(' '); 5831 completion.append(EXTENDS); 5832 completion.append(' '); 5833 } 5834 createType(typeVariable.superInterfaces[i], completion); 5835 } 5836 } 5837 } 5838 5839 private void createType(TypeBinding type, StringBuffer completion) { 5840 if (type.isBaseType()) { 5841 completion.append(type.sourceName()); 5842 } else if (type.isTypeVariable()) { 5843 completion.append(type.sourceName()); 5844 } else if (type.isWildcard()) { 5845 WildcardBinding wildcardBinding = (WildcardBinding) type; 5846 completion.append('?'); 5847 switch (wildcardBinding.boundKind) { 5848 case Wildcard.EXTENDS: 5849 completion.append(' '); 5850 completion.append(EXTENDS); 5851 completion.append(' '); 5852 createType(wildcardBinding.bound, completion); 5853 if(wildcardBinding.otherBounds != null) { 5854 5855 int length = wildcardBinding.otherBounds.length; 5856 for (int i = 0; i < length; i++) { 5857 completion.append(' '); 5858 completion.append('&'); 5859 completion.append(' '); 5860 createType(wildcardBinding.otherBounds[i], completion); 5861 } 5862 } 5863 break; 5864 case Wildcard.SUPER: 5865 completion.append(' '); 5866 completion.append(SUPER); 5867 completion.append(' '); 5868 createType(wildcardBinding.bound, completion); 5869 break; 5870 } 5871 } else if (type.isArrayType()) { 5872 createType(type.leafComponentType(), completion); 5873 int dim = type.dimensions(); 5874 for (int i = 0; i < dim; i++) { 5875 completion.append('['); 5876 completion.append(']'); 5877 } 5878 } else if (type.isParameterizedType()) { 5879 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type; 5880 if (type.isMemberType()) { 5881 createType(parameterizedType.enclosingType(), completion); 5882 completion.append('.'); 5883 completion.append(parameterizedType.sourceName); 5884 } else { 5885 completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.')); 5886 } 5887 if (parameterizedType.arguments != null) { 5888 completion.append('<'); 5889 for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) { 5890 if (i != 0) completion.append(','); 5891 createType(parameterizedType.arguments[i], completion); 5892 } 5893 completion.append('>'); 5894 } 5895 } else { 5896 char[] packageName = type.qualifiedPackageName(); 5897 char[] typeName = type.qualifiedSourceName(); 5898 if(mustQualifyType( 5899 packageName, 5900 type.sourceName(), 5901 type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null, 5902 ((ReferenceBinding)type).modifiers)) { 5903 completion.append(CharOperation.concat(packageName, typeName,'.')); 5904 } else { 5905 completion.append(type.sourceName()); 5906 } 5907 } 5908 } 5909 5910 private void createVargsType(TypeBinding type, StringBuffer completion) { 5911 if (type.isArrayType()) { 5912 createType(type.leafComponentType(), completion); 5913 int dim = type.dimensions() - 1; 5914 for (int i = 0; i < dim; i++) { 5915 completion.append('['); 5916 completion.append(']'); 5917 } 5918 completion.append(VARARGS); 5919 } else { 5920 createType(type, completion); 5921 } 5922 } 5923 private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) { 5924 char[] result = IMPORT; 5925 if (isStatic) { 5926 result = CharOperation.concat(result, STATIC, ' '); 5927 } 5928 result = CharOperation.concat(result, importedElement, ' '); 5929 if (onDemand) { 5930 result = CharOperation.concat(result, ON_DEMAND); 5931 } 5932 return CharOperation.concat(result, IMPORT_END); 5933 } 5934 private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, StringBuffer completion) { 5935 int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract); 5938 if(insertedModifiers != ClassFileConstants.AccDefault){ 5939 ASTNode.printModifiers(insertedModifiers, completion); 5940 } 5941 5942 5944 TypeVariableBinding[] typeVariableBindings = method.typeVariables; 5945 if(typeVariableBindings != null && typeVariableBindings.length != 0) { 5946 completion.append('<'); 5947 for (int i = 0; i < typeVariableBindings.length; i++) { 5948 if(i != 0) { 5949 completion.append(','); 5950 completion.append(' '); 5951 } 5952 createTypeVariable(typeVariableBindings[i], completion); 5953 } 5954 completion.append('>'); 5955 completion.append(' '); 5956 } 5957 5958 createType(method.returnType, completion); 5960 completion.append(' '); 5961 5962 completion.append(method.selector); 5964 5965 completion.append('('); 5966 5967 TypeBinding[] parameterTypes = method.parameters; 5969 int length = parameterTypes.length; 5970 for (int i = 0; i < length; i++) { 5971 if(i != 0) { 5972 completion.append(','); 5973 completion.append(' '); 5974 } 5975 createType(parameterTypes[i], completion); 5976 completion.append(' '); 5977 if(parameterNames != null){ 5978 completion.append(parameterNames[i]); 5979 } else { 5980 completion.append('%'); 5981 } 5982 } 5983 5984 completion.append(')'); 5985 5986 ReferenceBinding[] exceptions = method.thrownExceptions; 5988 5989 if (exceptions != null && exceptions.length > 0){ 5990 completion.append(' '); 5991 completion.append(THROWS); 5992 completion.append(' '); 5993 for(int i = 0; i < exceptions.length ; i++){ 5994 if(i != 0) { 5995 completion.append(' '); 5996 completion.append(','); 5997 } 5998 createType(exceptions[i], completion); 5999 } 6000 } 6001 } 6002 6003 private boolean isIgnored(int kind, boolean missingTypes) { 6004 return this.requestor.isIgnored(kind) || 6005 (missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF)); 6006 } 6007 6008 private boolean isIgnored(int kind) { 6009 return this.requestor.isIgnored(kind); 6010 } 6011 6012 private boolean isIgnored(int kind, int requiredProposalKind) { 6013 return this.requestor.isIgnored(kind) || 6014 !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind); 6015 } 6016 6017 private void findMethods( 6018 char[] selector, 6019 TypeBinding[] typeArgTypes, 6020 TypeBinding[] argTypes, 6021 ReferenceBinding receiverType, 6022 Scope scope, 6023 ObjectVector methodsFound, 6024 boolean onlyStaticMethods, 6025 boolean exactMatch, 6026 boolean isCompletingDeclaration, 6027 InvocationSite invocationSite, 6028 Scope invocationScope, 6029 boolean implicitCall, 6030 boolean superCall, 6031 boolean canBePrefixed, 6032 Binding[] missingElements, 6033 int[] missingElementsStarts, 6034 int[] missingElementsEnds, 6035 boolean missingElementsHaveProblems) { 6036 6037 boolean notInJavadoc = this.assistNodeInJavadoc == 0; 6038 if (selector == null && notInJavadoc) { 6039 return; 6040 } 6041 6042 if(isCompletingDeclaration) { 6043 MethodBinding[] methods = receiverType.availableMethods(); 6044 if (methods != null){ 6045 for (int i = 0; i < methods.length; i++) { 6046 if(!methods[i].isDefaultAbstract()) { 6047 methodsFound.add(methods[i]); 6048 } 6049 } 6050 } 6051 } 6052 6053 ReferenceBinding currentType = receiverType; 6054 if (notInJavadoc) { 6055 if (receiverType.isInterface()) { 6056 if (isCompletingDeclaration) { 6057 findInterfacesMethods( 6058 selector, 6059 typeArgTypes, 6060 argTypes, 6061 receiverType, 6062 currentType.superInterfaces(), 6063 scope, 6064 methodsFound, 6065 onlyStaticMethods, 6066 exactMatch, 6067 isCompletingDeclaration, 6068 invocationSite, 6069 invocationScope, 6070 implicitCall, 6071 superCall, 6072 canBePrefixed, 6073 missingElements, 6074 missingElementsStarts, 6075 missingElementsEnds, 6076 missingElementsHaveProblems); 6077 } else { 6078 findInterfacesMethods( 6079 selector, 6080 typeArgTypes, 6081 argTypes, 6082 receiverType, 6083 new ReferenceBinding[]{currentType}, 6084 scope, 6085 methodsFound, 6086 onlyStaticMethods, 6087 exactMatch, 6088 isCompletingDeclaration, 6089 invocationSite, 6090 invocationScope, 6091 implicitCall, 6092 superCall, 6093 canBePrefixed, 6094 missingElements, 6095 missingElementsStarts, 6096 missingElementsEnds, 6097 missingElementsHaveProblems); 6098 } 6099 6100 currentType = scope.getJavaLangObject(); 6101 } else { 6102 if (isCompletingDeclaration){ 6103 findInterfacesMethods( 6104 selector, 6105 typeArgTypes, 6106 argTypes, 6107 receiverType, 6108 currentType.superInterfaces(), 6109 scope, 6110 methodsFound, 6111 onlyStaticMethods, 6112 exactMatch, 6113 isCompletingDeclaration, 6114 invocationSite, 6115 invocationScope, 6116 implicitCall, 6117 superCall, 6118 canBePrefixed, 6119 missingElements, 6120 missingElementsStarts, 6121 missingElementsEnds, 6122 missingElementsHaveProblems); 6123 6124 currentType = receiverType.superclass(); 6125 } 6126 } 6127 } 6128 boolean hasPotentialDefaultAbstractMethods = true; 6129 while (currentType != null) { 6130 6131 MethodBinding[] methods = currentType.availableMethods(); 6132 if (methods != null) { 6133 if (isCompletingDeclaration){ 6134 findLocalMethodDeclarations( 6135 selector, 6136 methods, 6137 scope, 6138 methodsFound, 6139 exactMatch, 6140 receiverType); 6141 } else{ 6142 findLocalMethods( 6143 selector, 6144 typeArgTypes, 6145 argTypes, 6146 methods, 6147 scope, 6148 methodsFound, 6149 onlyStaticMethods, 6150 exactMatch, 6151 receiverType, 6152 invocationSite, 6153 invocationScope, 6154 implicitCall, 6155 superCall, 6156 canBePrefixed, 6157 missingElements, 6158 missingElementsStarts, 6159 missingElementsEnds, 6160 missingElementsHaveProblems); 6161 } 6162 } 6163 6164 if (notInJavadoc && 6165 hasPotentialDefaultAbstractMethods && 6166 (currentType.isAbstract() || currentType.isTypeVariable() || currentType.isIntersectionType())){ 6167 6168 ReferenceBinding[] superInterfaces = currentType.superInterfaces(); 6169 if (superInterfaces != null && currentType.isIntersectionType()) { 6170 for (int i = 0; i < superInterfaces.length; i++) { 6171 superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd()); 6172 } 6173 } 6174 6175 findInterfacesMethods( 6176 selector, 6177 typeArgTypes, 6178 argTypes, 6179 receiverType, 6180 superInterfaces, 6181 scope, 6182 methodsFound, 6183 onlyStaticMethods, 6184 exactMatch, 6185 isCompletingDeclaration, 6186 invocationSite, 6187 invocationScope, 6188 implicitCall, 6189 superCall, 6190 canBePrefixed, 6191 missingElements, 6192 missingElementsStarts, 6193 missingElementsEnds, 6194 missingElementsHaveProblems); 6195 } else { 6196 hasPotentialDefaultAbstractMethods = false; 6197 } 6198 if(currentType.isParameterizedType()) { 6199 currentType = ((ParameterizedTypeBinding)currentType).genericType().superclass(); 6200 } else { 6201 currentType = currentType.superclass(); 6202 } 6203 } 6204 } 6205 private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){ 6206 TypeBinding erasure = method.declaringClass.erasure(); 6207 if(!(erasure instanceof ReferenceBinding)) return null; 6208 6209 char[][] parameterNames = null; 6210 6211 int length = parameterTypeNames.length; 6212 6213 if (length == 0){ 6214 return CharOperation.NO_CHAR_CHAR; 6215 } 6216 if (erasure instanceof SourceTypeBinding){ 6218 SourceTypeBinding sourceType = (SourceTypeBinding) erasure; 6219 6220 if (sourceType.scope != null){ 6221 TypeDeclaration parsedType; 6222 6223 if ((parsedType = sourceType.scope.referenceContext) != null){ 6224 AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original()); 6225 6226 if (methodDecl != null){ 6227 Argument[] arguments = methodDecl.arguments; 6228 parameterNames = new char[length][]; 6229 6230 for(int i = 0 ; i < length ; i++){ 6231 parameterNames[i] = arguments[i].name; 6232 } 6233 } 6234 } 6235 } 6236 } 6237 if(parameterNames == null){ 6239 6240 ReferenceBinding bindingType = (ReferenceBinding)erasure; 6241 6242 char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.'); 6243 Object type = this.typeCache.get(compoundName); 6244 6245 ISourceType sourceType = null; 6246 if(type != null) { 6247 if(type instanceof ISourceType) { 6248 sourceType = (ISourceType) type; 6249 } 6250 } else { 6251 NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName); 6252 if(answer != null && answer.isSourceType()) { 6253 sourceType = answer.getSourceTypes()[0]; 6254 this.typeCache.put(compoundName, sourceType); 6255 } 6256 } 6257 6258 if(sourceType != null) { 6259 IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle(); 6260 6261 String [] parameterTypeSignatures = new String [length]; 6262 for (int i = 0; i < length; i++) { 6263 parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false); 6264 } 6265 IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures); 6266 IMethod[] foundMethods = typeHandle.findMethods(searchedMethod); 6267 6268 if(foundMethods != null) { 6269 int len = foundMethods.length; 6270 if(len == 1) { 6271 try { 6272 SourceMethod sourceMethod = (SourceMethod) foundMethods[0]; 6273 parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames(); 6274 } catch (JavaModelException e) { 6275 } 6277 } 6278 } 6279 } 6280 } 6281 return parameterNames; 6282 } 6283 6284 private void findNestedTypes( 6285 char[] typeName, 6286 SourceTypeBinding currentType, 6287 Scope scope, 6288 boolean proposeAllMemberTypes, 6289 ObjectVector typesFound) { 6290 if (typeName == null) 6291 return; 6292 6293 int typeLength = typeName.length; 6294 6295 SourceTypeBinding nextTypeToIgnore = null; 6296 while (scope != null) { 6298 switch (scope.kind) { 6299 6300 case Scope.METHOD_SCOPE : 6301 case Scope.BLOCK_SCOPE : 6302 BlockScope blockScope = (BlockScope) scope; 6303 6304 next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) { 6305 6306 if (blockScope.subscopes[i] instanceof ClassScope) { 6307 SourceTypeBinding localType = 6308 ((ClassScope) blockScope.subscopes[i]).referenceContext.binding; 6309 6310 if (!localType.isAnonymousType()) { 6311 if (this.isForbidden(localType)) 6312 continue next; 6313 6314 if (typeLength > localType.sourceName.length) 6315 continue next; 6316 if (!CharOperation.prefixEquals(typeName, localType.sourceName, false) 6317 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName))) 6318 continue next; 6319 6320 for (int j = typesFound.size; --j >= 0;) { 6321 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 6322 6323 if (localType == otherType) 6324 continue next; 6325 } 6326 6327 if(this.assistNodeIsClass) { 6328 if(!localType.isClass()) continue next; 6329 } else if(this.assistNodeIsInterface) { 6330 if(!localType.isInterface() && !localType.isAnnotationType()) continue next; 6331 } else if (this.assistNodeIsAnnotation) { 6332 if(!localType.isAnnotationType()) continue next; 6333 } 6334 6335 int relevance = computeBaseRelevance(); 6336 relevance += computeRelevanceForResolution(); 6337 relevance += computeRelevanceForInterestingProposal(); 6338 relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName); 6339 relevance += computeRelevanceForExpectingType(localType); 6340 relevance += computeRelevanceForException(localType.sourceName); 6341 relevance += computeRelevanceForClass(); 6342 relevance += computeRelevanceForQualification(false); 6343 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); relevance += computeRelevanceForAnnotationTarget(localType); 6345 6346 this.noProposal = false; 6347 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6348 createTypeProposal(localType, localType.sourceName, IAccessRule.K_ACCESSIBLE, localType.sourceName, relevance); 6349 } 6350 } 6351 } 6352 } 6353 break; 6354 6355 case Scope.CLASS_SCOPE : 6356 SourceTypeBinding enclosingSourceType = scope.enclosingSourceType(); 6357 findMemberTypes(typeName, enclosingSourceType, scope, currentType, false, false, false, false, proposeAllMemberTypes, nextTypeToIgnore, typesFound); 6358 nextTypeToIgnore = enclosingSourceType; 6359 if (typeLength == 0) 6360 return; break; 6362 6363 case Scope.COMPILATION_UNIT_SCOPE : 6364 return; 6365 } 6366 scope = scope.parent; 6367 } 6368 } 6369 6370 private void findPackages(CompletionOnPackageReference packageStatement) { 6371 6372 this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.'); 6373 if (this.completionToken.length == 0) 6374 return; 6375 6376 setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd); 6377 this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this); 6378 } 6379 6380 private void findParameterizedType(TypeReference ref, Scope scope) { 6381 ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType; 6382 if(refBinding != null) { 6383 if (this.options.checkDeprecation && 6384 refBinding.isViewedAsDeprecated() && 6385 !scope.isDefinedInSameUnit(refBinding)) 6386 return; 6387 6388 int accessibility = IAccessRule.K_ACCESSIBLE; 6389 if(refBinding.hasRestrictedAccess()) { 6390 AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding); 6391 if(accessRestriction != null) { 6392 switch (accessRestriction.getProblemId()) { 6393 case IProblem.ForbiddenReference: 6394 if (this.options.checkForbiddenReference) { 6395 return; 6396 } 6397 accessibility = IAccessRule.K_NON_ACCESSIBLE; 6398 break; 6399 case IProblem.DiscouragedReference: 6400 if (this.options.checkDiscouragedReference) { 6401 return; 6402 } 6403 accessibility = IAccessRule.K_DISCOURAGED; 6404 break; 6405 } 6406 } 6407 } 6408 6409 int relevance = computeBaseRelevance(); 6410 relevance += computeRelevanceForResolution(); 6411 relevance += computeRelevanceForInterestingProposal(); 6412 relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName); 6413 relevance += computeRelevanceForExpectingType(refBinding); 6414 relevance += computeRelevanceForQualification(false); 6415 relevance += computeRelevanceForRestrictions(accessibility); 6417 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6418 createTypeProposal(refBinding, refBinding.qualifiedSourceName(), IAccessRule.K_ACCESSIBLE, CharOperation.NO_CHAR, relevance); 6419 } 6420 } 6421 } 6422 private void findTypeParameters(char[] token, Scope scope) { 6423 if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return; 6424 6425 TypeParameter[] typeParameters = null; 6426 while (scope != null) { typeParameters = null; 6428 switch (scope.kind) { 6429 case Scope.METHOD_SCOPE : 6430 MethodScope methodScope = (MethodScope) scope; 6431 if(methodScope.referenceContext instanceof MethodDeclaration) { 6432 MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext; 6433 typeParameters = methodDeclaration.typeParameters; 6434 } else if(methodScope.referenceContext instanceof ConstructorDeclaration) { 6435 ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext; 6436 typeParameters = methodDeclaration.typeParameters; 6437 } 6438 break; 6439 case Scope.CLASS_SCOPE : 6440 ClassScope classScope = (ClassScope) scope; 6441 typeParameters = classScope.referenceContext.typeParameters; 6442 break; 6443 case Scope.COMPILATION_UNIT_SCOPE : 6444 return; 6445 } 6446 if(typeParameters != null) { 6447 for (int i = 0; i < typeParameters.length; i++) { 6448 int typeLength = token.length; 6449 TypeParameter typeParameter = typeParameters[i]; 6450 6451 if(typeParameter.binding == null) continue; 6452 6453 if (typeLength > typeParameter.name.length) continue; 6454 6455 if (!CharOperation.prefixEquals(token, typeParameter.name, false) 6456 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue; 6457 6458 int relevance = computeBaseRelevance(); 6459 relevance += computeRelevanceForResolution(); 6460 relevance += computeRelevanceForInterestingProposal(); 6461 relevance += computeRelevanceForCaseMatching(token, typeParameter.name); 6462 relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType); 6463 relevance += computeRelevanceForQualification(false); 6464 relevance += computeRelevanceForException(typeParameter.name); 6465 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6467 this.noProposal = false; 6468 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6469 createTypeParameterProposal(typeParameter, relevance); 6470 } 6471 } 6472 } 6473 scope = scope.parent; 6474 } 6475 } 6476 private void findTypesAndPackages(char[] token, Scope scope, ObjectVector typesFound) { 6477 6478 if (token == null) 6479 return; 6480 6481 boolean skip = false; 6483 if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) { 6484 if(!assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) { 6485 return; 6486 } 6487 skip = true; 6488 } 6489 6490 boolean proposeType = 6491 !this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 6492 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)); 6493 6494 boolean proposeAllMemberTypes = !this.assistNodeIsConstructor; 6495 6496 if (!skip && proposeType && scope.enclosingSourceType() != null) { 6497 findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound); 6498 if((!assistNodeIsConstructor && !assistNodeIsAnnotation) && this.assistNodeInJavadoc == 0) { 6499 findTypeParameters(token, scope); 6501 } 6502 } 6503 6504 boolean isEmptyPrefix = token.length == 0; 6505 6506 if (!skip && proposeType && this.unitScope != null) { 6507 ReferenceBinding outerInvocationType = scope.enclosingSourceType(); 6508 if(outerInvocationType != null) { 6509 ReferenceBinding temp = outerInvocationType.enclosingType(); 6510 while(temp != null) { 6511 outerInvocationType = temp; 6512 temp = temp.enclosingType(); 6513 } 6514 } 6515 6516 int typeLength = token.length; 6517 SourceTypeBinding[] types = this.unitScope.topLevelTypes; 6518 6519 next : for (int i = 0, length = types.length; i < length; i++) { 6520 SourceTypeBinding sourceType = types[i]; 6521 6522 if(isForbidden(sourceType)) continue next; 6523 6524 if(proposeAllMemberTypes && 6525 sourceType != outerInvocationType) { 6526 findSubMemberTypes( 6527 token, 6528 sourceType, 6529 scope, 6530 scope.enclosingSourceType(), 6531 false, 6532 false, 6533 false, 6534 typesFound); 6535 } 6536 6537 if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next; 6538 if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next; 6539 6540 if (typeLength > sourceType.sourceName.length) continue next; 6541 6542 if (!CharOperation.prefixEquals(token, sourceType.sourceName, false) 6543 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue; 6544 6545 if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) { 6546 continue next; 6547 } 6548 6549 for (int j = typesFound.size; --j >= 0;) { 6550 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 6551 6552 if (sourceType == otherType) continue next; 6553 } 6554 6555 this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this); 6556 6557 if(this.assistNodeIsClass) { 6558 if(!sourceType.isClass()) continue next; 6559 } else if(this.assistNodeIsInterface) { 6560 if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next; 6561 } else if (this.assistNodeIsAnnotation) { 6562 if(!sourceType.isAnnotationType()) continue next; 6563 } else if (isEmptyPrefix && this.assistNodeIsException) { 6564 if (sourceType.findSuperTypeErasingTo(TypeIds.T_JavaLangThrowable, true) == null) { 6565 continue next; 6566 } 6567 } 6568 6569 int relevance = computeBaseRelevance(); 6570 relevance += computeRelevanceForResolution(); 6571 relevance += computeRelevanceForInterestingProposal(); 6572 relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName); 6573 relevance += computeRelevanceForExpectingType(sourceType); 6574 relevance += computeRelevanceForQualification(false); 6575 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6577 if (sourceType.isAnnotationType()) { 6578 relevance += computeRelevanceForAnnotation(); 6579 relevance += computeRelevanceForAnnotationTarget(sourceType); 6580 } else if (sourceType.isInterface()) { 6581 relevance += computeRelevanceForInterface(); 6582 } else if(sourceType.isClass()){ 6583 relevance += computeRelevanceForClass(); 6584 relevance += computeRelevanceForException(sourceType.sourceName); 6585 } 6586 this.noProposal = false; 6587 if(proposeType) { 6588 char[] typeName = sourceType.sourceName(); 6589 createTypeProposal(sourceType, typeName, IAccessRule.K_ACCESSIBLE, typeName, relevance); 6590 } 6591 } 6592 } 6593 6594 if(!skip && proposeType) { 6595 this.findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound); 6596 } 6597 6598 if (isEmptyPrefix && !this.assistNodeIsAnnotation) { 6599 if(proposeType && this.expectedTypesPtr > -1) { 6600 next : for (int i = 0; i <= this.expectedTypesPtr; i++) { 6601 if(this.expectedTypes[i] instanceof ReferenceBinding) { 6602 ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i]; 6603 6604 if(refBinding.isTypeVariable() && assistNodeIsConstructor) { 6605 continue next; 6607 } 6608 if (this.options.checkDeprecation && 6609 refBinding.isViewedAsDeprecated() && 6610 !scope.isDefinedInSameUnit(refBinding)) 6611 continue next; 6612 6613 int accessibility = IAccessRule.K_ACCESSIBLE; 6614 if(refBinding.hasRestrictedAccess()) { 6615 AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(refBinding); 6616 if(accessRestriction != null) { 6617 switch (accessRestriction.getProblemId()) { 6618 case IProblem.ForbiddenReference: 6619 if (this.options.checkForbiddenReference) { 6620 continue next; 6621 } 6622 accessibility = IAccessRule.K_NON_ACCESSIBLE; 6623 break; 6624 case IProblem.DiscouragedReference: 6625 if (this.options.checkDiscouragedReference) { 6626 continue next; 6627 } 6628 accessibility = IAccessRule.K_DISCOURAGED; 6629 break; 6630 } 6631 } 6632 } 6633 6634 for (int j = 0; j < typesFound.size(); j++) { 6635 ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j); 6636 if (typeFound == refBinding) { 6637 continue next; 6638 } 6639 } 6640 6641 boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding); 6642 6643 if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) { 6645 char[] packageName = refBinding.qualifiedPackageName(); 6646 char[] typeName = refBinding.sourceName(); 6647 char[] completionName = typeName; 6648 6649 boolean isQualified = false; 6650 if (!this.insideQualifiedReference && !refBinding.isMemberType()) { 6651 if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) { 6652 if (packageName == null || packageName.length == 0) 6653 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 6654 continue next; completionName = CharOperation.concat(packageName, typeName, '.'); 6656 isQualified = true; 6657 } 6658 } 6659 6660 if(this.assistNodeIsClass) { 6661 if(!refBinding.isClass()) continue next; 6662 } else if(this.assistNodeIsInterface) { 6663 if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next; 6664 } else if (this.assistNodeIsAnnotation) { 6665 if(!refBinding.isAnnotationType()) continue next; 6666 } 6667 6668 int relevance = computeBaseRelevance(); 6669 relevance += computeRelevanceForResolution(); 6670 relevance += computeRelevanceForInterestingProposal(); 6671 relevance += computeRelevanceForCaseMatching(token, typeName); 6672 relevance += computeRelevanceForExpectingType(refBinding); 6673 relevance += computeRelevanceForQualification(isQualified); 6674 relevance += computeRelevanceForRestrictions(accessibility); 6675 6676 if(refBinding.isClass()) { 6677 relevance += computeRelevanceForClass(); 6678 relevance += computeRelevanceForException(typeName); 6679 } else if(refBinding.isEnum()) { 6680 relevance += computeRelevanceForEnum(); 6681 } else if(refBinding.isInterface()) { 6682 relevance += computeRelevanceForInterface(); 6683 } 6684 6685 this.noProposal = false; 6686 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6687 CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 6688 proposal.setDeclarationSignature(packageName); 6689 proposal.setSignature(getSignature(refBinding)); 6690 proposal.setPackageName(packageName); 6691 proposal.setTypeName(typeName); 6692 proposal.setCompletion(completionName); 6693 proposal.setFlags(refBinding.modifiers); 6694 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6695 proposal.setRelevance(relevance); 6696 proposal.setAccessibility(accessibility); 6697 this.requestor.accept(proposal); 6698 if(DEBUG) { 6699 this.printDebug(proposal); 6700 } 6701 } 6702 } 6703 } 6704 } 6705 } 6706 } else { 6707 if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 6708 if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) { 6709 findKeywords(token, BASE_TYPE_NAMES, false, false); 6710 } 6711 } 6712 if(proposeType) { 6713 int l = typesFound.size(); 6714 for (int i = 0; i < l; i++) { 6715 ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i); 6716 char[] fullyQualifiedTypeName = 6717 CharOperation.concat( 6718 typeFound.qualifiedPackageName(), 6719 typeFound.qualifiedSourceName(), 6720 '.'); 6721 this.knownTypes.put(fullyQualifiedTypeName, this); 6722 } 6723 int searchFor = IJavaSearchConstants.TYPE; 6724 if(this.assistNodeIsClass) { 6725 searchFor = IJavaSearchConstants.CLASS; 6726 } else if(this.assistNodeIsInterface) { 6727 searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION; 6728 } else if(this.assistNodeIsEnum) { 6729 searchFor = IJavaSearchConstants.ENUM; 6730 } else if(this.assistNodeIsAnnotation) { 6731 searchFor = IJavaSearchConstants.ANNOTATION_TYPE; 6732 } 6733 this.nameEnvironment.findTypes( 6734 token, 6735 proposeAllMemberTypes, 6736 this.options.camelCaseMatch, 6737 searchFor, 6738 this); 6739 acceptTypes(scope); 6740 } 6741 if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 6742 this.nameEnvironment.findPackages(token, this); 6743 } 6744 } 6745 } 6746 6747 private void findTypesAndSubpackages( 6748 char[] token, 6749 PackageBinding packageBinding, 6750 Scope scope) { 6751 6752 boolean proposeType = 6753 !this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 6754 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)); 6755 6756 char[] qualifiedName = 6757 CharOperation.concatWith(packageBinding.compoundName, token, '.'); 6758 6759 if (token == null || token.length == 0) { 6760 int length = qualifiedName.length; 6761 System.arraycopy( 6762 qualifiedName, 6763 0, 6764 qualifiedName = new char[length + 1], 6765 0, 6766 length); 6767 qualifiedName[length] = '.'; 6768 } 6769 6770 this.qualifiedCompletionToken = qualifiedName; 6771 6772 if (proposeType && this.unitScope != null) { 6773 int typeLength = qualifiedName.length; 6774 SourceTypeBinding[] types = this.unitScope.topLevelTypes; 6775 6776 for (int i = 0, length = types.length; i < length; i++) { 6777 SourceTypeBinding sourceType = types[i]; 6778 6779 char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.'); 6780 6781 if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue; 6782 if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue; 6783 if (typeLength > qualifiedSourceTypeName.length) continue; 6784 if (!(packageBinding == sourceType.getPackage())) continue; 6785 6786 if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false) 6787 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue; 6788 6789 if (this.options.checkDeprecation && 6790 sourceType.isViewedAsDeprecated() && 6791 !scope.isDefinedInSameUnit(sourceType)) 6792 continue; 6793 6794 int accessibility = IAccessRule.K_ACCESSIBLE; 6795 if(sourceType.hasRestrictedAccess()) { 6796 AccessRestriction accessRestriction = lookupEnvironment.getAccessRestriction(sourceType); 6797 if(accessRestriction != null) { 6798 switch (accessRestriction.getProblemId()) { 6799 case IProblem.ForbiddenReference: 6800 if (this.options.checkForbiddenReference) { 6801 continue; 6802 } 6803 accessibility = IAccessRule.K_NON_ACCESSIBLE; 6804 break; 6805 case IProblem.DiscouragedReference: 6806 if (this.options.checkDiscouragedReference) { 6807 continue; 6808 } 6809 accessibility = IAccessRule.K_DISCOURAGED; 6810 break; 6811 } 6812 } 6813 } 6814 6815 this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this); 6816 6817 int relevance = computeBaseRelevance(); 6818 relevance += computeRelevanceForResolution(); 6819 relevance += computeRelevanceForInterestingProposal(); 6820 relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName); 6821 relevance += computeRelevanceForExpectingType(sourceType); 6822 relevance += computeRelevanceForQualification(false); 6823 relevance += computeRelevanceForRestrictions(accessibility); 6824 6825 if (sourceType.isAnnotationType()) { 6826 relevance += computeRelevanceForAnnotation(); 6827 } else if (sourceType.isInterface()) { 6828 relevance += computeRelevanceForInterface(); 6829 } else if (sourceType.isClass()) { 6830 relevance += computeRelevanceForClass(); 6831 relevance += computeRelevanceForException(sourceType.sourceName); 6832 } 6833 this.noProposal = false; 6834 if(proposeType) { 6835 char[] typeName = sourceType.sourceName(); 6836 createTypeProposal(sourceType, typeName, IAccessRule.K_ACCESSIBLE, typeName, relevance); 6837 } 6838 } 6839 } 6840 6841 if(proposeType) { 6842 int searchFor = IJavaSearchConstants.TYPE; 6843 if(this.assistNodeIsClass) { 6844 searchFor = IJavaSearchConstants.CLASS; 6845 } else if(this.assistNodeIsInterface) { 6846 searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION; 6847 } else if(this.assistNodeIsEnum) { 6848 searchFor = IJavaSearchConstants.ENUM; 6849 } else if(this.assistNodeIsAnnotation) { 6850 searchFor = IJavaSearchConstants.ANNOTATION_TYPE; 6851 } 6852 this.nameEnvironment.findTypes( 6853 qualifiedName, 6854 false, 6855 this.options.camelCaseMatch, 6856 searchFor, 6857 this); 6858 acceptTypes(scope); 6859 } 6860 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 6861 this.nameEnvironment.findPackages(qualifiedName, this); 6862 } 6863 } 6864 6865 private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) { 6866 ImportBinding[] importBindings = scope.compilationUnitScope().imports; 6867 for (int i = 0; i < importBindings.length; i++) { 6868 ImportBinding importBinding = importBindings[i]; 6869 if(importBinding.isValidBinding() && importBinding.isStatic()) { 6870 Binding binding = importBinding.resolvedImport; 6871 if(binding != null && binding.isValidBinding()) { 6872 if(importBinding.onDemand) { 6873 if((binding.kind() & Binding.TYPE) != 0) { 6874 this.findMemberTypes( 6875 token, 6876 (ReferenceBinding) binding, 6877 scope, 6878 scope.enclosingSourceType(), 6879 true, 6880 false, 6881 true, 6882 true, 6883 proposeAllMemberTypes, 6884 null, 6885 typesFound); 6886 } 6887 } else { 6888 if ((binding.kind() & Binding.TYPE) != 0) { 6889 ReferenceBinding typeBinding = (ReferenceBinding) binding; 6890 int typeLength = token.length; 6891 6892 if (!typeBinding.isStatic()) continue; 6893 6894 if (typeLength > typeBinding.sourceName.length) continue; 6895 6896 if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false) 6897 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue; 6898 6899 if (typesFound.contains(typeBinding)) continue; 6900 6901 typesFound.add(typeBinding); 6902 6903 if(this.assistNodeIsClass) { 6904 if(!typeBinding.isClass()) continue; 6905 } else if(this.assistNodeIsInterface) { 6906 if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue; 6907 } else if (this.assistNodeIsAnnotation) { 6908 if(!typeBinding.isAnnotationType()) continue; 6909 } 6910 6911 int relevance = computeBaseRelevance(); 6912 relevance += computeRelevanceForResolution(); 6913 relevance += computeRelevanceForInterestingProposal(); 6914 relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName); 6915 relevance += computeRelevanceForExpectingType(typeBinding); 6916 relevance += computeRelevanceForQualification(false); 6917 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6918 6919 if (typeBinding.isClass()) { 6920 relevance += computeRelevanceForClass(); 6921 relevance += computeRelevanceForException(typeBinding.sourceName); 6922 } else if(typeBinding.isEnum()) { 6923 relevance += computeRelevanceForEnum(); 6924 } else if(typeBinding.isInterface()) { 6925 relevance += computeRelevanceForInterface(); 6926 } 6927 6928 this.noProposal = false; 6929 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6930 CompletionProposal proposal = this.createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 6931 proposal.setDeclarationSignature(typeBinding.qualifiedPackageName()); 6932 proposal.setSignature(getSignature(typeBinding)); 6933 proposal.setPackageName(typeBinding.qualifiedPackageName()); 6934 proposal.setTypeName(typeBinding.qualifiedSourceName()); 6935 proposal.setCompletion(typeBinding.sourceName()); 6936 proposal.setFlags(typeBinding.modifiers); 6937 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6938 proposal.setRelevance(relevance); 6939 this.requestor.accept(proposal); 6940 if(DEBUG) { 6941 this.printDebug(proposal); 6942 } 6943 } 6944 } 6945 } 6946 } 6947 } 6948 } 6949 } 6950 private void findVariablesAndMethods( 6951 char[] token, 6952 Scope scope, 6953 InvocationSite invocationSite, 6954 Scope invocationScope, 6955 boolean insideTypeAnnotation, 6956 boolean insideAnnotationAttribute) { 6957 6958 if (token == null) 6959 return; 6960 6961 6964 boolean staticsOnly = false; 6965 int tokenLength = token.length; 6967 6968 ObjectVector localsFound = new ObjectVector(); 6969 ObjectVector fieldsFound = new ObjectVector(); 6970 ObjectVector methodsFound = new ObjectVector(); 6971 6972 Scope currentScope = scope; 6973 6974 if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 6975 done1 : while (true) { 6977 switch (currentScope.kind) { 6978 6979 case Scope.METHOD_SCOPE : 6980 MethodScope methodScope = (MethodScope) currentScope; 6982 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 6983 6984 case Scope.BLOCK_SCOPE : 6985 BlockScope blockScope = (BlockScope) currentScope; 6986 6987 next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { 6988 LocalVariableBinding local = blockScope.locals[i]; 6989 6990 if (local == null) 6991 break next; 6992 6993 if (tokenLength > local.name.length) 6994 continue next; 6995 6996 if (!CharOperation.prefixEquals(token, local.name, false ) 6997 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name))) 6998 continue next; 6999 7000 if (local.isSecret()) 7001 continue next; 7002 7003 for (int f = 0; f < localsFound.size; f++) { 7004 LocalVariableBinding otherLocal = 7005 (LocalVariableBinding) localsFound.elementAt(f); 7006 if (CharOperation.equals(otherLocal.name, local.name, true)) 7007 continue next; 7008 } 7009 localsFound.add(local); 7010 7011 int relevance = computeBaseRelevance(); 7012 relevance += computeRelevanceForResolution(); 7013 relevance += computeRelevanceForInterestingProposal(local); 7014 relevance += computeRelevanceForCaseMatching(token, local.name); 7015 relevance += computeRelevanceForExpectingType(local.type); 7016 relevance += computeRelevanceForQualification(false); 7017 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); this.noProposal = false; 7019 if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 7020 CompletionProposal proposal = this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition); 7021 proposal.setSignature( 7022 local.type == null 7023 ? createTypeSignature( 7024 CharOperation.NO_CHAR, 7025 local.declaration.type.toString().toCharArray()) 7026 : getSignature(local.type)); 7027 if(local.type == null) { 7028 proposal.setTypeName(local.declaration.type.toString().toCharArray()); 7030 } else { 7031 proposal.setPackageName(local.type.qualifiedPackageName()); 7032 proposal.setTypeName(local.type.qualifiedSourceName()); 7033 } 7034 proposal.setName(local.name); 7035 proposal.setCompletion(local.name); 7036 proposal.setFlags(local.modifiers); 7037 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7038 proposal.setRelevance(relevance); 7039 this.requestor.accept(proposal); 7040 if(DEBUG) { 7041 this.printDebug(proposal); 7042 } 7043 } 7044 } 7045 break; 7046 7047 case Scope.COMPILATION_UNIT_SCOPE : 7048 break done1; 7049 } 7050 currentScope = currentScope.parent; 7051 } 7052 } 7053 7054 boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF); 7055 boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF); 7056 7057 staticsOnly = false; 7058 currentScope = scope; 7059 7060 if(proposeField || proposeMethod) { 7061 done2 : while (true) { 7063 switch (currentScope.kind) { 7064 case Scope.METHOD_SCOPE : 7065 MethodScope methodScope = (MethodScope) currentScope; 7067 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 7068 break; 7069 case Scope.CLASS_SCOPE : 7070 ClassScope classScope = (ClassScope) currentScope; 7071 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 7072 7077 if(!insideTypeAnnotation) { 7078 if(proposeField) { 7079 findFields( 7080 token, 7081 enclosingType, 7082 classScope, 7083 fieldsFound, 7084 localsFound, 7085 staticsOnly, 7086 invocationSite, 7087 invocationScope, 7088 true, 7089 true, 7090 null, 7091 null, 7092 null, 7093 false); 7094 } 7095 if(proposeMethod && !insideAnnotationAttribute) { 7096 findMethods( 7097 token, 7098 null, 7099 null, 7100 enclosingType, 7101 classScope, 7102 methodsFound, 7103 staticsOnly, 7104 false, 7105 false, 7106 invocationSite, 7107 invocationScope, 7108 true, 7109 false, 7110 true, 7111 null, 7112 null, 7113 null, 7114 false); 7115 } 7116 } 7117 staticsOnly |= enclosingType.isStatic(); 7118 insideTypeAnnotation = false; 7119 break; 7121 7122 case Scope.COMPILATION_UNIT_SCOPE : 7123 break done2; 7124 } 7125 currentScope = currentScope.parent; 7126 } 7127 7128 ImportBinding[] importBindings = scope.compilationUnitScope().imports; 7130 for (int i = 0; i < importBindings.length; i++) { 7131 ImportBinding importBinding = importBindings[i]; 7132 if(importBinding.isValidBinding() && importBinding.isStatic()) { 7133 Binding binding = importBinding.resolvedImport; 7134 if(binding != null && binding.isValidBinding()) { 7135 if(importBinding.onDemand) { 7136 if((binding.kind() & Binding.TYPE) != 0) { 7137 if(proposeField) { 7138 findFields( 7139 token, 7140 (ReferenceBinding)binding, 7141 scope, 7142 fieldsFound, 7143 localsFound, 7144 true, 7145 invocationSite, 7146 invocationScope, 7147 true, 7148 false, 7149 null, 7150 null, 7151 null, 7152 false); 7153 } 7154 if(proposeMethod && !insideAnnotationAttribute) { 7155 findMethods( 7156 token, 7157 null, 7158 null, 7159 (ReferenceBinding)binding, 7160 scope, 7161 methodsFound, 7162 true, 7163 false, 7164 false, 7165 invocationSite, 7166 invocationScope, 7167 true, 7168 false, 7169 false, 7170 null, 7171 null, 7172 null, 7173 false); 7174 } 7175 } 7176 } else { 7177 if ((binding.kind() & Binding.FIELD) != 0) { 7178 if(proposeField) { 7179 findFields( 7180 token, 7181 new FieldBinding[]{(FieldBinding)binding}, 7182 scope, 7183 fieldsFound, 7184 localsFound, 7185 true, 7186 ((FieldBinding)binding).declaringClass, 7187 invocationSite, 7188 invocationScope, 7189 true, 7190 false, 7191 null, 7192 null, 7193 null, 7194 false); 7195 } 7196 } else if ((binding.kind() & Binding.METHOD) != 0) { 7197 if(proposeMethod && !insideAnnotationAttribute) { 7198 MethodBinding methodBinding = (MethodBinding)binding; 7199 if(CharOperation.prefixEquals(token, methodBinding.selector)) 7200 7201 findLocalMethodsOfStaticImports( 7202 methodBinding.selector, 7203 methodBinding.declaringClass.methods(), 7204 scope, 7205 methodsFound, 7206 methodBinding.declaringClass, 7207 invocationSite); 7208 } 7209 } 7210 } 7211 } 7212 } 7213 } 7214 7215 if (this.assistNodeInJavadoc == 0) { 7216 findFieldsAndMethodsFromFavorites( 7218 token, 7219 scope, 7220 invocationSite, 7221 invocationScope, 7222 localsFound, 7223 fieldsFound, 7224 methodsFound); 7225 } 7226 } 7227 } 7228 private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) { 7229 final TypeReference type = variable.type; 7230 if(type != null && 7231 type.resolvedType != null && 7232 type.resolvedType.problemId() == ProblemReasons.NoError){ 7233 7234 final ArrayList proposedNames = new ArrayList (); 7235 7236 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 7237 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 7238 public void acceptName(char[] name) { 7239 int relevance = computeBaseRelevance(); 7240 relevance += computeRelevanceForInterestingProposal(); 7241 relevance += computeRelevanceForCaseMatching(completionToken, name); 7242 relevance += R_NAME_FIRST_PREFIX; 7243 relevance += R_NAME_FIRST_SUFFIX; 7244 relevance += R_NAME_LESS_NEW_CHARACTERS; 7245 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 7247 CompletionEngine.this.noProposal = false; 7249 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 7250 CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition); 7251 proposal.setSignature(getSignature(type.resolvedType)); 7252 proposal.setPackageName(type.resolvedType.qualifiedPackageName()); 7253 proposal.setTypeName(type.resolvedType.qualifiedSourceName()); 7254 proposal.setName(name); 7255 proposal.setCompletion(name); 7256 proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset); 7258 proposal.setRelevance(relevance); 7259 CompletionEngine.this.requestor.accept(proposal); 7260 if(DEBUG) { 7261 CompletionEngine.this.printDebug(proposal); 7262 } 7263 } 7264 proposedNames.add(name); 7265 } 7266 }; 7267 7268 ReferenceContext referenceContext = scope.referenceContext(); 7269 if (referenceContext instanceof AbstractMethodDeclaration) { 7270 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 7271 7272 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7273 nameFinder.find( 7274 completionToken, 7275 md, 7276 variable.declarationSourceEnd + 1, 7277 discouragedNames, 7278 nameRequestor); 7279 } else if (referenceContext instanceof TypeDeclaration) { 7280 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 7281 FieldDeclaration[] fields = typeDeclaration.fields; 7282 if (fields != null) { 7283 done : for (int i = 0; i < fields.length; i++) { 7284 if (fields[i] instanceof Initializer) { 7285 Initializer initializer = (Initializer) fields[i]; 7286 if (initializer.bodyStart <= variable.sourceStart && 7287 variable.sourceStart < initializer.bodyEnd) { 7288 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7289 nameFinder.find( 7290 completionToken, 7291 initializer, 7292 typeDeclaration.scope, 7293 variable.declarationSourceEnd + 1, 7294 discouragedNames, 7295 nameRequestor); 7296 break done; 7297 } 7298 } 7299 } 7300 } 7301 } 7302 7303 int proposedNamesCount = proposedNames.size(); 7304 if (proposedNamesCount > 0) { 7305 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 7306 } 7307 } 7308 7309 return null; 7310 } 7311 7312 private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) { 7313 final ArrayList proposedNames = new ArrayList (); 7314 7315 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 7316 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 7317 public void acceptName(char[] name) { 7318 CompletionEngine.this.acceptUnresolvedName(name); 7319 proposedNames.add(name); 7320 } 7321 }; 7322 7323 ReferenceContext referenceContext = scope.referenceContext(); 7324 if (referenceContext instanceof AbstractMethodDeclaration) { 7325 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 7326 7327 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7328 nameFinder.findAfter( 7329 completionToken, 7330 md.scope, 7331 md.scope.classScope(), 7332 from, 7333 md.bodyEnd, 7334 discouragedNames, 7335 nameRequestor); 7336 } else if (referenceContext instanceof TypeDeclaration) { 7337 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 7338 FieldDeclaration[] fields = typeDeclaration.fields; 7339 if (fields != null) { 7340 done : for (int i = 0; i < fields.length; i++) { 7341 if (fields[i] instanceof Initializer) { 7342 Initializer initializer = (Initializer) fields[i]; 7343 if (initializer.block.sourceStart <= from && 7344 from < initializer.bodyEnd) { 7345 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7346 nameFinder.findAfter( 7347 completionToken, 7348 typeDeclaration.scope, 7349 typeDeclaration.scope, 7350 from, 7351 initializer.bodyEnd, 7352 discouragedNames, 7353 nameRequestor); 7354 break done; 7355 } 7356 } 7357 } 7358 } 7359 } 7360 7361 int proposedNamesCount = proposedNames.size(); 7362 if (proposedNamesCount > 0) { 7363 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 7364 } 7365 7366 return null; 7367 } 7368 7369 private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) { 7370 char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames); 7371 if (foundNames != null && foundNames.length > 1) { 7372 int discouragedNamesLength = discouragedNames.length; 7373 int foundNamesLength = foundNames.length; 7374 int newLength = discouragedNamesLength + foundNamesLength; 7375 System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength); 7376 System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength); 7377 } 7378 findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames); 7379 } 7380 7381 private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) { 7382 final ArrayList proposedNames = new ArrayList (); 7383 7384 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 7385 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 7386 public void acceptName(char[] name) { 7387 CompletionEngine.this.acceptUnresolvedName(name); 7388 proposedNames.add(name); 7389 } 7390 }; 7391 7392 BlockScope upperScope = scope; 7393 while (upperScope.enclosingMethodScope() != null) { 7394 upperScope = upperScope.enclosingMethodScope(); 7395 } 7396 7397 ReferenceContext referenceContext = upperScope.referenceContext(); 7398 if (referenceContext instanceof AbstractMethodDeclaration) { 7399 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 7400 7401 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7402 nameFinder.findBefore( 7403 completionToken, 7404 md.scope, 7405 md.scope.classScope(), 7406 md.bodyStart, 7407 recordTo, 7408 parseTo, 7409 discouragedNames, 7410 nameRequestor); 7411 } else if (referenceContext instanceof TypeDeclaration) { 7412 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 7413 7414 7415 done : { 7416 FieldDeclaration[] fields = typeDeclaration.fields; 7417 if (fields != null) { 7418 for (int i = 0; i < fields.length; i++) { 7419 if (fields[i] instanceof Initializer) { 7420 Initializer initializer = (Initializer) fields[i]; 7421 if (initializer.block.sourceStart <= recordTo && 7422 recordTo < initializer.bodyEnd) { 7423 7424 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 7425 nameFinder.findBefore( 7426 completionToken, 7427 typeDeclaration.scope, 7428 typeDeclaration.scope, 7429 initializer.block.sourceStart, 7430 recordTo, 7431 parseTo, 7432 discouragedNames, 7433 nameRequestor); 7434 break done; 7435 } 7436 } 7437 } 7438 } 7439 } 7440 } 7441 7442 int proposedNamesCount = proposedNames.size(); 7443 if (proposedNamesCount > 0) { 7444 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 7445 } 7446 7447 return null; 7448 } 7449 private void findVariableName( 7451 char[] token, 7452 char[] qualifiedPackageName, 7453 char[] qualifiedSourceName, 7454 char[] sourceName, 7455 final TypeBinding typeBinding, 7456 char[][] discouragedNames, 7457 final char[][] forbiddenNames, 7458 int dim, 7459 int kind, 7460 int modifiers){ 7461 7462 if(sourceName == null || sourceName.length == 0) 7463 return; 7464 7465 final char[] displayName; 7467 if (dim > 0){ 7468 int l = qualifiedSourceName.length; 7469 displayName = new char[l+(2*dim)]; 7470 System.arraycopy(qualifiedSourceName, 0, displayName, 0, l); 7471 for(int i = 0; i < dim; i++){ 7472 displayName[l+(i*2)] = '['; 7473 displayName[l+(i*2)+1] = ']'; 7474 } 7475 } else { 7476 displayName = qualifiedSourceName; 7477 } 7478 7479 final char[] t = token; 7480 final char[] q = qualifiedPackageName; 7481 INamingRequestor namingRequestor = new INamingRequestor() { 7482 public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) { 7483 accept( 7484 name, 7485 (isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX), 7486 reusedCharacters); 7487 } 7488 7489 public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) { 7490 accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX, reusedCharacters); 7491 } 7492 7493 public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) { 7494 accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters); 7495 } 7496 7497 public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) { 7498 accept(name, 0, reusedCharacters); 7499 } 7500 void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){ 7501 int l = forbiddenNames == null ? 0 : forbiddenNames.length; 7502 for (int i = 0; i < l; i++) { 7503 if (CharOperation.equals(forbiddenNames[i], name, false)) return; 7504 } 7505 7506 if (CharOperation.prefixEquals(t, name, false)) { 7507 int relevance = computeBaseRelevance(); 7508 relevance += computeRelevanceForInterestingProposal(); 7509 relevance += computeRelevanceForCaseMatching(t, name); 7510 relevance += prefixAndSuffixRelevance; 7511 if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS; 7512 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 7514 CompletionEngine.this.noProposal = false; 7516 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 7517 CompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition); 7518 proposal.setSignature(getSignature(typeBinding)); 7519 proposal.setPackageName(q); 7520 proposal.setTypeName(displayName); 7521 proposal.setName(name); 7522 proposal.setCompletion(name); 7523 proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset); 7525 proposal.setRelevance(relevance); 7526 CompletionEngine.this.requestor.accept(proposal); 7527 if(DEBUG) { 7528 CompletionEngine.this.printDebug(proposal); 7529 } 7530 } 7531 } 7532 } 7533 }; 7534 7535 switch (kind) { 7536 case FIELD : 7537 InternalNamingConventions.suggestFieldNames( 7538 this.javaProject, 7539 qualifiedPackageName, 7540 qualifiedSourceName, 7541 dim, 7542 modifiers, 7543 token, 7544 discouragedNames, 7545 namingRequestor); 7546 break; 7547 case LOCAL : 7548 InternalNamingConventions.suggestLocalVariableNames( 7549 this.javaProject, 7550 qualifiedPackageName, 7551 qualifiedSourceName, 7552 dim, 7553 token, 7554 discouragedNames, 7555 namingRequestor); 7556 break; 7557 case ARGUMENT : 7558 InternalNamingConventions.suggestArgumentNames( 7559 this.javaProject, 7560 qualifiedPackageName, 7561 qualifiedSourceName, 7562 dim, 7563 token, 7564 discouragedNames, 7565 namingRequestor); 7566 break; 7567 } 7568 } 7569 7570 private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){ 7571 7572 if(type != null && 7573 type.resolvedType != null && 7574 type.resolvedType.problemId() == ProblemReasons.NoError){ 7575 TypeBinding tb = type.resolvedType; 7576 findVariableName( 7577 name, 7578 tb.leafComponentType().qualifiedPackageName(), 7579 tb.leafComponentType().qualifiedSourceName(), 7580 tb.leafComponentType().sourceName(), 7581 tb, 7582 discouragedNames, 7583 forbiddenNames, 7584 type.dimensions(), 7585 kind, 7586 modifiers); 7587 } 7597 } 7598 7599 private ImportBinding[] getFavoriteReferenceBindings(Scope scope) { 7600 if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings; 7601 7602 String [] favoriteReferences = this.requestor.getFavoriteReferences(); 7603 7604 if (favoriteReferences == null || favoriteReferences.length == 0) return null; 7605 7606 ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length]; 7607 7608 int count = 0; 7609 next : for (int i = 0; i < favoriteReferences.length; i++) { 7610 String favoriteReference = favoriteReferences[i]; 7611 7612 int length; 7613 if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next; 7614 7615 boolean onDemand = favoriteReference.charAt(length - 1) == '*'; 7616 7617 char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray()); 7618 if (onDemand) { 7619 compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1); 7620 } 7621 7622 for (int j = 0; j < count; j++) { 7624 ImportReference f = resolvedImports[j].reference; 7625 7626 if (CharOperation.equals(f.tokens, compoundName)) continue next; 7627 7628 if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) { 7629 if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1])) 7630 continue next; 7631 } 7632 } 7633 7634 boolean isStatic = true; 7635 7636 ImportReference importReference = 7637 new ImportReference( 7638 compoundName, 7639 new long[compoundName.length], 7640 onDemand, 7641 isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault); 7642 7643 Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand); 7644 7645 if (!importBinding.isValidBinding()) { 7646 continue next; 7647 } 7648 7649 if (importBinding instanceof PackageBinding) { 7650 continue next; 7651 } 7652 7653 resolvedImports[count++] = 7654 new ImportBinding(compoundName, onDemand, importBinding, importReference); 7655 } 7656 7657 if (resolvedImports.length > count) 7658 System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count); 7659 7660 return this.favoriteReferenceBindings = resolvedImports; 7661 } 7662 7663 public AssistParser getParser() { 7664 7665 return this.parser; 7666 } 7667 7668 protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) { 7669 if (this.targetedElement == TagBits.AnnotationForPackage) { 7670 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 7671 if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) { 7672 return false; 7673 } 7674 } else if ((this.targetedElement & TagBits.AnnotationForType) != 0) { 7675 if (scope.parent != null && 7676 scope.parent.parent != null && 7677 scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType && 7678 scope.parent.parent instanceof CompilationUnitScope) { 7679 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 7680 if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) { 7681 if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) { 7682 return false; 7683 } 7684 } else { 7685 if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) { 7686 return false; 7687 } 7688 } 7689 } 7690 } 7691 return true; 7692 } 7693 7694 protected void reset() { 7695 7696 super.reset(); 7697 this.knownPkgs = new HashtableOfObject(10); 7698 this.knownTypes = new HashtableOfObject(10); 7699 } 7700 7701 private void setSourceRange(int start, int end) { 7702 this.setSourceRange(start, end, true); 7703 } 7704 7705 private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) { 7706 this.startPosition = start; 7707 if(emptyTokenAdjstment) { 7708 int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken; 7709 this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1; 7710 } else { 7711 this.endPosition = end + 1; 7712 } 7713 } 7714 private char[][] computeAlreadyDefinedName( 7715 BlockScope scope, 7716 InvocationSite invocationSite) { 7717 ArrayList result = new ArrayList (); 7718 7719 boolean staticsOnly = false; 7720 7721 Scope currentScope = scope; 7722 7723 done1 : while (true) { 7725 switch (currentScope.kind) { 7726 7727 case Scope.METHOD_SCOPE : 7728 MethodScope methodScope = (MethodScope) currentScope; 7730 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 7731 7732 case Scope.BLOCK_SCOPE : 7733 BlockScope blockScope = (BlockScope) currentScope; 7734 7735 next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { 7736 LocalVariableBinding local = blockScope.locals[i]; 7737 7738 if (local == null) 7739 break next; 7740 7741 if (local.isSecret()) 7742 continue next; 7743 7744 result.add(local.name); 7745 } 7746 break; 7747 7748 case Scope.CLASS_SCOPE : 7749 ClassScope classScope = (ClassScope) currentScope; 7750 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 7751 computeAlreadyDefinedName( 7752 enclosingType, 7753 classScope, 7754 staticsOnly, 7755 invocationSite, 7756 result); 7757 staticsOnly |= enclosingType.isStatic(); 7758 break; 7759 7760 case Scope.COMPILATION_UNIT_SCOPE : 7761 break done1; 7762 } 7763 currentScope = currentScope.parent; 7764 } 7765 7766 if (result.size() == 0) return CharOperation.NO_CHAR_CHAR; 7767 7768 return (char[][])result.toArray(new char[result.size()][]); 7769 } 7770 7771 private void computeAlreadyDefinedName( 7772 SourceTypeBinding receiverType, 7773 ClassScope scope, 7774 boolean onlyStaticFields, 7775 InvocationSite invocationSite, 7776 ArrayList result) { 7777 7778 ReferenceBinding currentType = receiverType; 7779 ReferenceBinding[] interfacesToVisit = null; 7780 int nextPosition = 0; 7781 do { 7782 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 7783 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 7784 if (interfacesToVisit == null) { 7785 interfacesToVisit = itsInterfaces; 7786 nextPosition = interfacesToVisit.length; 7787 } else { 7788 int itsLength = itsInterfaces.length; 7789 if (nextPosition + itsLength >= interfacesToVisit.length) 7790 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 7791 nextInterface : for (int a = 0; a < itsLength; a++) { 7792 ReferenceBinding next = itsInterfaces[a]; 7793 for (int b = 0; b < nextPosition; b++) 7794 if (next == interfacesToVisit[b]) continue nextInterface; 7795 interfacesToVisit[nextPosition++] = next; 7796 } 7797 } 7798 } 7799 7800 FieldBinding[] fields = currentType.availableFields(); 7801 if(fields != null && fields.length > 0) { 7802 computeAlreadyDefinedName( 7803 fields, 7804 scope, 7805 onlyStaticFields, 7806 receiverType, 7807 invocationSite, 7808 result); 7809 } 7810 currentType = currentType.superclass(); 7811 } while ( currentType != null); 7812 7813 if (interfacesToVisit != null) { 7814 for (int i = 0; i < nextPosition; i++) { 7815 ReferenceBinding anInterface = interfacesToVisit[i]; 7816 FieldBinding[] fields = anInterface.availableFields(); 7817 if(fields != null) { 7818 computeAlreadyDefinedName( 7819 fields, 7820 scope, 7821 onlyStaticFields, 7822 receiverType, 7823 invocationSite, 7824 result); 7825 } 7826 7827 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 7828 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 7829 int itsLength = itsInterfaces.length; 7830 if (nextPosition + itsLength >= interfacesToVisit.length) 7831 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 7832 nextInterface : for (int a = 0; a < itsLength; a++) { 7833 ReferenceBinding next = itsInterfaces[a]; 7834 for (int b = 0; b < nextPosition; b++) 7835 if (next == interfacesToVisit[b]) continue nextInterface; 7836 interfacesToVisit[nextPosition++] = next; 7837 } 7838 } 7839 } 7840 } 7841 } 7842 7843 private void computeAlreadyDefinedName( 7844 FieldBinding[] fields, 7845 Scope scope, 7846 boolean onlyStaticFields, 7847 ReferenceBinding receiverType, 7848 InvocationSite invocationSite, 7849 ArrayList result) { 7850 7851 next : for (int f = fields.length; --f >= 0;) { 7852 FieldBinding field = fields[f]; 7853 7854 if (field.isSynthetic()) continue next; 7855 7856 if (onlyStaticFields && !field.isStatic()) continue next; 7857 7858 if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 7859 7860 result.add(field.name); 7861 } 7862 } 7863 7864 int computeBaseRelevance(){ 7865 return R_DEFAULT; 7866 } 7867 int computeRelevanceForResolution(){ 7868 return computeRelevanceForResolution(true); 7869 } 7870 int computeRelevanceForResolution(boolean isResolved){ 7871 if (isResolved) { 7872 return R_RESOLVED; 7873 } 7874 return 0; 7875 } 7876 private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){ 7877 7878 this.expectedTypesFilter = SUBTYPE; 7880 this.hasJavaLangObjectAsExpectedType = false; 7881 7882 if(parent instanceof AbstractVariableDeclaration) { 7884 AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent; 7885 TypeBinding binding = variable.type.resolvedType; 7886 if(binding != null) { 7887 if(!(variable.initialization instanceof ArrayInitializer)) { 7888 addExpectedType(binding, scope); 7889 } 7890 } 7891 } else if(parent instanceof Assignment) { 7892 TypeBinding binding = ((Assignment)parent).lhs.resolvedType; 7893 if(binding != null) { 7894 addExpectedType(binding, scope); 7895 } 7896 } else if(parent instanceof ReturnStatement) { 7897 if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) { 7898 MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding; 7899 TypeBinding binding = methodBinding == null ? null : methodBinding.returnType; 7900 if(binding != null) { 7901 addExpectedType(binding, scope); 7902 } 7903 } 7904 } else if(parent instanceof CastExpression) { 7905 Expression e = ((CastExpression)parent).type; 7906 TypeBinding binding = e.resolvedType; 7907 if(binding != null){ 7908 addExpectedType(binding, scope); 7909 this.expectedTypesFilter = SUBTYPE | SUPERTYPE; 7910 } 7911 } else if(parent instanceof MessageSend) { 7912 MessageSend messageSend = (MessageSend) parent; 7913 7914 if(messageSend.actualReceiverType instanceof ReferenceBinding) { 7915 ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType; 7916 boolean isStatic = messageSend.receiver.isTypeReference(); 7917 7918 while(binding != null) { 7919 computeExpectedTypesForMessageSend( 7920 binding, 7921 messageSend.selector, 7922 messageSend.arguments, 7923 (ReferenceBinding)messageSend.actualReceiverType, 7924 scope, 7925 messageSend, 7926 isStatic); 7927 computeExpectedTypesForMessageSendForInterface( 7928 binding, 7929 messageSend.selector, 7930 messageSend.arguments, 7931 (ReferenceBinding)messageSend.actualReceiverType, 7932 scope, 7933 messageSend, 7934 isStatic); 7935 binding = binding.superclass(); 7936 } 7937 } 7938 } else if(parent instanceof AllocationExpression) { 7939 AllocationExpression allocationExpression = (AllocationExpression) parent; 7940 7941 ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType; 7942 7943 if(binding != null) { 7944 computeExpectedTypesForAllocationExpression( 7945 binding, 7946 allocationExpression.arguments, 7947 scope, 7948 allocationExpression); 7949 } 7950 } else if(parent instanceof OperatorExpression) { 7951 int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT; 7952 if(parent instanceof ConditionalExpression) { 7953 } else if(parent instanceof InstanceOfExpression) { 7955 InstanceOfExpression e = (InstanceOfExpression) parent; 7956 TypeBinding binding = e.expression.resolvedType; 7957 if(binding != null){ 7958 addExpectedType(binding, scope); 7959 this.expectedTypesFilter = SUBTYPE | SUPERTYPE; 7960 } 7961 } else if(parent instanceof BinaryExpression) { 7962 switch(operator) { 7963 case OperatorIds.PLUS : 7964 addExpectedType(TypeBinding.SHORT, scope); 7965 addExpectedType(TypeBinding.INT, scope); 7966 addExpectedType(TypeBinding.LONG, scope); 7967 addExpectedType(TypeBinding.FLOAT, scope); 7968 addExpectedType(TypeBinding.DOUBLE, scope); 7969 addExpectedType(TypeBinding.CHAR, scope); 7970 addExpectedType(TypeBinding.BYTE, scope); 7971 addExpectedType(scope.getJavaLangString(), scope); 7972 break; 7973 case OperatorIds.AND_AND : 7974 case OperatorIds.OR_OR : 7975 case OperatorIds.XOR : 7976 addExpectedType(TypeBinding.BOOLEAN, scope); 7977 break; 7978 default : 7979 addExpectedType(TypeBinding.SHORT, scope); 7980 addExpectedType(TypeBinding.INT, scope); 7981 addExpectedType(TypeBinding.LONG, scope); 7982 addExpectedType(TypeBinding.FLOAT, scope); 7983 addExpectedType(TypeBinding.DOUBLE, scope); 7984 addExpectedType(TypeBinding.CHAR, scope); 7985 addExpectedType(TypeBinding.BYTE, scope); 7986 break; 7987 } 7988 BinaryExpression binaryExpression = (BinaryExpression) parent; 7989 if(operator == OperatorIds.LESS) { 7990 if(binaryExpression.left instanceof SingleNameReference){ 7991 SingleNameReference name = (SingleNameReference) binaryExpression.left; 7992 Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false); 7993 if(b instanceof ReferenceBinding) { 7994 TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables(); 7995 if(typeVariableBindings != null && typeVariableBindings.length > 0) { 7996 addExpectedType(typeVariableBindings[0].firstBound, scope); 7997 } 7998 7999 } 8000 } 8001 } 8002 } else if(parent instanceof UnaryExpression) { 8003 switch(operator) { 8004 case OperatorIds.NOT : 8005 addExpectedType(TypeBinding.BOOLEAN, scope); 8006 break; 8007 case OperatorIds.TWIDDLE : 8008 addExpectedType(TypeBinding.SHORT, scope); 8009 addExpectedType(TypeBinding.INT, scope); 8010 addExpectedType(TypeBinding.LONG, scope); 8011 addExpectedType(TypeBinding.CHAR, scope); 8012 addExpectedType(TypeBinding.BYTE, scope); 8013 break; 8014 case OperatorIds.PLUS : 8015 case OperatorIds.MINUS : 8016 case OperatorIds.PLUS_PLUS : 8017 case OperatorIds.MINUS_MINUS : 8018 addExpectedType(TypeBinding.SHORT, scope); 8019 addExpectedType(TypeBinding.INT, scope); 8020 addExpectedType(TypeBinding.LONG, scope); 8021 addExpectedType(TypeBinding.FLOAT, scope); 8022 addExpectedType(TypeBinding.DOUBLE, scope); 8023 addExpectedType(TypeBinding.CHAR, scope); 8024 addExpectedType(TypeBinding.BYTE, scope); 8025 break; 8026 } 8027 } 8028 } else if(parent instanceof ArrayReference) { 8029 addExpectedType(TypeBinding.SHORT, scope); 8030 addExpectedType(TypeBinding.INT, scope); 8031 addExpectedType(TypeBinding.LONG, scope); 8032 } else if(parent instanceof ParameterizedSingleTypeReference) { 8033 ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent; 8034 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 8035 int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; 8036 if(typeVariables != null && typeVariables.length >= length) { 8037 int index = length - 1; 8038 while(index > -1 && ref.typeArguments[index] != node) index--; 8039 8040 TypeBinding bound = typeVariables[index].firstBound; 8041 addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope); 8042 } 8043 } else if(parent instanceof ParameterizedQualifiedTypeReference) { 8044 ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent; 8045 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 8046 TypeReference[][] arguments = ref.typeArguments; 8047 if(typeVariables != null) { 8048 int iLength = arguments == null ? 0 : arguments.length; 8049 done: for (int i = 0; i < iLength; i++) { 8050 int jLength = arguments[i] == null ? 0 : arguments[i].length; 8051 for (int j = 0; j < jLength; j++) { 8052 if(arguments[i][j] == node && typeVariables.length > j) { 8053 TypeBinding bound = typeVariables[j].firstBound; 8054 addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope); 8055 break done; 8056 } 8057 } 8058 } 8059 } 8060 } else if(parent instanceof MemberValuePair) { 8061 MemberValuePair memberValuePair = (MemberValuePair) parent; 8062 if(memberValuePair.binding != null) { 8063 addExpectedType(memberValuePair.binding.returnType, scope); 8064 } 8065 } else if (parent instanceof NormalAnnotation) { 8066 NormalAnnotation annotation = (NormalAnnotation) parent; 8067 MemberValuePair[] memberValuePairs = annotation.memberValuePairs(); 8068 if(memberValuePairs == null || memberValuePairs.length == 0) { 8069 if(annotation.resolvedType instanceof ReferenceBinding) { 8070 MethodBinding[] methodBindings = 8071 ((ReferenceBinding)annotation.resolvedType).availableMethods(); 8072 if (methodBindings != null && 8073 methodBindings.length > 0 && 8074 CharOperation.equals(methodBindings[0].selector, VALUE)) { 8075 boolean canBeSingleMemberAnnotation = true; 8076 done : for (int i = 1; i < methodBindings.length; i++) { 8077 if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) { 8078 canBeSingleMemberAnnotation = false; 8079 break done; 8080 } 8081 } 8082 if (canBeSingleMemberAnnotation) { 8083 this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation; 8084 addExpectedType(methodBindings[0].returnType, scope); 8085 } 8086 } 8087 } 8088 } 8089 } else if (parent instanceof TryStatement) { 8090 boolean isException = false; 8091 if (node instanceof CompletionOnSingleTypeReference) { 8092 isException = ((CompletionOnSingleTypeReference)node).isException(); 8093 } else if (node instanceof CompletionOnQualifiedTypeReference) { 8094 isException = ((CompletionOnQualifiedTypeReference)node).isException(); 8095 } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) { 8096 isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException(); 8097 } 8098 if (isException) { 8099 ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder(); 8100 ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope); 8101 if (bindings != null && bindings.length > 0) { 8102 for (int i = 0; i < bindings.length; i++) { 8103 addExpectedType(bindings[i], scope); 8104 } 8105 this.expectedTypesFilter = SUPERTYPE; 8106 } 8107 } 8108 8109 } else if (parent instanceof Javadoc) { 8111 if (scope.kind == Scope.METHOD_SCOPE) { 8112 MethodScope methodScope = (MethodScope) scope; 8113 AbstractMethodDeclaration methodDecl = methodScope.referenceMethod(); 8114 if (methodDecl != null && methodDecl.binding != null) { 8115 ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions; 8116 if (exceptions != null) { 8117 for (int i = 0; i < exceptions.length; i++) { 8118 addExpectedType(exceptions[i], scope); 8119 } 8120 } 8121 } 8122 } 8123 } 8124 8125 if(this.expectedTypesPtr + 1 != this.expectedTypes.length) { 8126 System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1); 8127 } 8128 } 8129 8130 private void computeExpectedTypesForAllocationExpression( 8131 ReferenceBinding binding, 8132 Expression[] arguments, 8133 Scope scope, 8134 InvocationSite invocationSite) { 8135 8136 MethodBinding[] methods = binding.availableMethods(); 8137 nextMethod : for (int i = 0; i < methods.length; i++) { 8138 MethodBinding method = methods[i]; 8139 8140 if (!method.isConstructor()) continue nextMethod; 8141 8142 if (method.isSynthetic()) continue nextMethod; 8143 8144 if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod; 8145 8146 TypeBinding[] parameters = method.parameters; 8147 if(parameters.length < arguments.length) 8148 continue nextMethod; 8149 8150 int length = arguments.length - 1; 8151 8152 for (int j = 0; j < length; j++) { 8153 Expression argument = arguments[j]; 8154 TypeBinding argType = argument.resolvedType; 8155 if(argType != null && !argType.isCompatibleWith(parameters[j])) 8156 continue nextMethod; 8157 } 8158 8159 TypeBinding expectedType = method.parameters[arguments.length - 1]; 8160 if(expectedType != null) { 8161 addExpectedType(expectedType, scope); 8162 } 8163 } 8164 } 8165 8166 private void computeExpectedTypesForMessageSendForInterface( 8167 ReferenceBinding binding, 8168 char[] selector, 8169 Expression[] arguments, 8170 ReferenceBinding receiverType, 8171 Scope scope, 8172 InvocationSite invocationSite, 8173 boolean isStatic) { 8174 8175 ReferenceBinding[] itsInterfaces = binding.superInterfaces(); 8176 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 8177 ReferenceBinding[] interfacesToVisit = itsInterfaces; 8178 int nextPosition = interfacesToVisit.length; 8179 8180 for (int i = 0; i < nextPosition; i++) { 8181 ReferenceBinding currentType = interfacesToVisit[i]; 8182 computeExpectedTypesForMessageSend( 8183 currentType, 8184 selector, 8185 arguments, 8186 receiverType, 8187 scope, 8188 invocationSite, 8189 isStatic); 8190 8191 if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 8192 int itsLength = itsInterfaces.length; 8193 if (nextPosition + itsLength >= interfacesToVisit.length) 8194 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 8195 nextInterface : for (int a = 0; a < itsLength; a++) { 8196 ReferenceBinding next = itsInterfaces[a]; 8197 for (int b = 0; b < nextPosition; b++) 8198 if (next == interfacesToVisit[b]) continue nextInterface; 8199 interfacesToVisit[nextPosition++] = next; 8200 } 8201 } 8202 } 8203 } 8204 } 8205 8206 private void computeExpectedTypesForMessageSend( 8207 ReferenceBinding binding, 8208 char[] selector, 8209 Expression[] arguments, 8210 ReferenceBinding receiverType, 8211 Scope scope, 8212 InvocationSite invocationSite, 8213 boolean isStatic) { 8214 8215 MethodBinding[] methods = binding.availableMethods(); 8216 nextMethod : for (int i = 0; i < methods.length; i++) { 8217 MethodBinding method = methods[i]; 8218 8219 if (method.isSynthetic()) continue nextMethod; 8220 8221 if (method.isDefaultAbstract()) continue nextMethod; 8222 8223 if (method.isConstructor()) continue nextMethod; 8224 8225 if (isStatic && !method.isStatic()) continue nextMethod; 8226 8227 if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod; 8228 8229 if(!CharOperation.equals(method.selector, selector)) continue nextMethod; 8230 8231 TypeBinding[] parameters = method.parameters; 8232 if(parameters.length < arguments.length) 8233 continue nextMethod; 8234 8235 int length = arguments.length - 1; 8236 8237 for (int j = 0; j < length; j++) { 8238 Expression argument = arguments[j]; 8239 TypeBinding argType = argument.resolvedType; 8240 if(argType != null && !argType.isCompatibleWith(parameters[j])) 8241 continue nextMethod; 8242 } 8243 8244 TypeBinding expectedType = method.parameters[arguments.length - 1]; 8245 if(expectedType != null) { 8246 addExpectedType(expectedType, scope); 8247 } 8248 } 8249 } 8250 private void addExpectedType(TypeBinding type, Scope scope){ 8251 if (type == null || !type.isValidBinding()) return; 8252 8253 int length = this.expectedTypes.length; 8254 if (++this.expectedTypesPtr >= length) 8255 System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length); 8256 this.expectedTypes[this.expectedTypesPtr] = type; 8257 8258 if(type == scope.getJavaLangObject()) { 8259 this.hasJavaLangObjectAsExpectedType = true; 8260 } 8261 } 8262 private void addForbiddenBindings(Binding binding){ 8263 if (binding == null) return; 8264 8265 int length = this.forbbidenBindings.length; 8266 if (++this.forbbidenBindingsPtr >= length) 8267 System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length); 8268 this.forbbidenBindings[this.forbbidenBindingsPtr] = binding; 8269 } 8270 private void addUninterestingBindings(Binding binding){ 8271 if (binding == null) return; 8272 8273 int length = this.uninterestingBindings.length; 8274 if (++this.uninterestingBindingsPtr >= length) 8275 System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length); 8276 this.uninterestingBindings[this.uninterestingBindingsPtr] = binding; 8277 } 8278 8279 private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) { 8280 this.forbbidenBindingsFilter = NONE; 8281 if(scope instanceof ClassScope) { 8282 TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext; 8283 if(typeDeclaration.superclass == astNode) { 8284 this.addForbiddenBindings(typeDeclaration.binding); 8285 return scope.parent; 8286 } 8287 TypeReference[] superInterfaces = typeDeclaration.superInterfaces; 8288 int length = superInterfaces == null ? 0 : superInterfaces.length; 8289 for (int i = 0; i < length; i++) { 8290 if(superInterfaces[i] == astNode) { 8291 this.addForbiddenBindings(typeDeclaration.binding); 8292 return scope.parent; 8293 } 8294 } 8295 } else { 8296 if (astNodeParent != null && astNodeParent instanceof TryStatement) { 8297 boolean isException = false; 8298 if (astNode instanceof CompletionOnSingleTypeReference) { 8299 isException = ((CompletionOnSingleTypeReference)astNode).isException(); 8300 } else if (astNode instanceof CompletionOnQualifiedTypeReference) { 8301 isException = ((CompletionOnQualifiedTypeReference)astNode).isException(); 8302 } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) { 8303 isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException(); 8304 } 8305 if (isException) { 8306 Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments; 8307 int length = catchArguments == null ? 0 : catchArguments.length; 8308 for (int i = 0; i < length; i++) { 8309 TypeBinding caughtException = catchArguments[i].type.resolvedType; 8310 if (caughtException != null) { 8311 this.addForbiddenBindings(caughtException); 8312 this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this); 8313 } 8314 } 8315 this.forbbidenBindingsFilter = SUBTYPE; 8316 } 8317 } 8318 } 8319 return scope; 8326 } 8327 private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){ 8328 8329 StringBuffer completion = new StringBuffer (10); 8330 8331 if (isStatic) { 8332 completion.append(declarationType.sourceName()); 8333 8334 } else if (declarationType == invocationType) { 8335 completion.append(THIS); 8336 8337 } else { 8338 8339 if (!declarationType.isNestedType()) { 8340 8341 completion.append(declarationType.sourceName()); 8342 completion.append('.'); 8343 completion.append(THIS); 8344 8345 } else if (!declarationType.isAnonymousType()) { 8346 8347 completion.append(declarationType.sourceName()); 8348 completion.append('.'); 8349 completion.append(THIS); 8350 8351 } 8352 } 8353 8354 return completion.toString().toCharArray(); 8355 } 8356 8357 private void proposeNewMethod(char[] token, ReferenceBinding reference) { 8358 if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 8359 int relevance = computeBaseRelevance(); 8360 relevance += computeRelevanceForResolution(); 8361 relevance += computeRelevanceForInterestingProposal(); 8362 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8364 CompletionProposal proposal = this.createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition); 8365 proposal.setDeclarationSignature(getSignature(reference)); 8366 proposal.setSignature( 8367 createMethodSignature( 8368 CharOperation.NO_CHAR_CHAR, 8369 CharOperation.NO_CHAR_CHAR, 8370 CharOperation.NO_CHAR, 8371 VOID)); 8372 proposal.setDeclarationPackageName(reference.qualifiedPackageName()); 8373 proposal.setDeclarationTypeName(reference.qualifiedSourceName()); 8374 8375 proposal.setTypeName(VOID); 8377 proposal.setName(token); 8378 proposal.setCompletion(token); 8382 proposal.setFlags(Flags.AccPublic); 8383 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8384 proposal.setRelevance(relevance); 8385 this.requestor.accept(proposal); 8386 if(DEBUG) { 8387 this.printDebug(proposal); 8388 } 8389 } 8390 } 8391 private boolean isForbidden(Binding binding) { 8392 for (int i = 0; i <= this.forbbidenBindingsPtr; i++) { 8393 if(this.forbbidenBindings[i] == binding) { 8394 return true; 8395 } 8396 if((this.forbbidenBindingsFilter & SUBTYPE) != 0) { 8397 if (binding instanceof TypeBinding && 8398 this.forbbidenBindings[i] instanceof TypeBinding && 8399 ((TypeBinding)binding).isCompatibleWith((TypeBinding)this.forbbidenBindings[i])) { 8400 return true; 8401 } 8402 } 8403 } 8404 return false; 8405 } 8406 private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){ 8407 8408 if(parent instanceof ParameterizedSingleTypeReference) { 8409 ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent; 8410 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 8411 int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; 8412 int nodeIndex = -1; 8413 for(int i = length - 1 ; i > -1 ; i--) { 8414 if(node == ref.typeArguments[i]) { 8415 nodeIndex = i; 8416 break; 8417 } 8418 } 8419 if(nodeIndex > -1 && (typeVariables == null || typeVariables.length < nodeIndex + 1)) { 8420 TypeBinding[] typeBindings = new TypeBinding[nodeIndex + 1]; 8421 for(int i = 0; i < nodeIndex; i++) { 8422 typeBindings[i] = ref.typeArguments[i].resolvedType; 8423 } 8424 typeBindings[nodeIndex] = scope.getJavaLangObject(); 8425 if(typeVariables == null || typeVariables.length == 0) { 8426 scope.problemReporter().nonGenericTypeCannotBeParameterized(ref, ref.resolvedType, typeBindings); 8427 } else { 8428 scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings); 8429 } 8430 return false; 8431 } 8432 } else if(parent instanceof ParameterizedQualifiedTypeReference) { 8433 ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent; 8434 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 8435 TypeReference[][] arguments = ref.typeArguments; 8436 int iLength = arguments == null ? 0 : arguments.length; 8437 for (int i = 0; i < iLength; i++) { 8438 int jLength = arguments[i] == null ? 0 : arguments[i].length; 8439 for (int j = 0; j < jLength; j++) { 8440 if(arguments[i][j] == node && (typeVariables == null || typeVariables.length <= j)) { 8441 TypeBinding[] typeBindings = new TypeBinding[j + 1]; 8442 for(int k = 0; k < j; k++) { 8443 typeBindings[k] = ref.typeArguments[i][k].resolvedType; 8444 } 8445 typeBindings[j] = scope.getJavaLangObject(); 8446 if(typeVariables == null || typeVariables.length == 0) { 8447 scope.problemReporter().nonGenericTypeCannotBeParameterized(ref, ref.resolvedType, typeBindings); 8448 } else { 8449 scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings); 8450 } 8451 return false; 8452 } 8453 } 8454 } 8455 } 8456 return true; 8457 } 8458 8459 public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) { 8460 return Signature.createCharArrayTypeSignature( 8461 CharOperation.concat( 8462 qualifiedPackageName, 8463 CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true); 8464 } 8465 public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) { 8466 char[] name = new char[qualifiedTypeName.length]; 8467 System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length); 8468 8469 int depth = 0; 8470 int length = name.length; 8471 for (int i = length -1; i >= 0; i--) { 8472 switch (name[i]) { 8473 case '.': 8474 if (depth == 0 && name[i - 1] != '>') { 8475 name[i] = '$'; 8476 } 8477 break; 8478 case '<': 8479 depth--; 8480 break; 8481 case '>': 8482 depth++; 8483 break; 8484 } 8485 } 8486 return Signature.createCharArrayTypeSignature( 8487 CharOperation.concat( 8488 qualifiedPackageName, 8489 name, '.'), true); 8490 } 8491 8492 public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) { 8493 char[] returnTypeSignature = 8494 returnTypeName == null || returnTypeName.length == 0 8495 ? Signature.createCharArrayTypeSignature(VOID, true) 8496 : Signature.createCharArrayTypeSignature( 8497 CharOperation.concat( 8498 returnPackagename, 8499 CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true); 8500 8501 return createMethodSignature( 8502 parameterPackageNames, 8503 parameterTypeNames, 8504 returnTypeSignature); 8505 } 8506 8507 public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) { 8508 char[][] parameterTypeSignature = new char[parameterTypeNames.length][]; 8509 for (int i = 0; i < parameterTypeSignature.length; i++) { 8510 parameterTypeSignature[i] = 8511 Signature.createCharArrayTypeSignature( 8512 CharOperation.concat( 8513 parameterPackageNames[i], 8514 CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true); 8515 } 8516 8517 return Signature.createMethodSignature( 8518 parameterTypeSignature, 8519 returnTypeSignature); 8520 } 8521 8522 protected CompletionProposal createProposal(int kind, int completionOffset) { 8523 CompletionProposal proposal = CompletionProposal.create(kind, completionOffset - this.offset); 8524 proposal.nameLookup = this.nameEnvironment.nameLookup; 8525 proposal.completionEngine = this; 8526 return proposal; 8527 } 8528 8529 8532 private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) { 8533 8534 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 8536 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 8537 proposal.nameLookup = this.nameEnvironment.nameLookup; 8538 proposal.completionEngine = this; 8539 proposal.setDeclarationSignature(packageName); 8540 proposal.setSignature(createNonGenericTypeSignature(packageName, typeName)); 8541 proposal.setPackageName(packageName); 8542 proposal.setTypeName(typeName); 8543 proposal.setCompletion(completionName); 8544 proposal.setFlags(modifiers); 8545 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8546 proposal.setRelevance(relevance); 8547 proposal.setAccessibility(accessibility); 8548 this.requestor.accept(proposal); 8549 if(DEBUG) { 8550 this.printDebug(proposal); 8551 } 8552 } 8553 8554 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 8556 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 8557 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 8558 proposal.nameLookup = this.nameEnvironment.nameLookup; 8559 proposal.completionEngine = this; 8560 proposal.setDeclarationSignature(packageName); 8561 proposal.setSignature(createNonGenericTypeSignature(packageName, typeName)); 8562 proposal.setPackageName(packageName); 8563 proposal.setTypeName(typeName); 8564 proposal.setCompletion(javadocCompletion); 8565 proposal.setFlags(modifiers); 8566 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 8567 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 8568 proposal.setRelevance(relevance+R_INLINE_TAG); 8569 proposal.setAccessibility(accessibility); 8570 this.requestor.accept(proposal); 8571 if(DEBUG) { 8572 this.printDebug(proposal); 8573 } 8574 } 8575 } 8576 8577 8580 private void createTypeProposal(ReferenceBinding refBinding, char[] typeName, int accessibility, char[] completionName, int relevance) { 8581 8582 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 8584 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 8585 proposal.nameLookup = this.nameEnvironment.nameLookup; 8586 proposal.completionEngine = this; 8587 proposal.setDeclarationSignature(refBinding.qualifiedPackageName()); 8588 proposal.setSignature(getSignature(refBinding)); 8589 proposal.setPackageName(refBinding.qualifiedPackageName()); 8590 proposal.setTypeName(typeName); 8591 proposal.setCompletion(completionName); 8592 proposal.setFlags(refBinding.modifiers); 8593 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8594 proposal.setRelevance(relevance); 8595 this.requestor.accept(proposal); 8596 if(DEBUG) { 8597 this.printDebug(proposal); 8598 } 8599 } 8600 8601 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 8603 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 8604 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 8605 proposal.nameLookup = this.nameEnvironment.nameLookup; 8606 proposal.completionEngine = this; 8607 proposal.setDeclarationSignature(refBinding.qualifiedPackageName()); 8608 proposal.setSignature(getSignature(refBinding)); 8609 proposal.setPackageName(refBinding.qualifiedPackageName()); 8610 proposal.setTypeName(typeName); 8611 proposal.setCompletion(javadocCompletion); 8612 proposal.setFlags(refBinding.modifiers); 8613 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 8614 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 8615 proposal.setRelevance(relevance+R_INLINE_TAG); 8616 this.requestor.accept(proposal); 8617 if(DEBUG) { 8618 this.printDebug(proposal); 8619 } 8620 } 8621 } 8622 8623 8626 private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) { 8627 char[] completionName = typeParameter.name; 8628 8629 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 8631 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 8632 proposal.nameLookup = this.nameEnvironment.nameLookup; 8633 proposal.completionEngine = this; 8634 proposal.setSignature(getSignature(typeParameter.binding)); 8635 proposal.setTypeName(completionName); 8636 proposal.setCompletion(completionName); 8637 proposal.setFlags(typeParameter.modifiers); 8638 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8639 proposal.setRelevance(relevance); 8640 this.requestor.accept(proposal); 8641 if(DEBUG) { 8642 this.printDebug(proposal); 8643 } 8644 } 8645 8646 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 8648 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 8649 CompletionProposal proposal = CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 8650 proposal.nameLookup = this.nameEnvironment.nameLookup; 8651 proposal.completionEngine = this; 8652 proposal.setSignature(getSignature(typeParameter.binding)); 8653 proposal.setTypeName(javadocCompletion); 8654 proposal.setCompletion(javadocCompletion); 8655 proposal.setFlags(typeParameter.modifiers); 8656 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8657 proposal.setRelevance(relevance+R_INLINE_TAG); 8658 this.requestor.accept(proposal); 8659 if(DEBUG) { 8660 this.printDebug(proposal); 8661 } 8662 } 8663 } 8664 8665 8670 private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) { 8671 int tagLength= inlineTag.length; 8672 int completionLength = completionName.length; 8673 int inlineLength = 2+tagLength+1+completionLength+1; 8674 char[] inlineCompletion = new char[inlineLength]; 8675 inlineCompletion[0] = '{'; 8676 inlineCompletion[1] = '@'; 8677 System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength); 8678 inlineCompletion[tagLength+2] = ' '; 8679 System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength); 8680 inlineCompletion[inlineLength-1] = '}'; 8683 return inlineCompletion; 8684 } 8685 8686 protected void printDebug(CategorizedProblem error) { 8687 if(CompletionEngine.DEBUG) { 8688 System.out.print("COMPLETION - completionFailure("); System.out.print(error); 8690 System.out.println(")"); } 8692 } 8693 8694 private void printDebugTab(int tab, StringBuffer buffer) { 8695 for (int i = 0; i < tab; i++) { 8696 buffer.append('\t'); 8697 } 8698 } 8699 8700 protected void printDebug(CompletionProposal proposal){ 8701 StringBuffer buffer = new StringBuffer (); 8702 printDebug(proposal, 0, buffer); 8703 System.out.println(buffer.toString()); 8704 } 8705 private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){ 8706 printDebugTab(tab, buffer); 8707 buffer.append("COMPLETION - "); switch(proposal.getKind()) { 8709 case CompletionProposal.ANONYMOUS_CLASS_DECLARATION : 8710 buffer.append("ANONYMOUS_CLASS_DECLARATION"); break; 8712 case CompletionProposal.FIELD_REF : 8713 buffer.append("FIELD_REF"); break; 8715 case CompletionProposal.KEYWORD : 8716 buffer.append("KEYWORD"); break; 8718 case CompletionProposal.LABEL_REF : 8719 buffer.append("LABEL_REF"); break; 8721 case CompletionProposal.LOCAL_VARIABLE_REF : 8722 buffer.append("LOCAL_VARIABLE_REF"); break; 8724 case CompletionProposal.METHOD_DECLARATION : 8725 buffer.append("METHOD_DECLARATION"); break; 8727 case CompletionProposal.METHOD_REF : 8728 buffer.append("METHOD_REF"); break; 8730 case CompletionProposal.PACKAGE_REF : 8731 buffer.append("PACKAGE_REF"); break; 8733 case CompletionProposal.TYPE_REF : 8734 buffer.append("TYPE_REF"); break; 8736 case CompletionProposal.VARIABLE_DECLARATION : 8737 buffer.append("VARIABLE_DECLARATION"); break; 8739 case CompletionProposal.POTENTIAL_METHOD_DECLARATION : 8740 buffer.append("POTENTIAL_METHOD_DECLARATION"); break; 8742 case CompletionProposal.METHOD_NAME_REFERENCE : 8743 buffer.append("METHOD_NAME_REFERENCE"); break; 8745 case CompletionProposal.ANNOTATION_ATTRIBUTE_REF : 8746 buffer.append("ANNOTATION_ATTRIBUT_REF"); break; 8748 case CompletionProposal.FIELD_IMPORT : 8749 buffer.append("FIELD_IMPORT"); break; 8751 case CompletionProposal.METHOD_IMPORT : 8752 buffer.append("METHOD_IMPORT"); break; 8754 case CompletionProposal.TYPE_IMPORT : 8755 buffer.append("TYPE_IMPORT"); break; 8757 default : 8758 buffer.append("PROPOSAL"); break; 8760 8761 } 8762 8763 buffer.append("{\n"); printDebugTab(tab, buffer); 8765 buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); printDebugTab(tab, buffer); 8767 buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); printDebugTab(tab, buffer); 8769 buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); printDebugTab(tab, buffer); 8771 buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); printDebugTab(tab, buffer); 8773 buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); printDebugTab(tab, buffer); 8775 buffer.append("\tName[").append(proposal.getName() == null ? "null".toCharArray() : proposal.getName()).append("]\n"); 8777 printDebugTab(tab, buffer); 8778 buffer.append("\tFlags["); int flags = proposal.getFlags(); 8780 buffer.append(Flags.toString(flags)); 8781 if((flags & Flags.AccInterface) != 0) buffer.append("interface "); if((flags & Flags.AccEnum) != 0) buffer.append("enum "); buffer.append("]\n"); 8785 CompletionProposal[] proposals = proposal.getRequiredProposals(); 8786 if(proposals != null) { 8787 printDebugTab(tab, buffer); 8788 buffer.append("\tRequiredProposals["); for (int i = 0; i < proposals.length; i++) { 8790 buffer.append("\n"); printDebug(proposals[i], tab + 2, buffer); 8792 } 8793 printDebugTab(tab, buffer); 8794 buffer.append("\n\t]\n"); } 8796 8797 printDebugTab(tab, buffer); 8798 buffer.append("\tCompletionLocation[").append(proposal.getCompletionLocation()).append("]\n"); int start = proposal.getReplaceStart(); 8800 int end = proposal.getReplaceEnd(); 8801 printDebugTab(tab, buffer); 8802 buffer.append("\tReplaceStart[").append(start).append("]"); buffer.append("-ReplaceEnd[").append(end).append("]\n"); if (this.source != null) { 8805 printDebugTab(tab, buffer); 8806 buffer.append("\tReplacedText[").append(this.source, start, end-start).append("]\n"); } 8808 printDebugTab(tab, buffer); 8809 buffer.append("\tTokenStart[").append(proposal.getTokenStart()).append("]"); buffer.append("-TokenEnd[").append(proposal.getTokenEnd()).append("]\n"); printDebugTab(tab, buffer); 8812 buffer.append("\tRelevance[").append(proposal.getRelevance()).append("]\n"); 8814 printDebugTab(tab, buffer); 8815 buffer.append("}\n"); } 8817 8818 private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) { 8819 char[][] substituedParameterNames = new char[typeVariables.length][]; 8820 8821 for (int i = 0; i < substituedParameterNames.length; i++) { 8822 substituedParameterNames[i] = typeVariables[i].sourceName; 8823 } 8824 8825 boolean foundConflicts = false; 8826 8827 nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) { 8828 TypeVariableBinding typeVariableBinding = typeVariables[i]; 8829 char[] methodParameterName = typeVariableBinding.sourceName; 8830 8831 for (int j = 0; j < excludedNames.length; j++) { 8832 char[] typeParameterName = excludedNames[j]; 8833 if(CharOperation.equals(typeParameterName, methodParameterName, false)) { 8834 char[] substitution; 8835 if(methodParameterName.length == 1) { 8836 if(ScannerHelper.isUpperCase(methodParameterName[0])) { 8837 substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames); 8838 } else { 8839 substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames); 8840 } 8841 } else { 8842 substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames); 8843 } 8844 substituedParameterNames[i] = substitution; 8845 8846 foundConflicts = true; 8847 continue nextTypeParameter; 8848 } 8849 } 8850 } 8851 8852 if(foundConflicts) return substituedParameterNames; 8853 return null; 8854 } 8855 8856 private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) { 8857 char name = firstName; 8858 next : while (true) { 8859 for (int i = 0 ; i < excludedNames.length ; i++){ 8860 if(excludedNames[i].length == 1 && ScannerHelper.toLowerCase(excludedNames[i][0]) == ScannerHelper.toLowerCase(name)) { 8861 name++; 8862 if(name > endChar) 8863 name = startChar; 8864 if(name == firstName) 8865 return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames); 8866 continue next; 8867 } 8868 } 8869 8870 for (int i = 0; i < otherParameterNames.length; i++) { 8871 if(otherParameterNames[i].length == 1 && ScannerHelper.toLowerCase(otherParameterNames[i][0]) == ScannerHelper.toLowerCase(name)) { 8872 name++; 8873 if(name > endChar) 8874 name = startChar; 8875 if(name == firstName) 8876 return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames); 8877 continue next; 8878 } 8879 } 8880 break next; 8881 } 8882 return new char[]{name}; 8883 } 8884 8885 private char[] substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames) { 8886 char[] name = firstName; 8887 int count = 2; 8888 next : while(true) { 8889 for(int k = 0 ; k < excludedNames.length ; k++){ 8890 if(CharOperation.equals(name, excludedNames[k], false)) { 8891 name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray()); 8892 continue next; 8893 } 8894 } 8895 for (int i = 0; i < otherParameterNames.length; i++) { 8896 if(CharOperation.equals(name, otherParameterNames[i], false)) { 8897 name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray()); 8898 continue next; 8899 } 8900 } 8901 break next; 8902 } 8903 return name; 8904 } 8905} | Popular Tags |