| 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 = CharOperatio
|