1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Timo Kinnunen - Contributions for bug 377373 - [subwords] known limitations with JDT 3.8 13 * Bug 420953 - [subwords] Constructors that don't match prefix not found 14 * IBM Corporation - initial API and implementation 15 * Stephan Herrmann - Contribution for 16 * Bug 400874 - [1.8][compiler] Inference infrastructure should evolve to meet JLS8 18.x (Part G of JSR335 spec) 17 * Gábor Kövesdán - Contribution for Bug 350000 - [content assist] Include non-prefix matches in auto-complete suggestions 18 *******************************************************************************/ 19 package org.eclipse.jdt.internal.codeassist; 20 21 import java.util.ArrayList; 22 import java.util.Arrays; 23 import java.util.Collections; 24 import java.util.HashSet; 25 import java.util.LinkedHashSet; 26 import java.util.List; 27 import java.util.Locale; 28 import java.util.Map; 29 30 import org.eclipse.core.runtime.CoreException; 31 import org.eclipse.core.runtime.IProgressMonitor; 32 import org.eclipse.core.runtime.OperationCanceledException; 33 import org.eclipse.jdt.core.CompletionContext; 34 import org.eclipse.jdt.core.CompletionFlags; 35 import org.eclipse.jdt.core.CompletionProposal; 36 import org.eclipse.jdt.core.CompletionRequestor; 37 import org.eclipse.jdt.core.Flags; 38 import org.eclipse.jdt.core.IAccessRule; 39 import org.eclipse.jdt.core.IJavaElement; 40 import org.eclipse.jdt.core.IJavaProject; 41 import org.eclipse.jdt.core.IMethod; 42 import org.eclipse.jdt.core.IModuleDescription; 43 import org.eclipse.jdt.core.IPackageFragmentRoot; 44 import org.eclipse.jdt.core.IType; 45 import org.eclipse.jdt.core.ITypeHierarchy; 46 import org.eclipse.jdt.core.ITypeRoot; 47 import org.eclipse.jdt.core.JavaCore; 48 import org.eclipse.jdt.core.JavaModelException; 49 import org.eclipse.jdt.core.Signature; 50 import org.eclipse.jdt.core.WorkingCopyOwner; 51 import org.eclipse.jdt.core.compiler.CategorizedProblem; 52 import org.eclipse.jdt.core.compiler.CharOperation; 53 import org.eclipse.jdt.core.compiler.IProblem; 54 import org.eclipse.jdt.core.compiler.InvalidInputException; 55 import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; 56 import org.eclipse.jdt.core.search.IJavaSearchConstants; 57 import org.eclipse.jdt.core.search.IJavaSearchScope; 58 import org.eclipse.jdt.core.search.SearchEngine; 59 import org.eclipse.jdt.core.search.SearchMatch; 60 import org.eclipse.jdt.core.search.SearchParticipant; 61 import org.eclipse.jdt.core.search.SearchPattern; 62 import org.eclipse.jdt.core.search.SearchRequestor; 63 import org.eclipse.jdt.internal.codeassist.complete.AssistNodeParentAnnotationArrayInitializer; 64 import org.eclipse.jdt.internal.codeassist.complete.CompletionJavadoc; 65 import org.eclipse.jdt.internal.codeassist.complete.CompletionNodeDetector; 66 import org.eclipse.jdt.internal.codeassist.complete.CompletionNodeFound; 67 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnAnnotationOfType; 68 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnArgumentName; 69 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnBranchStatementLabel; 70 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnClassLiteralAccess; 71 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnExplicitConstructorCall; 72 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldName; 73 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldType; 74 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnImportReference; 75 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadoc; 76 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocAllocationExpression; 77 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocFieldReference; 78 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocMessageSend; 79 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocParamNameReference; 80 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocQualifiedTypeReference; 81 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocSingleTypeReference; 82 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocTag; 83 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnJavadocTypeParamReference; 84 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword; 85 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeyword3; 86 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeywordModuleDeclaration; 87 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnKeywordModuleInfo; 88 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnLocalName; 89 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMarkerAnnotationName; 90 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMemberAccess; 91 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMemberValueName; 92 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMessageSend; 93 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMessageSendName; 94 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodName; 95 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnMethodReturnType; 96 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnModuleDeclaration; 97 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnModuleReference; 98 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnPackageReference; 99 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnPackageVisibilityReference; 100 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnParameterizedQualifiedTypeReference; 101 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnProvidesImplementationsQualifiedTypeReference; 102 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnProvidesImplementationsSingleTypeReference; 103 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnProvidesInterfacesQualifiedTypeReference; 104 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnProvidesInterfacesSingleTypeReference; 105 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedAllocationExpression; 106 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedNameReference; 107 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedTypeReference; 108 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnReferenceExpressionName; 109 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameReference; 110 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleTypeReference; 111 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnStringLiteral; 112 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnUsesQualifiedTypeReference; 113 import org.eclipse.jdt.internal.codeassist.complete.CompletionOnUsesSingleTypeReference; 114 import org.eclipse.jdt.internal.codeassist.complete.CompletionParser; 115 import org.eclipse.jdt.internal.codeassist.complete.CompletionScanner; 116 import org.eclipse.jdt.internal.codeassist.complete.InvalidCursorLocation; 117 import org.eclipse.jdt.internal.codeassist.impl.AssistParser; 118 import org.eclipse.jdt.internal.codeassist.impl.Engine; 119 import org.eclipse.jdt.internal.codeassist.impl.Keywords; 120 import org.eclipse.jdt.internal.compiler.CompilationResult; 121 import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; 122 import org.eclipse.jdt.internal.compiler.ExtraFlags; 123 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 124 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 125 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; 126 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; 127 import org.eclipse.jdt.internal.compiler.ast.Annotation; 128 import org.eclipse.jdt.internal.compiler.ast.Argument; 129 import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; 130 import org.eclipse.jdt.internal.compiler.ast.ArrayReference; 131 import org.eclipse.jdt.internal.compiler.ast.AssertStatement; 132 import org.eclipse.jdt.internal.compiler.ast.Assignment; 133 import org.eclipse.jdt.internal.compiler.ast.BinaryExpression; 134 import org.eclipse.jdt.internal.compiler.ast.CaseStatement; 135 import org.eclipse.jdt.internal.compiler.ast.CastExpression; 136 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; 137 import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression; 138 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; 139 import org.eclipse.jdt.internal.compiler.ast.Expression; 140 import org.eclipse.jdt.internal.compiler.ast.ExpressionContext; 141 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 142 import org.eclipse.jdt.internal.compiler.ast.FieldReference; 143 import org.eclipse.jdt.internal.compiler.ast.ForStatement; 144 import org.eclipse.jdt.internal.compiler.ast.IfStatement; 145 import org.eclipse.jdt.internal.compiler.ast.ImportReference; 146 import org.eclipse.jdt.internal.compiler.ast.Initializer; 147 import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression; 148 import org.eclipse.jdt.internal.compiler.ast.Javadoc; 149 import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference; 150 import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference; 151 import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference; 152 import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; 153 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; 154 import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; 155 import org.eclipse.jdt.internal.compiler.ast.MessageSend; 156 import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; 157 import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration; 158 import org.eclipse.jdt.internal.compiler.ast.ModuleReference; 159 import org.eclipse.jdt.internal.compiler.ast.NameReference; 160 import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; 161 import org.eclipse.jdt.internal.compiler.ast.OperatorExpression; 162 import org.eclipse.jdt.internal.compiler.ast.OperatorIds; 163 import org.eclipse.jdt.internal.compiler.ast.PackageVisibilityStatement; 164 import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; 165 import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; 166 import org.eclipse.jdt.internal.compiler.ast.ProvidesStatement; 167 import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; 168 import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; 169 import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; 170 import org.eclipse.jdt.internal.compiler.ast.RequiresStatement; 171 import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; 172 import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; 173 import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; 174 import org.eclipse.jdt.internal.compiler.ast.SuperReference; 175 import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; 176 import org.eclipse.jdt.internal.compiler.ast.ThisReference; 177 import org.eclipse.jdt.internal.compiler.ast.TryStatement; 178 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 179 import org.eclipse.jdt.internal.compiler.ast.TypeParameter; 180 import org.eclipse.jdt.internal.compiler.ast.TypeReference; 181 import org.eclipse.jdt.internal.compiler.ast.UnaryExpression; 182 import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference; 183 import org.eclipse.jdt.internal.compiler.ast.UsesStatement; 184 import org.eclipse.jdt.internal.compiler.ast.WhileStatement; 185 import org.eclipse.jdt.internal.compiler.ast.Wildcard; 186 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 187 import org.eclipse.jdt.internal.compiler.env.AccessRestriction; 188 import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; 189 import org.eclipse.jdt.internal.compiler.env.INameEnvironment; 190 import org.eclipse.jdt.internal.compiler.env.ISourceType; 191 import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; 192 import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; 193 import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; 194 import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding; 195 import org.eclipse.jdt.internal.compiler.lookup.Binding; 196 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 197 import org.eclipse.jdt.internal.compiler.lookup.ClassScope; 198 import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; 199 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; 200 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 201 import org.eclipse.jdt.internal.compiler.lookup.ImportBinding; 202 import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18; 203 import org.eclipse.jdt.internal.compiler.lookup.InvocationSite; 204 import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; 205 import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; 206 import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; 207 import org.eclipse.jdt.internal.compiler.lookup.MethodScope; 208 import org.eclipse.jdt.internal.compiler.lookup.PackageBinding; 209 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding; 210 import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding; 211 import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; 212 import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; 213 import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; 214 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 215 import org.eclipse.jdt.internal.compiler.lookup.Scope; 216 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding; 217 import org.eclipse.jdt.internal.compiler.lookup.TagBits; 218 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 219 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 220 import org.eclipse.jdt.internal.compiler.lookup.TypeIds; 221 import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding; 222 import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; 223 import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding; 224 import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants; 225 import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; 226 import org.eclipse.jdt.internal.compiler.parser.SourceTypeConverter; 227 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; 228 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 229 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; 230 import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; 231 import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; 232 import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; 233 import org.eclipse.jdt.internal.compiler.util.ObjectVector; 234 import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray; 235 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 236 import org.eclipse.jdt.internal.core.BasicCompilationUnit; 237 import org.eclipse.jdt.internal.core.BinaryTypeConverter; 238 import org.eclipse.jdt.internal.core.INamingRequestor; 239 import org.eclipse.jdt.internal.core.InternalNamingConventions; 240 import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; 241 import org.eclipse.jdt.internal.core.JavaElementRequestor; 242 import org.eclipse.jdt.internal.core.JavaModelManager; 243 import org.eclipse.jdt.internal.core.ModuleSourcePathManager; 244 import org.eclipse.jdt.internal.core.SearchableEnvironment; 245 import org.eclipse.jdt.internal.core.SourceMethod; 246 import org.eclipse.jdt.internal.core.SourceMethodElementInfo; 247 import org.eclipse.jdt.internal.core.SourceType; 248 import org.eclipse.jdt.internal.core.SourceTypeElementInfo; 249 import org.eclipse.jdt.internal.core.search.BasicSearchEngine; 250 import org.eclipse.jdt.internal.core.search.matching.IndexBasedJavaSearchEnvironment; 251 import org.eclipse.jdt.internal.core.util.Messages; 252 import org.eclipse.jdt.internal.core.util.Util; 253 254 /** 255 * This class is the entry point for source completions. 256 * It contains two public APIs used to call CodeAssist on a given source with 257 * a given environment, assisting position and storage (and possibly options). 258 */ 259 @SuppressWarnings({ "rawtypes", "unchecked" }) 260 public final class CompletionEngine 261 extends Engine 262 implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants { 263 264 private static class AcceptedConstructor { 265 public int modifiers; 266 public char[] simpleTypeName; 267 public int parameterCount; 268 public char[] signature; 269 public char[][] parameterTypes; 270 public char[][] parameterNames; 271 public int typeModifiers; 272 public char[] packageName; 273 public int extraFlags; 274 public int accessibility; 275 public boolean proposeType = false; 276 public boolean proposeConstructor = false; 277 public char[] fullyQualifiedName = null; 278 279 public boolean mustBeQualified = false; 280 AcceptedConstructor( int modifiers, char[] simpleTypeName, int parameterCount, char[] signature, char[][] parameterTypes, char[][] parameterNames, int typeModifiers, char[] packageName, int extraFlags, int accessibility)281 public AcceptedConstructor( 282 int modifiers, 283 char[] simpleTypeName, 284 int parameterCount, 285 char[] signature, 286 char[][] parameterTypes, 287 char[][] parameterNames, 288 int typeModifiers, 289 char[] packageName, 290 int extraFlags, 291 int accessibility) { 292 this.modifiers = modifiers; 293 this.simpleTypeName = simpleTypeName; 294 this.parameterCount = parameterCount; 295 this.signature = signature; 296 this.parameterTypes = parameterTypes; 297 this.parameterNames = parameterNames; 298 this.typeModifiers = typeModifiers; 299 this.packageName = packageName; 300 this.extraFlags = extraFlags; 301 this.accessibility = accessibility; 302 } 303 304 @Override toString()305 public String toString() { 306 StringBuffer buffer = new StringBuffer(); 307 buffer.append('{'); 308 buffer.append(this.packageName); 309 buffer.append(','); 310 buffer.append(this.simpleTypeName); 311 buffer.append('}'); 312 return buffer.toString(); 313 } 314 } 315 316 private static class AcceptedType { 317 public char[] packageName; 318 public char[] simpleTypeName; 319 public char[][] enclosingTypeNames; 320 public int modifiers; 321 public int accessibility; 322 public boolean mustBeQualified = false; 323 324 public char[] fullyQualifiedName = null; 325 public char[] qualifiedTypeName = null; AcceptedType( char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, int accessibility)326 public AcceptedType( 327 char[] packageName, 328 char[] simpleTypeName, 329 char[][] enclosingTypeNames, 330 int modifiers, 331 int accessibility) { 332 this.packageName = packageName; 333 this.simpleTypeName = simpleTypeName; 334 this.enclosingTypeNames = enclosingTypeNames; 335 this.modifiers = modifiers; 336 this.accessibility = accessibility; 337 } 338 339 @Override toString()340 public String toString() { 341 StringBuffer buffer = new StringBuffer(); 342 buffer.append('{'); 343 buffer.append(this.packageName); 344 buffer.append(','); 345 buffer.append(this.simpleTypeName); 346 buffer.append(','); 347 buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.')); 348 buffer.append('}'); 349 return buffer.toString(); 350 } 351 } 352 353 public class CompletionProblemFactory extends DefaultProblemFactory { 354 private int lastErrorStart; 355 356 private boolean checkProblems = false; 357 public boolean hasForbiddenProblems = false; 358 public boolean hasAllowedProblems = false; 359 CompletionProblemFactory(Locale loc)360 public CompletionProblemFactory(Locale loc) { 361 super(loc); 362 } 363 checkProblem(CategorizedProblem pb, char[] originatingFileName, int severity, int start)364 private CategorizedProblem checkProblem(CategorizedProblem pb, 365 char[] originatingFileName, int severity, int start) { 366 int id = pb.getID(); 367 if (CompletionEngine.this.actualCompletionPosition > start 368 && this.lastErrorStart < start 369 && pb.isError() 370 && (id & IProblem.Syntax) == 0 371 && (CompletionEngine.this.fileName == null || CharOperation.equals(CompletionEngine.this.fileName, originatingFileName))) { 372 373 CompletionEngine.this.problem = pb; 374 this.lastErrorStart = start; 375 } 376 if (this.checkProblems && !this.hasForbiddenProblems) { 377 switch (id) { 378 case IProblem.UsingDeprecatedType: 379 this.hasForbiddenProblems = 380 CompletionEngine.this.options.checkDeprecation; 381 break; 382 case IProblem.NotVisibleType: 383 this.hasForbiddenProblems = 384 CompletionEngine.this.options.checkVisibility; 385 break; 386 case IProblem.ForbiddenReference: 387 this.hasForbiddenProblems = 388 CompletionEngine.this.options.checkForbiddenReference; 389 break; 390 case IProblem.DiscouragedReference: 391 this.hasForbiddenProblems = 392 CompletionEngine.this.options.checkDiscouragedReference; 393 break; 394 default: 395 if ((severity & ProblemSeverities.Optional) != 0) { 396 this.hasAllowedProblems = true; 397 } else { 398 this.hasForbiddenProblems = true; 399 } 400 401 break; 402 } 403 } 404 405 return pb; 406 } 407 408 @Override createProblem( char[] originatingFileName, int problemId, String[] problemArguments, int elaborationId, String[] messageArguments, int severity, int start, int end, int lineNumber, int columnNumber)409 public CategorizedProblem createProblem( 410 char[] originatingFileName, 411 int problemId, 412 String[] problemArguments, 413 int elaborationId, 414 String[] messageArguments, 415 int severity, 416 int start, 417 int end, 418 int lineNumber, 419 int columnNumber) { 420 return checkProblem( 421 super.createProblem( 422 originatingFileName, 423 problemId, 424 problemArguments, 425 elaborationId, 426 messageArguments, 427 severity, 428 start, 429 end, 430 lineNumber, 431 columnNumber), originatingFileName, severity, start); 432 } 433 434 @Override createProblem( char[] originatingFileName, int problemId, String[] problemArguments, String[] messageArguments, int severity, int start, int end, int lineNumber, int columnNumber)435 public CategorizedProblem createProblem( 436 char[] originatingFileName, 437 int problemId, 438 String[] problemArguments, 439 String[] messageArguments, 440 int severity, 441 int start, 442 int end, 443 int lineNumber, 444 int columnNumber) { 445 return checkProblem( 446 super.createProblem( 447 originatingFileName, 448 problemId, 449 problemArguments, 450 messageArguments, 451 severity, 452 start, 453 end, 454 lineNumber, 455 columnNumber), originatingFileName, severity, start); 456 } 457 startCheckingProblems()458 public void startCheckingProblems() { 459 this.checkProblems = true; 460 this.hasForbiddenProblems = false; 461 this.hasAllowedProblems = false; 462 } 463 stopCheckingProblems()464 public void stopCheckingProblems() { 465 this.checkProblems = false; 466 } 467 } 468 createBindingKey(char[] packageName, char[] typeName)469 public static char[] createBindingKey(char[] packageName, char[] typeName) { 470 char[] signature = createTypeSignature(packageName, typeName); 471 CharOperation.replace(signature, '.', '/'); 472 return signature; 473 } 474 createDefaultParameterNames(int length)475 public static char[][] createDefaultParameterNames(int length) { 476 char[][] parameters; 477 switch (length) { 478 case 0 : 479 parameters = new char[length][]; 480 break; 481 case 1 : 482 parameters = ARGS1; 483 break; 484 case 2 : 485 parameters = ARGS2; 486 break; 487 case 3 : 488 parameters = ARGS3; 489 break; 490 case 4 : 491 parameters = ARGS4; 492 break; 493 default : 494 parameters = new char[length][]; 495 for (int i = 0; i < length; i++) { 496 parameters[i] = CharOperation.concat(ARG, String.valueOf(i).toCharArray()); 497 } 498 break; 499 } 500 return parameters; 501 } createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature)502 public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) { 503 char[][] parameterTypeSignature = new char[parameterTypeNames.length][]; 504 for (int i = 0; i < parameterTypeSignature.length; i++) { 505 parameterTypeSignature[i] = 506 Signature.createCharArrayTypeSignature( 507 CharOperation.concat( 508 parameterPackageNames[i], 509 CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true); 510 } 511 512 return Signature.createMethodSignature( 513 parameterTypeSignature, 514 returnTypeSignature); 515 } 516 createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName)517 public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) { 518 char[] returnTypeSignature = 519 returnTypeName == null || returnTypeName.length == 0 520 ? Signature.createCharArrayTypeSignature(VOID, true) 521 : Signature.createCharArrayTypeSignature( 522 CharOperation.concat( 523 returnPackagename, 524 CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true); 525 526 return createMethodSignature( 527 parameterPackageNames, 528 parameterTypeNames, 529 returnTypeSignature); 530 } createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName)531 public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) { 532 return Signature.createCharArrayTypeSignature( 533 CharOperation.concat( 534 qualifiedPackageName, 535 CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true); 536 } 537 createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName)538 public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) { 539 char[] name = new char[qualifiedTypeName.length]; 540 System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length); 541 542 int depth = 0; 543 int length = name.length; 544 for (int i = length -1; i >= 0; i--) { 545 switch (name[i]) { 546 case '.': 547 if (depth == 0 && name[i - 1] != '>') { 548 name[i] = '$'; 549 } 550 break; 551 case '<': 552 depth--; 553 break; 554 case '>': 555 depth++; 556 break; 557 } 558 } 559 return Signature.createCharArrayTypeSignature( 560 CharOperation.concat( 561 qualifiedPackageName, 562 name, '.'), true); 563 } 564 getRequiredTypeSignature(TypeBinding typeBinding)565 private static char[] getRequiredTypeSignature(TypeBinding typeBinding) { 566 char[] result = null; 567 StringBuffer sig = new StringBuffer(10); 568 569 sig.append(typeBinding.signature()); 570 571 int sigLength = sig.length(); 572 result = new char[sigLength]; 573 sig.getChars(0, sigLength, result, 0); 574 result = CharOperation.replaceOnCopy(result, '/', '.'); 575 return result; 576 } 577 getTypeName(TypeReference typeReference)578 private static char[] getTypeName(TypeReference typeReference) { 579 char[] typeName = CharOperation.concatWith(typeReference.getTypeName(), '.'); 580 int dims = typeReference.dimensions(); 581 if (dims > 0) { 582 int length = typeName.length; 583 int newLength = length + (dims*2); 584 System.arraycopy(typeName, 0, typeName = new char[newLength], 0, length); 585 for (int k = length; k < newLength; k += 2) { 586 typeName[k] = '['; 587 typeName[k+1] = ']'; 588 } 589 } 590 591 return typeName; 592 } 593 hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope)594 private static boolean hasStaticMemberTypes(ReferenceBinding typeBinding, SourceTypeBinding invocationType, CompilationUnitScope unitScope) { 595 ReferenceBinding[] memberTypes = typeBinding.memberTypes(); 596 int length = memberTypes == null ? 0 : memberTypes.length; 597 next : for (int i = 0; i < length; i++) { 598 ReferenceBinding memberType = memberTypes[i]; 599 if (invocationType != null && !memberType.canBeSeenBy(typeBinding, invocationType)) { 600 continue next; 601 } else if(invocationType == null && !memberType.canBeSeenBy(unitScope.fPackage)) { 602 continue next; 603 } 604 605 if ((memberType.modifiers & ClassFileConstants.AccStatic) != 0) { 606 return true; 607 } 608 } 609 return false; 610 } 611 hasMemberTypesInEnclosingScope(SourceTypeBinding typeBinding, Scope scope)612 private static boolean hasMemberTypesInEnclosingScope(SourceTypeBinding typeBinding, Scope scope) { 613 ReferenceBinding[] memberTypes = typeBinding.memberTypes(); 614 int length = memberTypes == null ? 0 : memberTypes.length; 615 616 if (length > 0) { 617 MethodScope methodScope = scope.methodScope(); 618 if (methodScope != null && !methodScope.isStatic) { 619 ClassScope classScope = typeBinding.scope; 620 Scope currentScope = scope; 621 while (currentScope != null) { 622 if (currentScope == classScope) { 623 return true; 624 } 625 currentScope = currentScope.parent; 626 } 627 } 628 } 629 return false; 630 } 631 632 public HashtableOfObject typeCache; 633 public int openedBinaryTypes; // used during InternalCompletionProposal#findConstructorParameterNames() 634 635 public static boolean DEBUG = false; 636 public static boolean PERF = false; 637 638 private static final char[] KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS = new char[]{}; 639 private static final char[] KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS = new char[]{}; 640 641 private static final char[] ARG = "arg".toCharArray(); //$NON-NLS-1$ 642 private static final char[] ARG0 = "arg0".toCharArray(); //$NON-NLS-1$ 643 private static final char[] ARG1 = "arg1".toCharArray(); //$NON-NLS-1$ 644 private static final char[] ARG2 = "arg2".toCharArray(); //$NON-NLS-1$ 645 private static final char[] ARG3 = "arg3".toCharArray(); //$NON-NLS-1$ 646 private static final char[][] ARGS1 = new char[][]{ARG0}; 647 private static final char[][] ARGS2 = new char[][]{ARG0, ARG1}; 648 private static final char[][] ARGS3 = new char[][]{ARG0, ARG1, ARG2}; 649 private static final char[][] ARGS4 = new char[][]{ARG0, ARG1, ARG2, ARG3}; 650 651 private final static int CHECK_CANCEL_FREQUENCY = 50; 652 653 // temporary constants to quickly disabled polish features if necessary 654 public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false; 655 656 private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$ 657 private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$ 658 private final static char[] SEMICOLON = new char[] { ';' }; 659 660 private final static char[] CLASS = "Class".toCharArray(); //$NON-NLS-1$ 661 private final static char[] VOID = "void".toCharArray(); //$NON-NLS-1$ 662 private final static char[] INT = "int".toCharArray(); //$NON-NLS-1$ 663 private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT}; 664 private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$ 665 private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$ 666 private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$ 667 private final static char[] DEFAULT_CONSTRUCTOR_SIGNATURE = "()V".toCharArray(); //$NON-NLS-1$ 668 669 private final static char[] DOT = ".".toCharArray(); //$NON-NLS-1$ 670 671 private final static char[] VARARGS = "...".toCharArray(); //$NON-NLS-1$ 672 673 private final static char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$ 674 private final static char[] STATIC = "static".toCharArray(); //$NON-NLS-1$ 675 private final static char[] ON_DEMAND = ".*".toCharArray(); //$NON-NLS-1$ 676 private final static char[] IMPORT_END = ";\n".toCharArray(); //$NON-NLS-1$ 677 678 private final static char[] JAVA_LANG_OBJECT_SIGNATURE = 679 createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT); 680 private final static char[] JAVA_LANG_NAME = 681 CharOperation.concatWith(JAVA_LANG, '.'); 682 683 private final static int NONE = 0; 684 private final static int SUPERTYPE = 1; 685 private final static int SUBTYPE = 2; 686 687 int expectedTypesPtr = -1; 688 TypeBinding[] expectedTypes = new TypeBinding[1]; 689 int expectedTypesFilter; 690 boolean hasJavaLangObjectAsExpectedType = false; 691 boolean hasExpectedArrayTypes = false; 692 boolean hasComputedExpectedArrayTypes = false; 693 int uninterestingBindingsPtr = -1; 694 Binding[] uninterestingBindings = new Binding[1]; 695 int forbbidenBindingsPtr = -1; 696 Binding[] forbbidenBindings = new Binding[1]; 697 int uninterestingBindingsFilter; // only set when completing on an exception type 698 699 ImportBinding[] favoriteReferenceBindings; 700 701 boolean assistNodeIsClass; 702 boolean assistNodeIsEnum; 703 boolean assistNodeIsException; 704 boolean assistNodeIsInterface; 705 boolean assistNodeIsAnnotation; 706 boolean assistNodeIsConstructor; 707 boolean assistNodeIsSuperType; 708 boolean assistNodeIsExtendedType; 709 boolean assistNodeIsInterfaceExcludingAnnotation; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423 710 int assistNodeInJavadoc = 0; 711 boolean assistNodeCanBeSingleMemberAnnotation = false; 712 boolean assistNodeIsInsideCase = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346 713 boolean assistNodeIsString = false; // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476 714 715 long targetedElement; 716 717 WorkingCopyOwner owner; 718 IProgressMonitor monitor; 719 IJavaProject javaProject; 720 ITypeRoot typeRoot; 721 CompletionParser parser; 722 CompletionRequestor requestor; 723 CompletionProblemFactory problemFactory; 724 ProblemReporter problemReporter; 725 private INameEnvironment noCacheNameEnvironment; 726 char[] source; 727 ModuleDeclaration moduleDeclaration; 728 boolean skipDefaultPackage = false; 729 char[] completionToken; 730 731 char[] qualifiedCompletionToken; 732 boolean resolvingImports = false; 733 boolean resolvingStaticImports = false; 734 boolean insideQualifiedReference = false; 735 boolean noProposal = true; 736 CategorizedProblem problem = null; 737 char[] fileName = null; 738 int startPosition, actualCompletionPosition, endPosition, offset; 739 int tokenStart, tokenEnd; 740 int javadocTagPosition; // Position of previous tag while completing in javadoc 741 String sourceLevel; 742 String complianceLevel; 743 SimpleSetOfCharArray validPackageNames = new SimpleSetOfCharArray(10); 744 SimpleSetOfCharArray invalidPackageNames = new SimpleSetOfCharArray(1); 745 HashtableOfObject knownModules = new HashtableOfObject(10); 746 HashtableOfObject knownPkgs = new HashtableOfObject(10); 747 HashtableOfObject knownTypes = new HashtableOfObject(10); 748 749 /* 750 static final char[][] mainDeclarations = 751 new char[][] { 752 "package".toCharArray(), 753 "import".toCharArray(), 754 "abstract".toCharArray(), 755 "final".toCharArray(), 756 "public".toCharArray(), 757 "class".toCharArray(), 758 "interface".toCharArray()}; 759 760 static final char[][] modifiers = // may want field, method, type & member type modifiers 761 new char[][] { 762 "abstract".toCharArray(), 763 "final".toCharArray(), 764 "native".toCharArray(), 765 "public".toCharArray(), 766 "protected".toCharArray(), 767 "private".toCharArray(), 768 "static".toCharArray(), 769 "strictfp".toCharArray(), 770 "synchronized".toCharArray(), 771 "transient".toCharArray(), 772 "volatile".toCharArray()}; 773 */ 774 static final BaseTypeBinding[] BASE_TYPES = { 775 TypeBinding.BOOLEAN, 776 TypeBinding.BYTE, 777 TypeBinding.CHAR, 778 TypeBinding.DOUBLE, 779 TypeBinding.FLOAT, 780 TypeBinding.INT, 781 TypeBinding.LONG, 782 TypeBinding.SHORT, 783 TypeBinding.VOID 784 }; 785 static final int BASE_TYPES_LENGTH = BASE_TYPES.length; 786 static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][]; 787 static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1; 788 static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][]; 789 static { 790 for (int i=0; i<BASE_TYPES_LENGTH; i++) { 791 BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName; 792 } 793 for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) { 794 BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName; 795 } 796 } 797 798 static final char[] classField = "class".toCharArray(); //$NON-NLS-1$ 799 static final char[] lengthField = "length".toCharArray(); //$NON-NLS-1$ 800 static final char[] cloneMethod = "clone".toCharArray(); //$NON-NLS-1$ 801 static final char[] THIS = "this".toCharArray(); //$NON-NLS-1$ 802 static final char[] THROWS = "throws".toCharArray(); //$NON-NLS-1$ 803 804 static InvocationSite FakeInvocationSite = new InvocationSite(){ 805 @Override 806 public TypeBinding[] genericTypeArguments() { return null; } 807 @Override 808 public boolean isSuperAccess(){ return false; } 809 @Override 810 public boolean isTypeAccess(){ return false; } 811 @Override 812 public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */} 813 @Override 814 public void setDepth(int depth){/* empty */} 815 @Override 816 public void setFieldIndex(int depth){/* empty */} 817 @Override 818 public int sourceEnd() { return 0; } 819 @Override 820 public int sourceStart() { return 0; } 821 @Override 822 public TypeBinding invocationTargetType() { return null; } 823 @Override 824 public boolean receiverIsImplicitThis() { return false; } 825 @Override 826 public InferenceContext18 freshInferenceContext(Scope scope) { return null; } 827 @Override 828 public ExpressionContext getExpressionContext() { return ExpressionContext.VANILLA_CONTEXT; } 829 @Override 830 public boolean isQualifiedSuper() { return false; } 831 @Override 832 public boolean checkingPotentialCompatibility() { return false; } 833 @Override 834 public void acceptPotentiallyCompatibleMethods(MethodBinding[] methods) {/* ignore */} 835 }; 836 837 private int foundTypesCount; 838 private ObjectVector acceptedTypes; 839 840 private int foundConstructorsCount; 841 private ObjectVector acceptedConstructors; 842 843 /** 844 * The CompletionEngine is responsible for computing source completions. 845 * 846 * It requires a searchable name environment, which supports some 847 * specific search APIs, and a requestor to feed back the results to a UI. 848 * 849 * @param nameEnvironment org.eclipse.jdt.internal.codeassist.ISearchableNameEnvironment 850 * used to resolve type/package references and search for types/packages 851 * based on partial names. 852 * 853 * @param requestor org.eclipse.jdt.internal.codeassist.ICompletionRequestor 854 * since the engine might produce answers of various forms, the engine 855 * is associated with a requestor able to accept all possible completions. 856 * 857 * @param settings java.util.Map 858 * set of options used to configure the code assist engine. 859 */ CompletionEngine( SearchableEnvironment nameEnvironment, CompletionRequestor requestor, Map settings, IJavaProject javaProject, WorkingCopyOwner owner, IProgressMonitor monitor)860 public CompletionEngine( 861 SearchableEnvironment nameEnvironment, 862 CompletionRequestor requestor, 863 Map settings, 864 IJavaProject javaProject, 865 WorkingCopyOwner owner, 866 IProgressMonitor monitor) { 867 super(settings); 868 this.javaProject = javaProject; 869 this.requestor = requestor; 870 this.nameEnvironment = nameEnvironment; 871 this.typeCache = new HashtableOfObject(5); 872 this.openedBinaryTypes = 0; 873 this.sourceLevel = javaProject.getOption(JavaCore.COMPILER_SOURCE, true); 874 this.complianceLevel = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true); 875 876 this.problemFactory = new CompletionProblemFactory(Locale.getDefault()); 877 this.problemReporter = new ProblemReporter( 878 DefaultErrorHandlingPolicies.proceedWithAllProblems(), 879 this.compilerOptions, 880 this.problemFactory); 881 this.lookupEnvironment = 882 new LookupEnvironment(this, this.compilerOptions, this.problemReporter, nameEnvironment); 883 this.parser = 884 new CompletionParser(this.problemReporter, this.requestor.isExtendedContextRequired(), monitor); 885 this.owner = owner; 886 this.monitor = monitor; 887 } 888 889 @Override accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction)890 public void accept(ICompilationUnit sourceUnit, AccessRestriction accessRestriction) { 891 if (!CharOperation.equals(sourceUnit.getMainTypeName(), TypeConstants.PACKAGE_INFO_NAME)) { 892 // do not accept package-info.java as a type for completion engine 893 // because it contains no extra info that will help in completion 894 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343865 895 // Required after the fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=337868 896 // because now we get a type corresponding to the package-info.java from the java model. 897 super.accept(sourceUnit, accessRestriction); 898 } 899 } 900 901 @Override acceptConstructor( int modifiers, char[] simpleTypeName, int parameterCount, char[] signature, char[][] parameterTypes, char[][] parameterNames, int typeModifiers, char[] packageName, int extraFlags, String path, AccessRestriction accessRestriction)902 public void acceptConstructor( 903 int modifiers, 904 char[] simpleTypeName, 905 int parameterCount, 906 char[] signature, 907 char[][] parameterTypes, 908 char[][] parameterNames, 909 int typeModifiers, 910 char[] packageName, 911 int extraFlags, 912 String path, 913 AccessRestriction accessRestriction) { 914 915 // does not check cancellation for every types to avoid performance loss 916 if ((this.foundConstructorsCount % (CHECK_CANCEL_FREQUENCY)) == 0) checkCancel(); 917 this.foundConstructorsCount++; 918 919 if ((typeModifiers & ClassFileConstants.AccEnum) != 0) return; 920 921 if (this.options.checkDeprecation && (typeModifiers & ClassFileConstants.AccDeprecated) != 0) return; 922 923 if (this.options.checkVisibility) { 924 if((typeModifiers & ClassFileConstants.AccPublic) == 0) { 925 if((typeModifiers & ClassFileConstants.AccPrivate) != 0) return; 926 927 if (this.currentPackageName == null) { 928 initializePackageCache(); 929 } 930 931 if(!CharOperation.equals(packageName, this.currentPackageName)) return; 932 } 933 } 934 935 int accessibility = IAccessRule.K_ACCESSIBLE; 936 if(accessRestriction != null) { 937 switch (accessRestriction.getProblemId()) { 938 case IProblem.ForbiddenReference: 939 if (this.options.checkForbiddenReference) { 940 return; 941 } 942 accessibility = IAccessRule.K_NON_ACCESSIBLE; 943 break; 944 case IProblem.DiscouragedReference: 945 if (this.options.checkDiscouragedReference) { 946 return; 947 } 948 accessibility = IAccessRule.K_DISCOURAGED; 949 break; 950 } 951 } 952 953 if(this.acceptedConstructors == null) { 954 this.acceptedConstructors = new ObjectVector(); 955 } 956 this.acceptedConstructors.add( 957 new AcceptedConstructor( 958 modifiers, 959 simpleTypeName, 960 parameterCount, 961 signature, 962 parameterTypes, 963 parameterNames, 964 typeModifiers, 965 packageName, 966 extraFlags, 967 accessibility)); 968 } 969 acceptConstructors(Scope scope)970 private void acceptConstructors(Scope scope) { 971 final boolean DEFER_QUALIFIED_PROPOSALS = false; 972 973 this.checkCancel(); 974 975 if(this.acceptedConstructors == null) return; 976 977 int length = this.acceptedConstructors.size(); 978 979 if(length == 0) return; 980 981 HashtableOfObject onDemandFound = new HashtableOfObject(); 982 983 ArrayList deferredProposals = null; 984 if (DEFER_QUALIFIED_PROPOSALS) { 985 deferredProposals = new ArrayList(); 986 } 987 988 try { 989 next : for (int i = 0; i < length; i++) { 990 991 // does not check cancellation for every types to avoid performance loss 992 if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 993 994 AcceptedConstructor acceptedConstructor = (AcceptedConstructor)this.acceptedConstructors.elementAt(i); 995 final int typeModifiers = acceptedConstructor.typeModifiers; 996 final char[] packageName = acceptedConstructor.packageName; 997 final char[] simpleTypeName = acceptedConstructor.simpleTypeName; 998 final int modifiers = acceptedConstructor.modifiers; 999 final int parameterCount = acceptedConstructor.parameterCount; 1000 final char[] signature = acceptedConstructor.signature; 1001 final char[][] parameterTypes = acceptedConstructor.parameterTypes; 1002 final char[][] parameterNames = acceptedConstructor.parameterNames; 1003 final int extraFlags = acceptedConstructor.extraFlags; 1004 final int accessibility = acceptedConstructor.accessibility; 1005 1006 boolean proposeType = hasArrayTypeAsExpectedSuperTypes() || (extraFlags & ExtraFlags.HasNonPrivateStaticMemberTypes) != 0; 1007 1008 char[] fullyQualifiedName = CharOperation.concat(packageName, simpleTypeName, '.'); 1009 1010 Object knownTypeKind = this.knownTypes.get(fullyQualifiedName); 1011 if (knownTypeKind != null) { 1012 if (knownTypeKind == KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS) { 1013 // the type and its constructors are already accepted 1014 continue next; 1015 } 1016 // this type is already accepted 1017 proposeType = false; 1018 } else { 1019 this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS); 1020 } 1021 1022 boolean proposeConstructor = true; 1023 1024 if (this.options.checkVisibility) { 1025 if((modifiers & ClassFileConstants.AccPublic) == 0) { 1026 if((modifiers & ClassFileConstants.AccPrivate) != 0) { 1027 if (!proposeType) continue next; 1028 proposeConstructor = false; 1029 } else { 1030 if (this.currentPackageName == null) { 1031 initializePackageCache(); 1032 } 1033 1034 if(!CharOperation.equals(packageName, this.currentPackageName)) { 1035 1036 if((typeModifiers & ClassFileConstants.AccAbstract) == 0 || 1037 (modifiers & ClassFileConstants.AccProtected) == 0) { 1038 if (!proposeType) continue next; 1039 proposeConstructor = false; 1040 } 1041 } 1042 } 1043 } 1044 } 1045 1046 acceptedConstructor.fullyQualifiedName = fullyQualifiedName; 1047 acceptedConstructor.proposeType = proposeType; 1048 acceptedConstructor.proposeConstructor = proposeConstructor; 1049 1050 1051 if(!this.importCachesInitialized) { 1052 initializeImportCaches(); 1053 } 1054 1055 for (int j = 0; j < this.importCacheCount; j++) { 1056 char[][] importName = this.importsCache[j]; 1057 if(CharOperation.equals(simpleTypeName, importName[0])) { 1058 if (proposeType) { 1059 proposeType( 1060 packageName, 1061 simpleTypeName, 1062 typeModifiers, 1063 accessibility, 1064 simpleTypeName, 1065 fullyQualifiedName, 1066 !CharOperation.equals(fullyQualifiedName, importName[1]), 1067 scope); 1068 } 1069 1070 if (proposeConstructor && !Flags.isEnum(typeModifiers)) { 1071 boolean isQualified = !CharOperation.equals(fullyQualifiedName, importName[1]); 1072 if (!isQualified) { 1073 proposeConstructor( 1074 simpleTypeName, 1075 parameterCount, 1076 signature, 1077 parameterTypes, 1078 parameterNames, 1079 modifiers, 1080 packageName, 1081 typeModifiers, 1082 accessibility, 1083 simpleTypeName, 1084 fullyQualifiedName, 1085 isQualified, 1086 scope, 1087 extraFlags); 1088 } else { 1089 acceptedConstructor.mustBeQualified = true; 1090 if (DEFER_QUALIFIED_PROPOSALS) { 1091 deferredProposals.add(acceptedConstructor); 1092 } else { 1093 proposeConstructor(acceptedConstructor, scope); 1094 } 1095 } 1096 } 1097 continue next; 1098 } 1099 } 1100 1101 1102 if (CharOperation.equals(this.currentPackageName, packageName)) { 1103 if (proposeType) { 1104 proposeType( 1105 packageName, 1106 simpleTypeName, 1107 typeModifiers, 1108 accessibility, 1109 simpleTypeName, 1110 fullyQualifiedName, 1111 false, 1112 scope); 1113 } 1114 1115 if (proposeConstructor && !Flags.isEnum(typeModifiers)) { 1116 proposeConstructor( 1117 simpleTypeName, 1118 parameterCount, 1119 signature, 1120 parameterTypes, 1121 parameterNames, 1122 modifiers, 1123 packageName, 1124 typeModifiers, 1125 accessibility, 1126 simpleTypeName, 1127 fullyQualifiedName, 1128 false, 1129 scope, 1130 extraFlags); 1131 } 1132 continue next; 1133 } else { 1134 char[] fullyQualifiedEnclosingTypeOrPackageName = null; 1135 1136 AcceptedConstructor foundConstructor = null; 1137 if((foundConstructor = (AcceptedConstructor)onDemandFound.get(simpleTypeName)) == null) { 1138 for (int j = 0; j < this.onDemandImportCacheCount; j++) { 1139 ImportBinding importBinding = this.onDemandImportsCache[j]; 1140 1141 char[][] importName = importBinding.compoundName; 1142 char[] importFlatName = CharOperation.concatWith(importName, '.'); 1143 1144 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 1145 fullyQualifiedEnclosingTypeOrPackageName = packageName; 1146 } 1147 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 1148 if(importBinding.isStatic()) { 1149 if((typeModifiers & ClassFileConstants.AccStatic) != 0) { 1150 onDemandFound.put( 1151 simpleTypeName, 1152 acceptedConstructor); 1153 continue next; 1154 } 1155 } else { 1156 onDemandFound.put( 1157 simpleTypeName, 1158 acceptedConstructor); 1159 continue next; 1160 } 1161 } 1162 } 1163 } else if(!foundConstructor.mustBeQualified){ 1164 done : for (int j = 0; j < this.onDemandImportCacheCount; j++) { 1165 ImportBinding importBinding = this.onDemandImportsCache[j]; 1166 1167 char[][] importName = importBinding.compoundName; 1168 char[] importFlatName = CharOperation.concatWith(importName, '.'); 1169 1170 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 1171 fullyQualifiedEnclosingTypeOrPackageName = packageName; 1172 } 1173 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 1174 if(importBinding.isStatic()) { 1175 if((typeModifiers & ClassFileConstants.AccStatic) != 0) { 1176 foundConstructor.mustBeQualified = true; 1177 break done; 1178 } 1179 } else { 1180 foundConstructor.mustBeQualified = true; 1181 break done; 1182 } 1183 } 1184 } 1185 } 1186 if (proposeType) { 1187 proposeType( 1188 packageName, 1189 simpleTypeName, 1190 typeModifiers, 1191 accessibility, 1192 simpleTypeName, 1193 fullyQualifiedName, 1194 true, 1195 scope); 1196 } 1197 1198 if (proposeConstructor && !Flags.isEnum(typeModifiers)) { 1199 acceptedConstructor.mustBeQualified = true; 1200 if (DEFER_QUALIFIED_PROPOSALS) { 1201 deferredProposals.add(acceptedConstructor); 1202 } else { 1203 proposeConstructor(acceptedConstructor, scope); 1204 } 1205 } 1206 } 1207 } 1208 1209 char[][] keys = onDemandFound.keyTable; 1210 Object[] values = onDemandFound.valueTable; 1211 int max = keys.length; 1212 for (int i = 0; i < max; i++) { 1213 1214 // does not check cancellation for every types to avoid performance loss 1215 if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 1216 1217 if(keys[i] != null) { 1218 AcceptedConstructor value = (AcceptedConstructor) values[i]; 1219 if(value != null) { 1220 char[] fullyQualifiedEnclosingTypeOrPackageName = null; 1221 done : for (int j = 0; j < this.onDemandImportCacheCount; j++) { 1222 ImportBinding importBinding = this.onDemandImportsCache[j]; 1223 1224 char[][] importName = importBinding.compoundName; 1225 char[] importFlatName = CharOperation.concatWith(importName, '.'); 1226 1227 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 1228 fullyQualifiedEnclosingTypeOrPackageName = value.packageName; 1229 } 1230 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 1231 if(importBinding.isStatic()) { 1232 if((value.modifiers & ClassFileConstants.AccStatic) != 0) { 1233 value.mustBeQualified = true; 1234 break done; 1235 } 1236 } else { 1237 value.mustBeQualified = true; 1238 break done; 1239 } 1240 } 1241 } 1242 if (value.proposeType) { 1243 proposeType( 1244 value.packageName, 1245 value.simpleTypeName, 1246 value.typeModifiers, 1247 value.accessibility, 1248 value.simpleTypeName, 1249 value.fullyQualifiedName, 1250 value.mustBeQualified, 1251 scope); 1252 } 1253 1254 if (value.proposeConstructor && !Flags.isEnum(value.modifiers)) { 1255 if (!value.mustBeQualified) { 1256 proposeConstructor( 1257 value.simpleTypeName, 1258 value.parameterCount, 1259 value.signature, 1260 value.parameterTypes, 1261 value.parameterNames, 1262 value.modifiers, 1263 value.packageName, 1264 value.typeModifiers, 1265 value.accessibility, 1266 value.simpleTypeName, 1267 value.fullyQualifiedName, 1268 value.mustBeQualified, 1269 scope, 1270 value.extraFlags); 1271 } else { 1272 if (DEFER_QUALIFIED_PROPOSALS) { 1273 deferredProposals.add(value); 1274 } else { 1275 proposeConstructor(value, scope); 1276 } 1277 } 1278 } 1279 } 1280 } 1281 } 1282 1283 if (DEFER_QUALIFIED_PROPOSALS) { 1284 int size = deferredProposals.size(); 1285 for (int i = 0; i < size; i++) { 1286 1287 // does not check cancellation for every types to avoid performance loss 1288 if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 1289 1290 AcceptedConstructor deferredProposal = (AcceptedConstructor)deferredProposals.get(i); 1291 1292 if (deferredProposal.proposeConstructor) { 1293 proposeConstructor( 1294 deferredProposal.simpleTypeName, 1295 deferredProposal.parameterCount, 1296 deferredProposal.signature, 1297 deferredProposal.parameterTypes, 1298 deferredProposal.parameterNames, 1299 deferredProposal.modifiers, 1300 deferredProposal.packageName, 1301 deferredProposal.typeModifiers, 1302 deferredProposal.accessibility, 1303 deferredProposal.simpleTypeName, 1304 deferredProposal.fullyQualifiedName, 1305 deferredProposal.mustBeQualified, 1306 scope, 1307 deferredProposal.extraFlags); 1308 } 1309 } 1310 } 1311 } finally { 1312 this.acceptedTypes = null; // reset 1313 } 1314 } 1315 1316 /** 1317 * One result of the search consists of a new module. 1318 * 1319 * NOTE - All module names are presented in their readable form: 1320 * Module names are in the form "a.b.c". 1321 * The default module is represented by an empty array. 1322 */ 1323 @Override acceptModule(char[] moduleName)1324 public void acceptModule(char[] moduleName) { 1325 if (this.knownModules.containsKey(moduleName)) return; 1326 if (CharOperation.equals(moduleName, this.moduleDeclaration.moduleName)) return; 1327 if (CharOperation.equals(moduleName, CharOperation.NO_CHAR)) return; 1328 this.knownModules.put(moduleName, this); 1329 char[] completion = moduleName; 1330 int relevance = computeBaseRelevance(); 1331 relevance += computeRelevanceForResolution(); 1332 relevance += computeRelevanceForInterestingProposal(); 1333 relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, moduleName); 1334 relevance += computeRelevanceForQualification(true); 1335 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 1336 this.noProposal = false; 1337 if(!this.requestor.isIgnored(CompletionProposal.MODULE_REF)) { 1338 InternalCompletionProposal proposal = createProposal(CompletionProposal.MODULE_REF, this.actualCompletionPosition); 1339 proposal.setModuleName(moduleName); 1340 proposal.setDeclarationSignature(moduleName); 1341 proposal.setCompletion(completion); 1342 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 1343 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 1344 proposal.setRelevance(relevance); 1345 this.requestor.accept(proposal); 1346 if(DEBUG) { 1347 this.printDebug(proposal); 1348 } 1349 } 1350 1351 } 1352 1353 @Override acceptPackage(char[] packageName)1354 public void acceptPackage(char[] packageName) { 1355 1356 if (this.knownPkgs.containsKey(packageName)) return; 1357 1358 if (!isValidPackageName(packageName)) return; 1359 1360 if (this.skipDefaultPackage && 1361 CharOperation.equals(packageName, CharOperation.NO_CHAR)) 1362 return; 1363 1364 this.knownPkgs.put(packageName, this); 1365 1366 char[] completion; 1367 if(this.resolvingImports) { 1368 if(this.resolvingStaticImports) { 1369 completion = CharOperation.concat(packageName, new char[] { '.' }); 1370 } else { 1371 completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' }); 1372 } 1373 } else { 1374 completion = packageName; 1375 } 1376 1377 int relevance = computeBaseRelevance(); 1378 relevance += computeRelevanceForResolution(); 1379 relevance += computeRelevanceForInterestingProposal(); 1380 relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName); 1381 if(!this.resolvingImports) { 1382 relevance += computeRelevanceForQualification(true); 1383 } 1384 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 1385 1386 this.noProposal = false; 1387 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 1388 InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition); 1389 proposal.setDeclarationSignature(packageName); 1390 proposal.setPackageName(packageName); 1391 proposal.setCompletion(completion); 1392 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 1393 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 1394 proposal.setRelevance(relevance); 1395 this.requestor.accept(proposal); 1396 if(DEBUG) { 1397 this.printDebug(proposal); 1398 } 1399 } 1400 } 1401 1402 @Override acceptType( char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, int modifiers, AccessRestriction accessRestriction)1403 public void acceptType( 1404 char[] packageName, 1405 char[] simpleTypeName, 1406 char[][] enclosingTypeNames, 1407 int modifiers, 1408 AccessRestriction accessRestriction) { 1409 1410 // does not check cancellation for every types to avoid performance loss 1411 if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 1412 this.foundTypesCount++; 1413 1414 if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return; 1415 if (this.assistNodeIsExtendedType && (modifiers & ClassFileConstants.AccFinal) != 0) return; 1416 if (this.assistNodeIsExtendedType && (modifiers & ExtraCompilerModifiers.AccRecord) != 0) return; 1417 1418 if (this.options.checkVisibility) { 1419 if((modifiers & ClassFileConstants.AccPublic) == 0) { 1420 if((modifiers & ClassFileConstants.AccPrivate) != 0) return; 1421 if (this.moduleDeclaration == null) { 1422 char[] currentPackage = CharOperation.concatWith(this.unitScope.fPackage.compoundName, '.'); 1423 if(!CharOperation.equals(packageName, currentPackage)) return; 1424 } 1425 } 1426 } 1427 1428 int accessibility = IAccessRule.K_ACCESSIBLE; 1429 if(accessRestriction != null) { 1430 switch (accessRestriction.getProblemId()) { 1431 case IProblem.ForbiddenReference: 1432 if (this.options.checkForbiddenReference) { 1433 return; 1434 } 1435 accessibility = IAccessRule.K_NON_ACCESSIBLE; 1436 break; 1437 case IProblem.DiscouragedReference: 1438 if (this.options.checkDiscouragedReference) { 1439 return; 1440 } 1441 accessibility = IAccessRule.K_DISCOURAGED; 1442 break; 1443 } 1444 } 1445 1446 if (isForbidden(packageName, simpleTypeName, enclosingTypeNames)) { 1447 return; 1448 } 1449 1450 if(this.acceptedTypes == null) { 1451 this.acceptedTypes = new ObjectVector(); 1452 } 1453 this.acceptedTypes.add(new AcceptedType(packageName, simpleTypeName, enclosingTypeNames, modifiers, accessibility)); 1454 } 1455 acceptTypes(Scope scope)1456 private void acceptTypes(Scope scope) { 1457 this.checkCancel(); 1458 1459 if(this.acceptedTypes == null) return; 1460 1461 int length = this.acceptedTypes.size(); 1462 1463 if(length == 0) return; 1464 1465 HashtableOfObject onDemandFound = new HashtableOfObject(); 1466 1467 try { 1468 next : for (int i = 0; i < length; i++) { 1469 1470 // does not check cancellation for every types to avoid performance loss 1471 if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 1472 1473 AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i); 1474 char[] packageName = acceptedType.packageName; 1475 char[] simpleTypeName = acceptedType.simpleTypeName; 1476 char[][] enclosingTypeNames = acceptedType.enclosingTypeNames; 1477 int modifiers = acceptedType.modifiers; 1478 int accessibility = acceptedType.accessibility; 1479 1480 char[] typeName; 1481 char[] flatEnclosingTypeNames; 1482 if(enclosingTypeNames == null || enclosingTypeNames.length == 0) { 1483 flatEnclosingTypeNames = null; 1484 typeName = simpleTypeName; 1485 } else { 1486 flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.'); 1487 typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.'); 1488 } 1489 char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.'); 1490 1491 if (this.knownTypes.containsKey(fullyQualifiedName)) continue next; 1492 1493 this.knownTypes.put(fullyQualifiedName, KNOWN_TYPE_WITH_UNKNOWN_CONSTRUCTORS); 1494 1495 if (this.resolvingImports) { 1496 if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) { 1497 continue next; // import of default package is forbidden when compliance is 1.4 or higher 1498 } 1499 1500 char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName; 1501 1502 if(this.resolvingStaticImports) { 1503 if(enclosingTypeNames == null || enclosingTypeNames.length == 0) { 1504 completionName = CharOperation.concat(completionName, new char[] { '.' }); 1505 } else if ((modifiers & ClassFileConstants.AccStatic) == 0) { 1506 continue next; 1507 } else { 1508 completionName = appendUnlessNextToken(completionName, new char[] { ';' }, TerminalTokens.TokenNameSEMICOLON); 1509 } 1510 } else { 1511 completionName = appendUnlessNextToken(completionName, new char[] {';'}, TerminalTokens.TokenNameSEMICOLON); 1512 } 1513 1514 int relevance = computeBaseRelevance(); 1515 relevance += computeRelevanceForResolution(); 1516 relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName); 1517 relevance += computeRelevanceForRestrictions(accessibility); 1518 relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName); 1519 1520 this.noProposal = false; 1521 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 1522 createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance); 1523 } 1524 } else { 1525 if(!this.importCachesInitialized) { 1526 initializeImportCaches(); 1527 } 1528 1529 for (int j = 0; j < this.importCacheCount; j++) { 1530 char[][] importName = this.importsCache[j]; 1531 if(CharOperation.equals(typeName, importName[0])) { 1532 proposeType( 1533 packageName, 1534 simpleTypeName, 1535 modifiers, 1536 accessibility, 1537 typeName, 1538 fullyQualifiedName, 1539 !CharOperation.equals(fullyQualifiedName, importName[1]), 1540 scope); 1541 continue next; 1542 } 1543 } 1544 1545 1546 if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) { 1547 proposeType( 1548 packageName, 1549 simpleTypeName, 1550 modifiers, 1551 accessibility, 1552 typeName, 1553 fullyQualifiedName, 1554 false, 1555 scope); 1556 continue next; 1557 } else { 1558 char[] fullyQualifiedEnclosingTypeOrPackageName = null; 1559 1560 AcceptedType foundType = null; 1561 if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) { 1562 for (int j = 0; j < this.onDemandImportCacheCount; j++) { 1563 ImportBinding importBinding = this.onDemandImportsCache[j]; 1564 1565 char[][] importName = importBinding.compoundName; 1566 char[] importFlatName = CharOperation.concatWith(importName, '.'); 1567 1568 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 1569 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) { 1570 fullyQualifiedEnclosingTypeOrPackageName = 1571 CharOperation.concat( 1572 packageName, 1573 flatEnclosingTypeNames, 1574 '.'); 1575 } else { 1576 fullyQualifiedEnclosingTypeOrPackageName = 1577 packageName; 1578 } 1579 } 1580 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 1581 if(importBinding.isStatic()) { 1582 if((modifiers & ClassFileConstants.AccStatic) != 0) { 1583 acceptedType.qualifiedTypeName = typeName; 1584 acceptedType.fullyQualifiedName = fullyQualifiedName; 1585 onDemandFound.put( 1586 simpleTypeName, 1587 acceptedType); 1588 continue next; 1589 } 1590 } else { 1591 acceptedType.qualifiedTypeName = typeName; 1592 acceptedType.fullyQualifiedName = fullyQualifiedName; 1593 onDemandFound.put( 1594 simpleTypeName, 1595 acceptedType); 1596 continue next; 1597 } 1598 } 1599 } 1600 } else if(!foundType.mustBeQualified){ 1601 done : for (int j = 0; j < this.onDemandImportCacheCount; j++) { 1602 ImportBinding importBinding = this.onDemandImportsCache[j]; 1603 1604 char[][] importName = importBinding.compoundName; 1605 char[] importFlatName = CharOperation.concatWith(importName, '.'); 1606 1607 if(fullyQualifiedEnclosingTypeOrPackageName == null) { 1608 if(enclosingTypeNames != null && enclosingTypeNames.length != 0) { 1609 fullyQualifiedEnclosingTypeOrPackageName = 1610 CharOperation.concat( 1611 packageName, 1612 flatEnclosingTypeNames, 1613 '.'); 1614 } else { 1615 fullyQualifiedEnclosingTypeOrPackageName = 1616 packageName; 1617 } 1618 } 1619 if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) { 1620 if(importBinding.isStatic()) { 1621 if((modifiers & ClassFileConstants.AccStatic) != 0) { 1622 foundType.mustBeQualified = true; 1623 break done; 1624 } 1625 } else { 1626 foundType.mustBeQualified = true; 1627 break done; 1628 } 1629 } 1630 } 1631 } 1632 proposeType( 1633 packageName, 1634 simpleTypeName, 1635 modifiers, 1636 accessibility, 1637 typeName, 1638 fullyQualifiedName, 1639 true, 1640 scope); 1641 } 1642 } 1643 } 1644 1645 char[][] keys = onDemandFound.keyTable; 1646 Object[] values = onDemandFound.valueTable; 1647 int max = keys.length; 1648 for (int i = 0; i < max; i++) { 1649 if ((i % CHECK_CANCEL_FREQUENCY) == 0) checkCancel(); 1650 if(keys[i] != null) { 1651 AcceptedType value = (AcceptedType) values[i]; 1652 if(value != null) { 1653 proposeType( 1654 value.packageName, 1655 value.simpleTypeName, 1656 value.modifiers, 1657 value.accessibility, 1658 value.qualifiedTypeName, 1659 value.fullyQualifiedName, 1660 value.mustBeQualified, 1661 scope); 1662 } 1663 } 1664 } 1665 } finally { 1666 this.acceptedTypes = null; // reset 1667 } 1668 } 1669 appendUnlessNextToken(char[] completionName, char[] suffix, int nextToken)1670 private char[] appendUnlessNextToken(char[] completionName, char[] suffix, int nextToken) { 1671 if (this.source == null) 1672 return CharOperation.concat(completionName, suffix); 1673 1674 AssistParser assistParser = getParser(); 1675 Object parserState = assistParser.becomeSimpleParser(); 1676 1677 assistParser.scanner.setSource(this.source); 1678 assistParser.scanner.resetTo(this.endPosition, Integer.MAX_VALUE); 1679 try { 1680 if (assistParser.scanner.getNextToken() != nextToken) { 1681 return CharOperation.concat(completionName, suffix); 1682 } 1683 } catch (InvalidInputException e) { 1684 // ignore 1685 } finally { 1686 assistParser.restoreAssistParser(parserState); 1687 } 1688 return completionName; 1689 } 1690 acceptUnresolvedName(char[] name)1691 public void acceptUnresolvedName(char[] name) { 1692 int relevance = computeBaseRelevance(); 1693 relevance += computeRelevanceForResolution(false); 1694 relevance += computeRelevanceForInterestingProposal(); 1695 relevance += computeRelevanceForCaseMatching(this.completionToken, name); 1696 relevance += computeRelevanceForQualification(false); 1697 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable 1698 CompletionEngine.this.noProposal = false; 1699 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 1700 InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.LOCAL_VARIABLE_REF, CompletionEngine.this.actualCompletionPosition); 1701 proposal.setSignature(JAVA_LANG_OBJECT_SIGNATURE); 1702 proposal.setPackageName(JAVA_LANG_NAME); 1703 proposal.setTypeName(OBJECT); 1704 proposal.setName(name); 1705 proposal.setCompletion(name); 1706 proposal.setFlags(Flags.AccDefault); 1707 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 1708 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 1709 proposal.setRelevance(relevance); 1710 CompletionEngine.this.requestor.accept(proposal); 1711 if(DEBUG) { 1712 CompletionEngine.this.printDebug(proposal); 1713 } 1714 } 1715 } addExpectedType(TypeBinding type, Scope scope)1716 private void addExpectedType(TypeBinding type, Scope scope){ 1717 if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return; 1718 1719 // do not add twice the same type 1720 for (int i = 0; i <= this.expectedTypesPtr; i++) { 1721 if (TypeBinding.equalsEquals(this.expectedTypes[i], type)) return; 1722 } 1723 1724 int length = this.expectedTypes.length; 1725 if (++this.expectedTypesPtr >= length) 1726 System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length); 1727 this.expectedTypes[this.expectedTypesPtr] = type; 1728 1729 if(TypeBinding.equalsEquals(type, scope.getJavaLangObject())) { 1730 this.hasJavaLangObjectAsExpectedType = true; 1731 } 1732 } 1733 addForbiddenBindings(Binding binding)1734 private void addForbiddenBindings(Binding binding){ 1735 if (binding == null) return; 1736 1737 int length = this.forbbidenBindings.length; 1738 if (++this.forbbidenBindingsPtr >= length) 1739 System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length); 1740 this.forbbidenBindings[this.forbbidenBindingsPtr] = binding; 1741 } 1742 addUninterestingBindings(Binding binding)1743 private void addUninterestingBindings(Binding binding){ 1744 if (binding == null) return; 1745 1746 int length = this.uninterestingBindings.length; 1747 if (++this.uninterestingBindingsPtr >= length) 1748 System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length); 1749 this.uninterestingBindings[this.uninterestingBindingsPtr] = binding; 1750 } 1751 1752 // this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[]) areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs)1753 private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) { 1754 int paramLength = parameters.length; 1755 int argLength = arguments.length; 1756 int lastIndex = argLength; 1757 if (isVarargs) { 1758 lastIndex = paramLength - 1; 1759 if (paramLength == argLength) { // accept X[] but not X or X[][] 1760 TypeBinding varArgType = parameters[lastIndex]; // is an ArrayBinding by definition 1761 TypeBinding lastArgument = arguments[lastIndex]; 1762 if (TypeBinding.notEquals(varArgType, lastArgument) && !lastArgument.isCompatibleWith(varArgType)) 1763 return false; 1764 } else if (paramLength < argLength) { // all remainig argument types must be compatible with the elementsType of varArgType 1765 TypeBinding varArgType = ((ArrayBinding) parameters[lastIndex]).elementsType(); 1766 for (int i = lastIndex; i < argLength; i++) 1767 if (TypeBinding.notEquals(varArgType, arguments[i]) && !arguments[i].isCompatibleWith(varArgType)) 1768 return false; 1769 } else if (lastIndex != argLength) { // can call foo(int i, X ... x) with foo(1) but NOT foo(); 1770 return false; 1771 } 1772 // now compare standard arguments from 0 to lastIndex 1773 } else { 1774 if(paramLength != argLength) 1775 return false; 1776 } 1777 for (int i = 0; i < lastIndex; i++) 1778 if (TypeBinding.notEquals(parameters[i], arguments[i]) && !arguments[i].isCompatibleWith(parameters[i])) 1779 return false; 1780 return true; 1781 } 1782 buildContext( ASTNode astNode, ASTNode astNodeParent, CompilationUnitDeclaration compilationUnitDeclaration, Binding qualifiedBinding, Scope scope)1783 private void buildContext( 1784 ASTNode astNode, 1785 ASTNode astNodeParent, 1786 CompilationUnitDeclaration compilationUnitDeclaration, 1787 Binding qualifiedBinding, 1788 Scope scope) { 1789 InternalCompletionContext context = new InternalCompletionContext(); 1790 if (this.requestor.isExtendedContextRequired()) { 1791 context.setExtendedData( 1792 this.typeRoot, 1793 compilationUnitDeclaration, 1794 this.lookupEnvironment, 1795 scope, 1796 astNode, 1797 astNodeParent, 1798 this.owner, 1799 this.parser); 1800 } 1801 1802 // build expected types context 1803 if (this.expectedTypesPtr > -1) { 1804 int length = this.expectedTypesPtr + 1; 1805 char[][] expTypes = new char[length][]; 1806 char[][] expKeys = new char[length][]; 1807 for (int i = 0; i < length; i++) { 1808 expTypes[i] = getSignature(this.expectedTypes[i]); 1809 expKeys[i] = this.expectedTypes[i].computeUniqueKey(); 1810 } 1811 context.setExpectedTypesSignatures(expTypes); 1812 context.setExpectedTypesKeys(expKeys); 1813 } 1814 1815 context.setOffset(this.actualCompletionPosition + 1 - this.offset); 1816 1817 // Set javadoc info 1818 if (astNode instanceof CompletionOnJavadoc) { 1819 this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags(); 1820 context.setJavadoc(this.assistNodeInJavadoc); 1821 } 1822 1823 if (!(astNode instanceof CompletionOnJavadoc)) { 1824 CompletionScanner scanner = (CompletionScanner)this.parser.scanner; 1825 context.setToken(scanner.completionIdentifier); 1826 context.setTokenRange( 1827 scanner.completedIdentifierStart - this.offset, 1828 scanner.completedIdentifierEnd - this.offset, 1829 scanner.endOfEmptyToken - this.offset); 1830 } else if(astNode instanceof CompletionOnJavadocTag) { 1831 CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode; 1832 context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token)); 1833 context.setTokenRange( 1834 javadocTag.tagSourceStart - this.offset, 1835 javadocTag.tagSourceEnd - this.offset, 1836 ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset); 1837 } else { 1838 CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner; 1839 context.setToken(scanner.completionIdentifier); 1840 context.setTokenRange( 1841 scanner.completedIdentifierStart - this.offset, 1842 scanner.completedIdentifierEnd - this.offset, 1843 scanner.endOfEmptyToken - this.offset); 1844 } 1845 1846 if(astNode instanceof CompletionOnStringLiteral) { 1847 context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL); 1848 } else { 1849 context.setTokenKind(CompletionContext.TOKEN_KIND_NAME); 1850 } 1851 1852 buildTokenLocationContext(context, scope, astNode, astNodeParent); 1853 1854 if(DEBUG) { 1855 System.out.println(context.toString()); 1856 } 1857 this.requestor.acceptContext(context); 1858 } 1859 buildTokenLocationContext(InternalCompletionContext context, Scope scope, ASTNode astNode, ASTNode astNodeParent)1860 private void buildTokenLocationContext(InternalCompletionContext context, Scope scope, ASTNode astNode, ASTNode astNodeParent) { 1861 if (scope == null || context.isInJavadoc()) return; 1862 1863 if (astNode instanceof CompletionOnFieldType) { 1864 CompletionOnFieldType field = (CompletionOnFieldType) astNode; 1865 if (!field.isLocalVariable && 1866 field.modifiers == ClassFileConstants.AccDefault && 1867 (field.annotations == null || field.annotations.length == 0)) { 1868 context.setTokenLocation(CompletionContext.TL_MEMBER_START); 1869 } 1870 } else if (astNode instanceof CompletionOnMethodReturnType) { 1871 CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode; 1872 if (method.modifiers == ClassFileConstants.AccDefault && 1873 (method.annotations == null || method.annotations.length == 0)) { 1874 context.setTokenLocation(CompletionContext.TL_MEMBER_START); 1875 } 1876 } else if (astNode instanceof CompletionOnSingleTypeReference) { 1877 CompletionOnSingleTypeReference completionOnSingleTypeReference = (CompletionOnSingleTypeReference) astNode; 1878 if (completionOnSingleTypeReference.isConstructorType) { 1879 context.setTokenLocation(CompletionContext.TL_CONSTRUCTOR_START); 1880 } 1881 } else if (astNode instanceof CompletionOnQualifiedTypeReference) { 1882 CompletionOnQualifiedTypeReference completionOnQualifiedTypeReference = (CompletionOnQualifiedTypeReference) astNode; 1883 if (completionOnQualifiedTypeReference.isConstructorType){ 1884 context.setTokenLocation(CompletionContext.TL_CONSTRUCTOR_START); 1885 } 1886 } else if (astNode instanceof CompletionOnKeyword3 && ((CompletionOnKeyword3) astNode).afterTryOrCatch()) { 1887 context.setTokenLocation(CompletionContext.TL_STATEMENT_START); 1888 } else if (astNode instanceof CompletionOnImportReference) { 1889 context.setTokenLocation(CompletionContext.TL_IN_IMPORT); 1890 } else { 1891 ReferenceContext referenceContext = scope.referenceContext(); 1892 if (referenceContext instanceof AbstractMethodDeclaration) { 1893 AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration)referenceContext; 1894 if (methodDeclaration.bodyStart <= astNode.sourceStart && 1895 astNode.sourceEnd <= methodDeclaration.bodyEnd) { 1896 // completion is inside a method body 1897 if (astNodeParent == null && 1898 astNode instanceof CompletionOnSingleNameReference && 1899 !((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) { 1900 context.setTokenLocation(CompletionContext.TL_STATEMENT_START); 1901 } 1902 } 1903 } else if (referenceContext instanceof LambdaExpression) { 1904 LambdaExpression expression = (LambdaExpression)referenceContext; 1905 if (expression.body().sourceStart <= astNode.sourceStart && 1906 astNode.sourceEnd <= expression.body().sourceEnd) { 1907 // completion is inside a method body 1908 if ((astNodeParent == null || astNodeParent == expression) && 1909 astNode instanceof CompletionOnSingleNameReference && 1910 !((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) { 1911 context.setTokenLocation(CompletionContext.TL_STATEMENT_START); 1912 } 1913 } 1914 } else if (referenceContext instanceof TypeDeclaration) { 1915 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 1916 FieldDeclaration[] fields = typeDeclaration.fields; 1917 if (fields != null) { 1918 done : for (int i = 0; i < fields.length; i++) { 1919 if (fields[i] instanceof Initializer) { 1920 Initializer initializer = (Initializer) fields[i]; 1921 if (initializer.block.sourceStart <= astNode.sourceStart && 1922 astNode.sourceStart < initializer.bodyEnd) { 1923 // completion is inside an initializer 1924 if (astNodeParent == null && 1925 astNode instanceof CompletionOnSingleNameReference && 1926 !((CompletionOnSingleNameReference)astNode).isPrecededByModifiers) { 1927 context.setTokenLocation(CompletionContext.TL_STATEMENT_START); 1928 } 1929 break done; 1930 } 1931 } 1932 } 1933 } 1934 } 1935 } 1936 } 1937 checkCancel()1938 void checkCancel() { 1939 if (this.monitor != null && this.monitor.isCanceled()) { 1940 throw new OperationCanceledException(); 1941 } 1942 } 1943 complete( ASTNode astNode, ASTNode astNodeParent, ASTNode enclosingNode, CompilationUnitDeclaration compilationUnitDeclaration, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation)1944 private boolean complete( 1945 ASTNode astNode, 1946 ASTNode astNodeParent, 1947 ASTNode enclosingNode, 1948 CompilationUnitDeclaration compilationUnitDeclaration, 1949 Binding qualifiedBinding, 1950 Scope scope, 1951 boolean insideTypeAnnotation) { 1952 1953 setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd); 1954 1955 scope = computeForbiddenBindings(astNode, astNodeParent, scope); 1956 computeUninterestingBindings(astNode, astNodeParent, scope); 1957 if(astNodeParent != null) { 1958 if(!isValidParent(astNodeParent, astNode, scope)) return false; 1959 computeExpectedTypes(astNodeParent, astNode, scope); 1960 } 1961 1962 buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope); 1963 1964 if (astNode instanceof CompletionOnMemberAccess && qualifiedBinding instanceof BaseTypeBinding) return true; 1965 if (astNode instanceof CompletionOnFieldType) { 1966 completionOnFieldType(astNode, scope); 1967 } else if (astNode instanceof CompletionOnMethodReturnType) { 1968 completionOnMethodReturnType(astNode, scope); 1969 } else if (astNode instanceof CompletionOnSingleNameReference) { 1970 completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation); 1971 } else if (astNode instanceof CompletionOnProvidesInterfacesQualifiedTypeReference) { 1972 completionOnProvidesInterfacesQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1973 } else if (astNode instanceof CompletionOnProvidesInterfacesSingleTypeReference) { 1974 completionOnProvidesInterfacesSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1975 } else if (astNode instanceof CompletionOnProvidesImplementationsQualifiedTypeReference) { 1976 completionOnProvidesImplementationsQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1977 } else if (astNode instanceof CompletionOnProvidesImplementationsSingleTypeReference) { 1978 completionOnProvidesImplementationsSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1979 } else if (astNode instanceof CompletionOnSingleTypeReference) { 1980 completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1981 } else if (astNode instanceof CompletionOnQualifiedNameReference) { 1982 completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation); 1983 } else if (astNode instanceof CompletionOnQualifiedTypeReference) { 1984 completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 1985 } else if (astNode instanceof CompletionOnMemberAccess) { 1986 completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation); 1987 } else if (astNode instanceof CompletionOnMessageSend) { 1988 completionOnMessageSend(astNode, qualifiedBinding, scope); 1989 } else if (astNode instanceof CompletionOnExplicitConstructorCall) { 1990 completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope); 1991 } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) { 1992 completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope); 1993 } else if (astNode instanceof CompletionOnClassLiteralAccess) { 1994 completionOnClassLiteralAccess(astNode, qualifiedBinding, scope); 1995 } else if (astNode instanceof CompletionOnMethodName) { 1996 completionOnMethodName(astNode, scope); 1997 } else if (astNode instanceof CompletionOnFieldName) { 1998 completionOnFieldName(astNode, scope); 1999 } else if (astNode instanceof CompletionOnLocalName) { 2000 completionOnLocalOrArgumentName(astNode, scope); 2001 } else if (astNode instanceof CompletionOnArgumentName) { 2002 completionOnLocalOrArgumentName(astNode, scope); 2003 } else if (astNode instanceof CompletionOnKeyword) { 2004 completionOnKeyword(astNode); 2005 } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) { 2006 completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 2007 } else if (astNode instanceof CompletionOnMarkerAnnotationName) { 2008 completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope); 2009 } else if (astNode instanceof CompletionOnMemberValueName) { 2010 completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation); 2011 } else if(astNode instanceof CompletionOnBranchStatementLabel) { 2012 completionOnBranchStatementLabel(astNode); 2013 } else if(astNode instanceof CompletionOnMessageSendName) { 2014 completionOnMessageSendName(astNode, qualifiedBinding, scope); 2015 } else if (astNode instanceof CompletionOnReferenceExpressionName) { 2016 completionOnReferenceExpressionName(astNode, qualifiedBinding, scope); 2017 // Completion on Javadoc nodes 2018 } else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) { 2019 if (astNode instanceof CompletionOnJavadocSingleTypeReference) { 2020 completionOnJavadocSingleTypeReference(astNode, scope); 2021 } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) { 2022 completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope); 2023 } else if (astNode instanceof CompletionOnJavadocFieldReference) { 2024 completionOnJavadocFieldReference(astNode, scope); 2025 } else if (astNode instanceof CompletionOnJavadocMessageSend) { 2026 completionOnJavadocMessageSend(astNode, qualifiedBinding, scope); 2027 } else if (astNode instanceof CompletionOnJavadocAllocationExpression) { 2028 completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope); 2029 } else if (astNode instanceof CompletionOnJavadocParamNameReference) { 2030 completionOnJavadocParamNameReference(astNode); 2031 } else if (astNode instanceof CompletionOnJavadocTypeParamReference) { 2032 completionOnJavadocTypeParamReference(astNode); 2033 } else if (astNode instanceof CompletionOnJavadocTag) { 2034 completionOnJavadocTag(astNode); 2035 } 2036 } 2037 return true; 2038 } 2039 2040 /** 2041 * Ask the engine to compute a completion at the specified position 2042 * of the given compilation unit. 2043 * 2044 * No return 2045 * completion results are answered through a requestor. 2046 * 2047 * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit 2048 * the source of the current compilation unit. 2049 * 2050 * @param completionPosition int 2051 * a position in the source where the completion is taking place. 2052 * This position is relative to the source provided. 2053 */ complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root)2054 public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) { 2055 2056 if(DEBUG) { 2057 System.out.print("COMPLETION IN "); //$NON-NLS-1$ 2058 System.out.print(sourceUnit.getFileName()); 2059 System.out.print(" AT POSITION "); //$NON-NLS-1$ 2060 System.out.println(completionPosition); 2061 System.out.println("COMPLETION - Source :"); //$NON-NLS-1$ 2062 System.out.println(sourceUnit.getContents()); 2063 } 2064 if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN); 2065 this.requestor.beginReporting(); 2066 boolean contextAccepted = false; 2067 try { 2068 this.fileName = sourceUnit.getFileName(); 2069 this.actualCompletionPosition = completionPosition - 1; 2070 this.offset = pos; 2071 this.typeRoot = root; 2072 this.source = sourceUnit.getContents(); 2073 2074 this.checkCancel(); 2075 2076 // for now until we can change the UI. 2077 CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); 2078 CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition); 2079 2080 // boolean completionNodeFound = false; 2081 if (parsedUnit != null) { 2082 if(DEBUG) { 2083 System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$ 2084 System.out.println(parsedUnit.toString()); 2085 } 2086 2087 if (parsedUnit.isModuleInfo()) { 2088 this.moduleDeclaration = parsedUnit.moduleDeclaration; 2089 if (this.moduleDeclaration == null) return; 2090 if (this.moduleDeclaration instanceof CompletionOnModuleDeclaration) { 2091 contextAccepted = true; 2092 buildContext(parsedUnit.moduleDeclaration, null, parsedUnit, null, null); 2093 //this.requestor.setIgnored(CompletionProposal.MODULE_DECLARATION, false); //TODO: Hack until ui fixes this issue. 2094 if(!this.requestor.isIgnored(CompletionProposal.MODULE_DECLARATION)) { 2095 proposeModuleName(parsedUnit); 2096 } 2097 debugPrintf(); 2098 return; 2099 } 2100 if (this.moduleDeclaration instanceof CompletionOnKeywordModuleDeclaration) { 2101 contextAccepted = true; 2102 processModuleKeywordCompletion(parsedUnit, this.moduleDeclaration, (CompletionOnKeyword) this.moduleDeclaration); 2103 return; 2104 } 2105 if (this.moduleDeclaration.exports != null) { 2106 contextAccepted = completeOnPackageVisibilityStatements(contextAccepted, parsedUnit, this.moduleDeclaration.exports); 2107 if (contextAccepted) return; 2108 } 2109 if (this.moduleDeclaration.opens != null) { 2110 contextAccepted = completeOnPackageVisibilityStatements(contextAccepted, parsedUnit, this.moduleDeclaration.opens); 2111 if (contextAccepted) return; 2112 } 2113 RequiresStatement[] moduleRefs = this.moduleDeclaration.requires; 2114 if (moduleRefs != null) { 2115 for (int i = 0, l = moduleRefs.length; i < l; ++i) { 2116 ModuleReference reference = moduleRefs[i].module; 2117 if (reference instanceof CompletionOnModuleReference) { 2118 contextAccepted = true; 2119 buildContext(reference, null, parsedUnit, null, null); 2120 if(!this.requestor.isIgnored(CompletionProposal.MODULE_REF)) { 2121 findModules((CompletionOnModuleReference) reference, false /* targetted */); 2122 } 2123 debugPrintf(); 2124 return; 2125 } 2126 } 2127 } 2128 try { 2129 UsesStatement[] uses = this.moduleDeclaration.uses; 2130 if (uses != null) { 2131 for (int i = 0, l = uses.length; i < l; ++i) { 2132 UsesStatement usesStatement = uses[i]; 2133 this.parser.enclosingNode = usesStatement; 2134 TypeReference usesReference = usesStatement.serviceInterface; 2135 if (usesReference instanceof CompletionOnUsesSingleTypeReference || 2136 usesReference instanceof CompletionOnUsesQualifiedTypeReference) { 2137 contextAccepted = checkForCNF(usesReference, parsedUnit, true); 2138 return; 2139 } 2140 } 2141 } 2142 ProvidesStatement[] providesStmts = this.moduleDeclaration.services; 2143 for (int i = 0, l = providesStmts != null ? providesStmts.length : 0; i < l; ++i) { 2144 ProvidesStatement providesStmt = providesStmts[i]; 2145 this.parser.enclosingNode = providesStmt; 2146 TypeReference pInterface = providesStmt.serviceInterface; 2147 if (pInterface instanceof CompletionOnProvidesInterfacesSingleTypeReference || 2148 pInterface instanceof CompletionOnProvidesInterfacesQualifiedTypeReference) { 2149 contextAccepted = checkForCNF(pInterface, parsedUnit, true); 2150 return; 2151 } 2152 TypeReference[] implementations = providesStmt.implementations; 2153 for (int j = 0, k = implementations.length; j < k; ++j) { 2154 TypeReference implementation = implementations[j]; 2155 if (implementation instanceof CompletionOnProvidesImplementationsSingleTypeReference || 2156 implementation instanceof CompletionOnProvidesImplementationsQualifiedTypeReference) { 2157 this.skipDefaultPackage = true; 2158 contextAccepted = checkForCNF(implementation, parsedUnit, false); 2159 return; 2160 } else if (implementation instanceof CompletionOnKeyword) { 2161 contextAccepted = true; 2162 processModuleKeywordCompletion(parsedUnit, implementation, (CompletionOnKeyword) implementation); 2163 } 2164 } 2165 } 2166 } catch (CompletionNodeFound e) { 2167 // completionNodeFound = true; 2168 if (e.astNode != null) { 2169 // if null then we found a problem in the completion node 2170 if(DEBUG) { 2171 System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$ 2172 System.out.println(e.astNode.toString()); 2173 if(this.parser.assistNodeParent != null) { 2174 System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$ 2175 System.out.println(this.parser.assistNodeParent); 2176 } 2177 } 2178 this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting 2179 contextAccepted = 2180 complete( 2181 e.astNode, 2182 this.parser.assistNodeParent, 2183 this.parser.enclosingNode, 2184 parsedUnit, 2185 e.qualifiedBinding, 2186 e.scope, 2187 e.insideTypeAnnotation); 2188 } 2189 } finally { 2190 this.skipDefaultPackage = false; 2191 } 2192 } 2193 // scan the package & import statements first 2194 if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) { 2195 contextAccepted = true; 2196 buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null); 2197 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 2198 findPackages((CompletionOnPackageReference) parsedUnit.currentPackage); 2199 } 2200 debugPrintf(); 2201 return; 2202 } 2203 2204 ImportReference[] imports = parsedUnit.imports; 2205 if (imports != null) { 2206 for (int i = 0, length = imports.length; i < length; i++) { 2207 ImportReference importReference = imports[i]; 2208 if (importReference instanceof CompletionOnImportReference) { 2209 this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); 2210 if ((this.unitScope = parsedUnit.scope) != null) { 2211 contextAccepted = true; 2212 buildContext(importReference, null, parsedUnit, null, this.unitScope); 2213 2214 long positions = importReference.sourcePositions[importReference.tokens.length - 1]; 2215 setSourceAndTokenRange((int) (positions >>> 32), (int) positions); 2216 2217 char[][] oldTokens = importReference.tokens; 2218 int tokenCount = oldTokens.length; 2219 if (tokenCount == 1) { 2220 findImports((CompletionOnImportReference)importReference, true); 2221 } else if(tokenCount > 1){ 2222 this.insideQualifiedReference = true; 2223 2224 char[] lastToken = oldTokens[tokenCount - 1]; 2225 char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1); 2226 2227 Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens); 2228 if(binding != null) { 2229 if(binding instanceof PackageBinding) { 2230 findImports((CompletionOnImportReference)importReference, false); 2231 } else { 2232 ReferenceBinding ref = (ReferenceBinding) binding; 2233 2234 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 2235 findImportsOfMemberTypes(lastToken, ref, importReference.isStatic()); 2236 } 2237 if(importReference.isStatic()) { 2238 2239 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 2240 findImportsOfStaticFields(lastToken, ref); 2241 } 2242 if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) { 2243 findImportsOfStaticMethods(lastToken, ref); 2244 } 2245 } 2246 } 2247 } 2248 } 2249 2250 debugPrintf(); 2251 } 2252 return; 2253 } else if(importReference instanceof CompletionOnKeyword) { 2254 contextAccepted = true; 2255 buildContext(importReference, null, parsedUnit, null, null); 2256 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2257 setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd); 2258 CompletionOnKeyword keyword = (CompletionOnKeyword)importReference; 2259 findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, parsedUnit.currentPackage != null); 2260 } 2261 debugPrintf(); 2262 return; 2263 } 2264 } 2265 } 2266 // javadoc tag completion in module-info file 2267 contextAccepted = completeJavadocTagInModuleInfo(parsedUnit); 2268 if (parsedUnit.types != null) { 2269 try { 2270 this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); 2271 2272 if ((this.unitScope = parsedUnit.scope) != null) { 2273 this.lookupEnvironment.completeTypeBindings(parsedUnit, true); 2274 parsedUnit.scope.faultInTypes(); 2275 parseBlockStatements(parsedUnit, this.actualCompletionPosition); 2276 if(DEBUG) { 2277 System.out.println("COMPLETION - AST :"); //$NON-NLS-1$ 2278 System.out.println(parsedUnit.toString()); 2279 } 2280 parsedUnit.resolve(); 2281 } 2282 } catch (CompletionNodeFound e) { 2283 // completionNodeFound = true; 2284 if (e.astNode != null) { 2285 // if null then we found a problem in the completion node 2286 if(DEBUG) { 2287 System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$ 2288 System.out.println(e.astNode.toString()); 2289 if(this.parser.assistNodeParent != null) { 2290 System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$ 2291 System.out.println(this.parser.assistNodeParent); 2292 } 2293 } 2294 this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting 2295 contextAccepted = 2296 complete( 2297 e.astNode, 2298 this.parser.assistNodeParent, 2299 this.parser.enclosingNode, 2300 parsedUnit, 2301 e.qualifiedBinding, 2302 e.scope, 2303 e.insideTypeAnnotation); 2304 } 2305 } 2306 } 2307 } 2308 2309 if(this.noProposal && this.problem != null) { 2310 if(!contextAccepted) { 2311 contextAccepted = true; 2312 InternalCompletionContext context = new InternalCompletionContext(); 2313 context.setOffset(completionPosition - this.offset); 2314 context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN); 2315 if (this.requestor.isExtendedContextRequired()) context.setExtended(); 2316 this.requestor.acceptContext(context); 2317 } 2318 this.requestor.completionFailure(this.problem); 2319 if(DEBUG) { 2320 this.printDebug(this.problem); 2321 } 2322 } 2323 /* Ignore package, import, class & interface keywords for now... 2324 if (!completionNodeFound) { 2325 if (parsedUnit == null || parsedUnit.types == null) { 2326 // this is not good enough... can still be trying to define a second type 2327 CompletionScanner scanner = (CompletionScanner) this.parser.scanner; 2328 setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd); 2329 findKeywords(scanner.completionIdentifier, mainDeclarations, null); 2330 } 2331 // currently have no way to know if extends/implements are possible keywords 2332 } 2333 */ 2334 } catch (IndexOutOfBoundsException | InvalidCursorLocation | AbortCompilation | CompletionNodeFound e){ // internal failure - bugs 5618 2335 if(DEBUG) { 2336 System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$ 2337 e.printStackTrace(System.out); 2338 } 2339 } finally { 2340 if(!contextAccepted) { 2341 contextAccepted = true; 2342 InternalCompletionContext context = new InternalCompletionContext(); 2343 context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN); 2344 context.setOffset(completionPosition - this.offset); 2345 if (this.requestor.isExtendedContextRequired()) context.setExtended(); 2346 this.requestor.acceptContext(context); 2347 } 2348 this.requestor.endReporting(); 2349 if (this.monitor != null) this.monitor.done(); 2350 reset(); 2351 } 2352 } 2353 completeJavadocTagInModuleInfo(CompilationUnitDeclaration parsedUnit)2354 private boolean completeJavadocTagInModuleInfo(CompilationUnitDeclaration parsedUnit) { 2355 boolean contextAccepted = false; 2356 if (this.parser.assistNodeParent instanceof CompletionJavadoc && parsedUnit.isModuleInfo() ) { 2357 try { 2358 this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/); 2359 if(this.parser.assistNode instanceof CompletionOnJavadocTag) { 2360 ((CompletionOnJavadocTag)this.parser.assistNode).filterPossibleTags(parsedUnit.scope); 2361 } 2362 throw new CompletionNodeFound(this.parser.assistNode, null, parsedUnit.scope); 2363 } 2364 catch (CompletionNodeFound e) { 2365 this.unitScope = parsedUnit.scope; 2366 if (e.astNode != null) { 2367 // if null then we found a problem in the completion node 2368 if(DEBUG) { 2369 System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$ 2370 System.out.println(e.astNode.toString()); 2371 if(this.parser.assistNodeParent != null) { 2372 System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$ 2373 System.out.println(this.parser.assistNodeParent); 2374 } 2375 } 2376 this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting 2377 contextAccepted = 2378 complete( 2379 e.astNode, 2380 this.parser.assistNodeParent, 2381 this.parser.enclosingNode, 2382 parsedUnit, 2383 e.qualifiedBinding, 2384 e.scope, 2385 e.insideTypeAnnotation); 2386 } 2387 } 2388 } 2389 return contextAccepted; 2390 } 2391 checkForCNF(TypeReference ref, CompilationUnitDeclaration parsedUnit, boolean showAll)2392 private boolean checkForCNF(TypeReference ref, CompilationUnitDeclaration parsedUnit, boolean showAll) { 2393 this.lookupEnvironment.buildTypeBindings(parsedUnit, null); 2394 this.lookupEnvironment.completeTypeBindings(parsedUnit, true); 2395 parsedUnit.resolve(); 2396 this.startPosition = ref.sourceStart; 2397 this.endPosition = ref.sourceEnd > ref.sourceStart ? ref.sourceEnd : ref.sourceStart; 2398 if ((this.unitScope = parsedUnit.scope) != null) { 2399 if (showAll) { 2400 char[][] tokens = ref.getTypeName(); 2401 char[] typeName = CharOperation.concatWithAll(tokens, '.'); 2402 if (typeName.length == 0) { 2403 buildContext(ref, null, parsedUnit, null, null); 2404 this.completionToken = new char[] {'*'}; 2405 findTypesAndPackages(this.completionToken, this.unitScope, true, true, new ObjectVector()); 2406 return true; 2407 } 2408 } 2409 parsedUnit.scope.faultInTypes(); 2410 } 2411 return false; // should not come here - will throw exception 2412 } 2413 completeOnPackageVisibilityStatements(boolean contextAccepted, CompilationUnitDeclaration parsedUnit, PackageVisibilityStatement[] pvsStmts)2414 private boolean completeOnPackageVisibilityStatements(boolean contextAccepted, 2415 CompilationUnitDeclaration parsedUnit, PackageVisibilityStatement[] pvsStmts) { 2416 try { 2417 this.skipDefaultPackage = true; 2418 for (int i = 0, l = pvsStmts.length; i < l; ++i) { 2419 PackageVisibilityStatement pvs = pvsStmts[i]; 2420 if (pvs instanceof CompletionOnKeywordModuleInfo) { // dummy pvs statement 2421 contextAccepted = true; 2422 processModuleKeywordCompletion(parsedUnit, pvs, (CompletionOnKeyword) pvs); 2423 return contextAccepted; 2424 } 2425 if (pvs.pkgRef instanceof CompletionOnPackageVisibilityReference) { 2426 contextAccepted = true; 2427 buildContext(pvs, null, parsedUnit, null, null); 2428 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 2429 findPackages((CompletionOnPackageVisibilityReference) pvs.pkgRef); 2430 } 2431 debugPrintf(); 2432 return contextAccepted; 2433 } 2434 ModuleReference[] targets = pvs.targets; 2435 if (targets == null) continue; 2436 HashSet<String> skipSet = new HashSet<>(); 2437 for (int j = 0, lj = targets.length; j < lj; j++) { 2438 ModuleReference target = targets[j]; 2439 if (target == null) break; 2440 if (target instanceof CompletionOnModuleReference) { 2441 buildContext(target, null, parsedUnit, null, null); 2442 contextAccepted = true; 2443 if(!this.requestor.isIgnored(CompletionProposal.MODULE_REF)) { 2444 findTargettedModules((CompletionOnModuleReference) target, skipSet); 2445 } 2446 debugPrintf(); 2447 return contextAccepted; 2448 } else if (target instanceof CompletionOnKeyword) { 2449 contextAccepted = true; 2450 processModuleKeywordCompletion(parsedUnit, target, (CompletionOnKeyword) target); 2451 } else { 2452 if (target.moduleName != null || target.moduleName == CharOperation.NO_CHAR) 2453 skipSet.add(new String(target.moduleName)); 2454 } 2455 } 2456 } 2457 } finally { 2458 this.skipDefaultPackage = false; 2459 } 2460 return contextAccepted; 2461 } 2462 debugPrintf()2463 private void debugPrintf() { 2464 if(this.noProposal && this.problem != null) { 2465 this.requestor.completionFailure(this.problem); 2466 if(DEBUG) { 2467 this.printDebug(this.problem); 2468 } 2469 } 2470 } 2471 processModuleKeywordCompletion(CompilationUnitDeclaration parsedUnit, ASTNode node, CompletionOnKeyword keyword)2472 private void processModuleKeywordCompletion(CompilationUnitDeclaration parsedUnit, ASTNode node, CompletionOnKeyword keyword) { 2473 buildContext(node, null, parsedUnit, null, null); 2474 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2475 setSourceAndTokenRange(node.sourceStart, node.sourceEnd); 2476 findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, parsedUnit.currentPackage != null); 2477 } 2478 debugPrintf(); 2479 } 2480 complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic)2481 public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){ 2482 if(this.requestor != null){ 2483 this.requestor.beginReporting(); 2484 } 2485 boolean contextAccepted = false; 2486 IType topLevelType = type; 2487 while(topLevelType.getDeclaringType() != null) { 2488 topLevelType = topLevelType.getDeclaringType(); 2489 } 2490 2491 this.fileName = topLevelType.getParent().getElementName().toCharArray(); 2492 CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit); 2493 2494 CompilationUnitDeclaration compilationUnit = null; 2495 2496 try { 2497 // TypeConverter is used instead of SourceTypeConverter because the type 2498 // to convert can be a binary type or a source type 2499 TypeDeclaration typeDeclaration = null; 2500 if (type instanceof SourceType) { 2501 SourceType sourceType = (SourceType) type; 2502 ISourceType info = (ISourceType) sourceType.getElementInfo(); 2503 compilationUnit = SourceTypeConverter.buildCompilationUnit( 2504 new ISourceType[] {info},//sourceTypes[0] is always toplevel here 2505 SourceTypeConverter.FIELD_AND_METHOD // need field and methods 2506 | SourceTypeConverter.MEMBER_TYPE, // need member types 2507 // no need for field initialization 2508 this.problemReporter, 2509 compilationResult); 2510 if (compilationUnit != null && compilationUnit.types != null) 2511 typeDeclaration = compilationUnit.types[0]; 2512 } else { 2513 compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0); 2514 typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit); 2515 } 2516 2517 if(typeDeclaration != null) { 2518 // build AST from snippet 2519 Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic); 2520 2521 // merge AST 2522 FieldDeclaration[] oldFields = typeDeclaration.fields; 2523 FieldDeclaration[] newFields = null; 2524 if (oldFields != null) { 2525 newFields = new FieldDeclaration[oldFields.length + 1]; 2526 System.arraycopy(oldFields, 0, newFields, 0, oldFields.length); 2527 newFields[oldFields.length] = fakeInitializer; 2528 } else { 2529 newFields = new FieldDeclaration[] {fakeInitializer}; 2530 } 2531 typeDeclaration.fields = newFields; 2532 2533 if(DEBUG) { 2534 System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$ 2535 System.out.println(compilationUnit.toString()); 2536 } 2537 2538 if (compilationUnit.types != null) { 2539 try { 2540 this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/); 2541 2542 if ((this.unitScope = compilationUnit.scope) != null) { 2543 this.lookupEnvironment.completeTypeBindings(compilationUnit, true); 2544 compilationUnit.scope.faultInTypes(); 2545 compilationUnit.resolve(); 2546 } 2547 } catch (CompletionNodeFound e) { 2548 // completionNodeFound = true; 2549 if (e.astNode != null) { 2550 // if null then we found a problem in the completion node 2551 contextAccepted = 2552 complete( 2553 e.astNode, 2554 this.parser.assistNodeParent, 2555 this.parser.enclosingNode, 2556 compilationUnit, 2557 e.qualifiedBinding, 2558 e.scope, 2559 e.insideTypeAnnotation); 2560 } 2561 } 2562 } 2563 if(this.noProposal && this.problem != null) { 2564 if(!contextAccepted) { 2565 contextAccepted = true; 2566 InternalCompletionContext context = new InternalCompletionContext(); 2567 if (this.requestor.isExtendedContextRequired()) context.setExtended(); 2568 this.requestor.acceptContext(context); 2569 } 2570 this.requestor.completionFailure(this.problem); 2571 if(DEBUG) { 2572 this.printDebug(this.problem); 2573 } 2574 } 2575 } 2576 } catch (IndexOutOfBoundsException | InvalidCursorLocation | AbortCompilation | CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629) 2577 if(DEBUG) { 2578 System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$ 2579 e.printStackTrace(System.out); 2580 } 2581 } catch(JavaModelException e) { 2582 // Do nothing 2583 } 2584 if(!contextAccepted) { 2585 contextAccepted = true; 2586 InternalCompletionContext context = new InternalCompletionContext(); 2587 if (this.requestor.isExtendedContextRequired()) context.setExtended(); 2588 this.requestor.acceptContext(context); 2589 } 2590 if(this.requestor != null){ 2591 this.requestor.endReporting(); 2592 } 2593 } 2594 completionOnBranchStatementLabel(ASTNode astNode)2595 private void completionOnBranchStatementLabel(ASTNode astNode) { 2596 if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) { 2597 CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode; 2598 this.completionToken = label.label; 2599 findLabels(this.completionToken, label.possibleLabels); 2600 } 2601 } 2602 completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope)2603 private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2604 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 2605 CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode; 2606 setSourceAndTokenRange(access.classStart, access.sourceEnd); 2607 this.completionToken = access.completionIdentifier; 2608 findClassField( 2609 this.completionToken, 2610 (TypeBinding) qualifiedBinding, 2611 scope, 2612 null, 2613 null, 2614 null, 2615 false); 2616 } 2617 } 2618 completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope)2619 private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2620 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 2621 setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false); 2622 CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode; 2623 TypeBinding[] argTypes = computeTypes(constructorCall.arguments); 2624 findConstructors( 2625 (ReferenceBinding) qualifiedBinding, 2626 argTypes, 2627 scope, 2628 constructorCall, 2629 false, 2630 null, 2631 null, 2632 null, 2633 false); 2634 } 2635 } 2636 completionOnFieldName(ASTNode astNode, Scope scope)2637 private void completionOnFieldName(ASTNode astNode, Scope scope) { 2638 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 2639 CompletionOnFieldName field = (CompletionOnFieldName) astNode; 2640 2641 FieldBinding[] fields = scope.enclosingSourceType().fields(); 2642 char[][] excludeNames = new char[fields.length][]; 2643 for(int i = 0 ; i < fields.length ; i++){ 2644 excludeNames[i] = fields[i].name; 2645 } 2646 2647 this.completionToken = field.realName; 2648 2649 2650 int kind = 2651 (field.modifiers & ClassFileConstants.AccStatic) == 0 ? 2652 InternalNamingConventions.VK_INSTANCE_FIELD : 2653 (field.modifiers & ClassFileConstants.AccFinal) == 0 ? 2654 InternalNamingConventions.VK_STATIC_FIELD : 2655 InternalNamingConventions.VK_STATIC_FINAL_FIELD; 2656 2657 findVariableNames(field.realName, field.type, excludeNames, null, kind); 2658 } 2659 } 2660 completionOnFieldType(ASTNode astNode, Scope scope)2661 private void completionOnFieldType(ASTNode astNode, Scope scope) { 2662 CompletionOnFieldType field = (CompletionOnFieldType) astNode; 2663 CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type; 2664 this.completionToken = type.token; 2665 setSourceAndTokenRange(type.sourceStart, type.sourceEnd); 2666 2667 findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector()); 2668 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2669 findKeywordsForMember(this.completionToken, field.modifiers, astNode); 2670 } 2671 2672 if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) { 2673 SourceTypeBinding enclosingType = scope.enclosingSourceType(); 2674 if (!enclosingType.isAnnotationType()) { 2675 if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 2676 findMethodDeclarations( 2677 this.completionToken, 2678 enclosingType, 2679 scope, 2680 new ObjectVector(), 2681 null, 2682 null, 2683 null, 2684 false); 2685 } 2686 if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 2687 proposeNewMethod(this.completionToken, enclosingType); 2688 } 2689 } 2690 } 2691 } 2692 //TODO completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope)2693 private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2694 // setSourceRange(astNode.sourceStart, astNode.sourceEnd, false); 2695 2696 CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode; 2697 this.javadocTagPosition = allocExpression.tagSourceStart; 2698 int rangeStart = astNode.sourceStart; 2699 if (allocExpression.type.isThis()) { 2700 if (allocExpression.completeInText()) { 2701 rangeStart = allocExpression.separatorPosition; 2702 } 2703 } else if (allocExpression.completeInText()) { 2704 rangeStart = allocExpression.type.sourceStart; 2705 } 2706 setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false); 2707 TypeBinding[] argTypes = computeTypes(allocExpression.arguments); 2708 2709 ReferenceBinding ref = (ReferenceBinding) qualifiedBinding; 2710 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) { 2711 findConstructors(ref, argTypes, scope, allocExpression, false, null, null, null, false); 2712 } 2713 } 2714 //TODO completionOnJavadocFieldReference(ASTNode astNode, Scope scope)2715 private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) { 2716 this.insideQualifiedReference = true; 2717 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode; 2718 this.completionToken = fieldRef.token; 2719 long completionPosition = fieldRef.nameSourcePosition; 2720 this.javadocTagPosition = fieldRef.tagSourceStart; 2721 2722 if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) { 2723 ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType; 2724 int rangeStart = (int) (completionPosition >>> 32); 2725 if (fieldRef.receiver.isThis()) { 2726 if (fieldRef.completeInText()) { 2727 rangeStart = fieldRef.separatorPosition; 2728 } 2729 } else if (fieldRef.completeInText()) { 2730 rangeStart = fieldRef.receiver.sourceStart; 2731 } 2732 setSourceAndTokenRange(rangeStart, (int) completionPosition); 2733 2734 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF) 2735 || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) { 2736 findFields(this.completionToken, 2737 receiverType, 2738 scope, 2739 new ObjectVector(), 2740 new ObjectVector(), 2741 false, /*not only static */ 2742 fieldRef, 2743 scope, 2744 false, 2745 true, 2746 null, 2747 null, 2748 null, 2749 false, 2750 null, 2751 -1, 2752 -1); 2753 } 2754 2755 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) 2756 || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 2757 findMethods( 2758 this.completionToken, 2759 null, 2760 null, 2761 receiverType, 2762 scope, 2763 new ObjectVector(), 2764 false, /*not only static */ 2765 false, 2766 fieldRef, 2767 scope, 2768 false, 2769 false, 2770 true, 2771 null, 2772 null, 2773 null, 2774 false, 2775 null, 2776 -1, 2777 -1); 2778 if (fieldRef.actualReceiverType instanceof ReferenceBinding) { 2779 ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType; 2780 if (this.completionToken == null 2781 || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName) 2782 || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) { 2783 findConstructors(refBinding, null, scope, fieldRef, false, null, null, null, false); 2784 } 2785 } 2786 } 2787 } 2788 } 2789 //TODO completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope)2790 private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2791 CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode; 2792 TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments); 2793 this.completionToken = messageSend.selector; 2794 this.javadocTagPosition = messageSend.tagSourceStart; 2795 2796 // Set source range 2797 int rangeStart = astNode.sourceStart; 2798 if (messageSend.receiver.isThis()) { 2799 if (messageSend.completeInText()) { 2800 rangeStart = messageSend.separatorPosition; 2801 } 2802 } else if (messageSend.completeInText()) { 2803 rangeStart = messageSend.receiver.sourceStart; 2804 } 2805 setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false); 2806 2807 if (qualifiedBinding == null) { 2808 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 2809 findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector()); 2810 } 2811 } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 2812 findMethods( 2813 this.completionToken, 2814 null, 2815 argTypes, 2816 (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd), 2817 scope, 2818 new ObjectVector(), 2819 false, 2820 false/* prefix match */, 2821 messageSend, 2822 scope, 2823 false, 2824 messageSend.receiver instanceof SuperReference, 2825 true, 2826 null, 2827 null, 2828 null, 2829 false, 2830 null, 2831 -1, 2832 -1); 2833 } 2834 } 2835 //TODO completionOnJavadocParamNameReference(ASTNode astNode)2836 private void completionOnJavadocParamNameReference(ASTNode astNode) { 2837 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 2838 CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode; 2839 setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd); 2840 findJavadocParamNames(paramRef.token, paramRef.missingParams, false); 2841 findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true); 2842 } 2843 } 2844 //TODO completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope)2845 private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2846 this.insideQualifiedReference = true; 2847 2848 CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode; 2849 this.completionToken = typeRef.completionIdentifier; 2850 long completionPosition = typeRef.sourcePositions[typeRef.tokens.length]; 2851 this.javadocTagPosition = typeRef.tagSourceStart; 2852 2853 // get the source positions of the completion identifier 2854 if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 2855 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 2856 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) { 2857 int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32); 2858 setSourceAndTokenRange(rangeStart, (int) completionPosition); 2859 findMemberTypes( 2860 this.completionToken, 2861 (ReferenceBinding) qualifiedBinding, 2862 scope, 2863 scope.enclosingSourceType(), 2864 false, 2865 false, 2866 new ObjectVector(), 2867 null, 2868 null, 2869 null, 2870 false); 2871 } 2872 } else if (qualifiedBinding instanceof PackageBinding) { 2873 2874 setSourceRange(astNode.sourceStart, (int) completionPosition); 2875 int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32); 2876 setTokenRange(rangeStart, (int) completionPosition); 2877 // replace to the end of the completion identifier 2878 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 2879 } 2880 } 2881 //TODO completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope)2882 private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) { 2883 CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode; 2884 this.completionToken = typeRef.token; 2885 this.javadocTagPosition = typeRef.tagSourceStart; 2886 setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd); 2887 findTypesAndPackages( 2888 this.completionToken, 2889 scope, 2890 (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0, 2891 false, 2892 new ObjectVector()); 2893 } 2894 //TODO completionOnJavadocTag(ASTNode astNode)2895 private void completionOnJavadocTag(ASTNode astNode) { 2896 CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode; 2897 setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd); 2898 findJavadocBlockTags(javadocTag); 2899 findJavadocInlineTags(javadocTag); 2900 } 2901 //TODO completionOnJavadocTypeParamReference(ASTNode astNode)2902 private void completionOnJavadocTypeParamReference(ASTNode astNode) { 2903 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 2904 CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode; 2905 setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd); 2906 findJavadocParamNames(paramRef.token, paramRef.missingParams, true); 2907 } 2908 } 2909 completionOnKeyword(ASTNode astNode)2910 private void completionOnKeyword(ASTNode astNode) { 2911 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2912 CompletionOnKeyword keyword = (CompletionOnKeyword)astNode; 2913 findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false); 2914 } 2915 } 2916 completionOnLocalOrArgumentName(ASTNode astNode, Scope scope)2917 private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) { 2918 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 2919 LocalDeclaration variable = (LocalDeclaration) astNode; 2920 2921 int kind; 2922 if (variable instanceof CompletionOnLocalName){ 2923 this.completionToken = ((CompletionOnLocalName) variable).realName; 2924 kind = InternalNamingConventions.VK_LOCAL; 2925 } else { 2926 CompletionOnArgumentName arg = (CompletionOnArgumentName) variable; 2927 this.completionToken = arg.realName; 2928 kind = arg.isCatchArgument ? InternalNamingConventions.VK_LOCAL : InternalNamingConventions.VK_PARAMETER; 2929 } 2930 2931 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable); 2932 2933 char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName); 2934 2935 LocalVariableBinding[] locals = ((BlockScope)scope).locals; 2936 char[][] discouragedNames = new char[locals.length][]; 2937 int localCount = 0; 2938 for(int i = 0 ; i < locals.length ; i++){ 2939 if (locals[i] != null) { 2940 discouragedNames[localCount++] = locals[i].name; 2941 } 2942 } 2943 2944 System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount); 2945 2946 findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind); 2947 } 2948 } 2949 completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope)2950 private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 2951 CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode; 2952 2953 // When completion is inside lambda body, the fake type cannot be attached to the lambda. 2954 ReferenceContext referenceContext = scope.parent.referenceContext(); 2955 CompletionOnAnnotationOfType fakeType; 2956 if (referenceContext instanceof CompletionOnAnnotationOfType) { 2957 fakeType = (CompletionOnAnnotationOfType) referenceContext; 2958 } else { 2959 fakeType = new CompletionOnAnnotationOfType(CompletionParser.FAKE_TYPE_NAME, scope.referenceCompilationUnit().compilationResult, annot); 2960 } 2961 if (fakeType.annotations[0] == annot) { 2962 // When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery. 2963 // So 'targetedElement' is not computed in this case. 2964 if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) { 2965 this.targetedElement = computeTargetedElement(fakeType); 2966 } 2967 2968 } 2969 2970 this.assistNodeIsAnnotation = true; 2971 if (annot.type instanceof CompletionOnSingleTypeReference) { 2972 CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type; 2973 this.completionToken = type.token; 2974 setSourceAndTokenRange(type.sourceStart, type.sourceEnd); 2975 2976 if (scope.parent.parent != null && 2977 !(scope.parent.parent instanceof MethodScope) && !fakeType.isParameter) { 2978 2979 if (this.completionToken.length <= Keywords.INTERFACE.length 2980 && CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */ 2981 )){ 2982 int relevance = computeBaseRelevance(); 2983 relevance += computeRelevanceForResolution(); 2984 relevance += computeRelevanceForInterestingProposal(); 2985 relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE); 2986 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords 2987 relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals 2988 2989 this.noProposal = false; 2990 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 2991 CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 2992 proposal.setName(Keywords.INTERFACE); 2993 proposal.setCompletion(Keywords.INTERFACE); 2994 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 2995 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 2996 proposal.setRelevance(relevance); 2997 this.requestor.accept(proposal); 2998 if(DEBUG) { 2999 this.printDebug(proposal); 3000 } 3001 } 3002 } 3003 } 3004 3005 findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector()); 3006 } else if (annot.type instanceof CompletionOnQualifiedTypeReference) { 3007 this.insideQualifiedReference = true; 3008 3009 CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type; 3010 this.completionToken = type.completionIdentifier; 3011 long completionPosition = type.sourcePositions[type.tokens.length]; 3012 if (qualifiedBinding instanceof PackageBinding) { 3013 3014 setSourceRange(astNode.sourceStart, (int) completionPosition); 3015 setTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3016 // replace to the end of the completion identifier 3017 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 3018 } else { 3019 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3020 3021 findMemberTypes( 3022 this.completionToken, 3023 (ReferenceBinding) qualifiedBinding, 3024 scope, 3025 scope.enclosingSourceType(), 3026 false, 3027 false, 3028 new ObjectVector(), 3029 null, 3030 null, 3031 null, 3032 false); 3033 } 3034 } 3035 } 3036 completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation)3037 private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding, 3038 Scope scope, boolean insideTypeAnnotation) { 3039 this.insideQualifiedReference = true; 3040 CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode; 3041 long completionPosition = access.nameSourcePosition; 3042 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3043 3044 this.completionToken = access.token; 3045 3046 if (qualifiedBinding.problemId() == ProblemReasons.NotFound) { 3047 // complete method members with missing return type 3048 // class X { 3049 // Missing f() {return null;} 3050 // void foo() { 3051 // f().| 3052 // } 3053 // } 3054 if (this.assistNodeInJavadoc == 0 && 3055 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 3056 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) { 3057 ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding; 3058 findFieldsAndMethodsFromMissingReturnType( 3059 problemMethodBinding.selector, 3060 problemMethodBinding.parameters, 3061 scope, 3062 access, 3063 insideTypeAnnotation); 3064 } 3065 } else { 3066 if (!access.isInsideAnnotation) { 3067 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD) && !access.isSuperAccess()) { 3068 findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false); 3069 } 3070 3071 ObjectVector fieldsFound = new ObjectVector(); 3072 ObjectVector methodsFound = new ObjectVector(); 3073 3074 boolean superCall = access.receiver instanceof SuperReference; 3075 3076 findFieldsAndMethods( 3077 this.completionToken, 3078 ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceStart, access.receiver.sourceEnd), 3079 scope, 3080 fieldsFound, 3081 methodsFound, 3082 access, 3083 scope, 3084 false, 3085 superCall, 3086 null, 3087 null, 3088 null, 3089 false, 3090 null, 3091 -1, 3092 -1); 3093 3094 if (!superCall) { 3095 3096 checkCancel(); 3097 3098 findFieldsAndMethodsFromCastedReceiver( 3099 enclosingNode, 3100 qualifiedBinding, 3101 scope, 3102 fieldsFound, 3103 methodsFound, 3104 access, 3105 scope, 3106 access.receiver); 3107 } 3108 } 3109 } 3110 } 3111 completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope, boolean insideTypeAnnotation)3112 private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope, 3113 boolean insideTypeAnnotation) { 3114 CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode; 3115 Annotation annotation = (Annotation) astNodeParent; 3116 3117 this.completionToken = memberValuePair.name; 3118 3119 ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType; 3120 3121 if (annotationType != null && annotationType.isAnnotationType()) { 3122 if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) { 3123 findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType); 3124 } 3125 if (this.assistNodeCanBeSingleMemberAnnotation) { 3126 if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) { 3127 findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector()); 3128 } else { 3129 if (this.expectedTypesPtr > -1) { 3130 this.assistNodeIsEnum = true; 3131 done : for (int i = 0; i <= this.expectedTypesPtr; i++) { 3132 if (!this.expectedTypes[i].isEnum()) { 3133 this.assistNodeIsEnum = false; 3134 break done; 3135 } 3136 } 3137 3138 } 3139 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 3140 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite); 3141 3142 findUnresolvedReference( 3143 memberValuePair.sourceStart, 3144 memberValuePair.sourceEnd, 3145 (BlockScope)scope, 3146 alreadyDefinedName); 3147 } 3148 findVariablesAndMethods( 3149 this.completionToken, 3150 scope, 3151 FakeInvocationSite, 3152 scope, 3153 insideTypeAnnotation, 3154 true); 3155 // can be the start of a qualified type name 3156 findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector()); 3157 } 3158 } 3159 } 3160 } 3161 completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope)3162 private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 3163 setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false); 3164 3165 CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode; 3166 TypeBinding[] argTypes = computeTypes(messageSend.arguments); 3167 this.completionToken = messageSend.selector; 3168 if (qualifiedBinding == null) { 3169 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 3170 ObjectVector methodsFound = new ObjectVector(); 3171 3172 findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound); 3173 3174 checkCancel(); 3175 3176 findLocalMethodsFromStaticImports( 3177 this.completionToken, 3178 scope, 3179 messageSend, 3180 scope, 3181 true, 3182 methodsFound, 3183 true); 3184 } 3185 } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 3186 findMethods( 3187 this.completionToken, 3188 null, 3189 argTypes, 3190 (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd), 3191 scope, 3192 new ObjectVector(), 3193 false, 3194 true, 3195 messageSend, 3196 scope, 3197 false, 3198 messageSend.receiver instanceof SuperReference, 3199 false, 3200 null, 3201 null, 3202 null, 3203 false, 3204 null, 3205 -1, 3206 -1); 3207 } 3208 } 3209 completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope)3210 private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 3211 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 3212 CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode; 3213 3214 this.insideQualifiedReference = true; 3215 this.completionToken = messageSend.selector; 3216 boolean onlyStatic = false; 3217 if (messageSend.receiver instanceof NameReference) { 3218 onlyStatic = ((NameReference)messageSend.receiver).isTypeReference(); 3219 } else if (!(messageSend.receiver instanceof MessageSend) && 3220 !(messageSend.receiver instanceof FieldReference) && 3221 !(messageSend.receiver.isThis())) { 3222 onlyStatic = true; 3223 } 3224 3225 TypeBinding receiverType = (TypeBinding)qualifiedBinding; 3226 3227 if(receiverType != null && receiverType instanceof ReferenceBinding) { 3228 TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments); 3229 if(typeArgTypes != null) { 3230 findMethods( 3231 this.completionToken, 3232 typeArgTypes, 3233 null, 3234 (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceStart, messageSend.receiver.sourceEnd), 3235 scope, 3236 new ObjectVector(), 3237 onlyStatic, 3238 false, 3239 messageSend, 3240 scope, 3241 false, 3242 false, 3243 false, 3244 null, 3245 null, 3246 null, 3247 false, 3248 null, 3249 -1, 3250 -1); 3251 } 3252 } 3253 } 3254 } completionOnReferenceExpressionName(ASTNode astNode, Binding qualifiedBinding, Scope scope)3255 private void completionOnReferenceExpressionName(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 3256 if (!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) { 3257 CompletionOnReferenceExpressionName referenceExpression = (CompletionOnReferenceExpressionName) astNode; 3258 this.insideQualifiedReference = true; 3259 this.completionToken = referenceExpression.selector; 3260 boolean onlyStatic = false; 3261 3262 TypeBinding receiverType = (TypeBinding) qualifiedBinding; 3263 if (receiverType != null && receiverType instanceof ReferenceBinding) { 3264 setSourceAndTokenRange(referenceExpression.nameSourceStart, referenceExpression.sourceEnd); 3265 if (!(receiverType.isInterface() || this.requestor.isIgnored(CompletionProposal.KEYWORD))) { 3266 this.assistNodeIsConstructor = true; 3267 findKeywords(this.completionToken, new char[][] { Keywords.NEW }, false, false); 3268 } 3269 findMethods( 3270 this.completionToken, 3271 referenceExpression.resolvedTypeArguments, 3272 null, 3273 (ReferenceBinding)receiverType.capture(scope, referenceExpression.sourceStart, referenceExpression.sourceEnd), 3274 scope, 3275 new ObjectVector(), 3276 onlyStatic, 3277 false, 3278 referenceExpression, 3279 scope, 3280 false, 3281 false, 3282 false, 3283 null, 3284 null, 3285 null, 3286 false, 3287 null, 3288 -1, 3289 -1); 3290 } 3291 } 3292 } 3293 3294 completionOnMethodName(ASTNode astNode, Scope scope)3295 private void completionOnMethodName(ASTNode astNode, Scope scope) { 3296 if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 3297 CompletionOnMethodName method = (CompletionOnMethodName) astNode; 3298 3299 setSourceAndTokenRange(method.sourceStart, method.selectorEnd); 3300 3301 FieldBinding[] fields = scope.enclosingSourceType().fields(); 3302 char[][] excludeNames = new char[fields.length][]; 3303 for(int i = 0 ; i < fields.length ; i++){ 3304 excludeNames[i] = fields[i].name; 3305 } 3306 3307 this.completionToken = method.selector; 3308 3309 3310 int kind = 3311 (method.modifiers & ClassFileConstants.AccStatic) == 0 ? 3312 InternalNamingConventions.VK_INSTANCE_FIELD : 3313 (method.modifiers & ClassFileConstants.AccFinal) == 0 ? 3314 InternalNamingConventions.VK_STATIC_FIELD : 3315 InternalNamingConventions.VK_STATIC_FINAL_FIELD; 3316 3317 findVariableNames(this.completionToken, method.returnType, excludeNames, null, kind); 3318 } 3319 } 3320 completionOnMethodReturnType(ASTNode astNode, Scope scope)3321 private void completionOnMethodReturnType(ASTNode astNode, Scope scope) { 3322 CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode; 3323 SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType; 3324 this.completionToken = type.token; 3325 setSourceAndTokenRange(type.sourceStart, type.sourceEnd); 3326 findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector()); 3327 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 3328 findKeywordsForMember(this.completionToken, method.modifiers, null); 3329 } 3330 3331 if (method.modifiers == ClassFileConstants.AccDefault) { 3332 SourceTypeBinding enclosingType = scope.enclosingSourceType(); 3333 if (!enclosingType.isAnnotationType()) { 3334 if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 3335 findMethodDeclarations( 3336 this.completionToken, 3337 scope.enclosingSourceType(), 3338 scope, 3339 new ObjectVector(), 3340 null, 3341 null, 3342 null, 3343 false); 3344 } 3345 if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 3346 proposeNewMethod(this.completionToken, scope.enclosingSourceType()); 3347 } 3348 } 3349 } 3350 } 3351 completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3352 private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3353 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 3354 CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode; 3355 3356 this.insideQualifiedReference = true; 3357 3358 this.assistNodeIsClass = ref.isClass(); 3359 this.assistNodeIsException = ref.isException(); 3360 this.assistNodeIsInterface = ref.isInterface(); 3361 this.assistNodeIsSuperType = ref.isSuperType(); 3362 this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); 3363 this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent); 3364 3365 this.completionToken = ref.completionIdentifier; 3366 long completionPosition = ref.sourcePositions[ref.tokens.length]; 3367 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3368 3369 if (qualifiedBinding.problemId() == ProblemReasons.NotFound || 3370 (((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) { 3371 if (this.assistNodeInJavadoc == 0 && 3372 (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) { 3373 if(ref.tokens.length == 1) { 3374 findMemberTypesFromMissingType( 3375 ref, 3376 ref.sourcePositions[0], 3377 scope); 3378 } 3379 } 3380 } else { 3381 ObjectVector typesFound = new ObjectVector(); 3382 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 3383 findExceptionFromTryStatement( 3384 this.completionToken, 3385 (ReferenceBinding)qualifiedBinding, 3386 scope.enclosingSourceType(), 3387 (BlockScope)scope, 3388 typesFound); 3389 } 3390 3391 checkCancel(); 3392 3393 findMemberTypes( 3394 this.completionToken, 3395 (ReferenceBinding) qualifiedBinding, 3396 scope, 3397 scope.enclosingSourceType(), 3398 false, 3399 false, 3400 typesFound, 3401 null, 3402 null, 3403 null, 3404 false); 3405 } 3406 } 3407 } 3408 assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent)3409 private boolean assistNodeIsExtendedType(ASTNode astNode, ASTNode astNodeParent) { 3410 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=99399, don't propose final types for extension. 3411 if (astNodeParent == null) 3412 return false; 3413 if (astNodeParent instanceof TypeDeclaration) { 3414 TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent; 3415 return (typeDeclaration.superclass == astNode); 3416 } else if (astNodeParent instanceof TypeParameter) { 3417 TypeParameter typeParameter = (TypeParameter) astNodeParent; 3418 return (typeParameter.type == astNode); 3419 } else if (astNodeParent instanceof Wildcard) { 3420 Wildcard wildcard = (Wildcard) astNodeParent; 3421 return (wildcard.bound == astNode && wildcard.kind == Wildcard.EXTENDS); 3422 } 3423 return false; 3424 } 3425 assistNodeIsInterfaceExcludingAnnotation(ASTNode astNode, ASTNode astNodeParent)3426 private boolean assistNodeIsInterfaceExcludingAnnotation(ASTNode astNode, ASTNode astNodeParent) { 3427 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310423, don't propose annotations for implements. 3428 if (astNodeParent == null) 3429 return false; 3430 if (astNodeParent instanceof TypeDeclaration) { 3431 TypeDeclaration typeDeclaration = (TypeDeclaration) astNodeParent; 3432 TypeReference [] superInterfaces = typeDeclaration.superInterfaces; 3433 int length = superInterfaces == null ? 0 : superInterfaces.length; 3434 for (int i = 0; i < length; i++) { 3435 if (superInterfaces[i] == astNode) 3436 return true; 3437 } 3438 } 3439 return false; 3440 } 3441 assistNodeIsInsideCase(ASTNode astNode, ASTNode astNodeParent)3442 private boolean assistNodeIsInsideCase(ASTNode astNode, ASTNode astNodeParent) { 3443 // To find whether we're completing inside the case expression in a 3444 // switch case construct (https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346) 3445 if (astNodeParent instanceof SwitchStatement) { 3446 CaseStatement[] cases = ((SwitchStatement) astNodeParent).cases; 3447 for (int i = 0, caseCount = ((SwitchStatement) astNodeParent).caseCount; i < caseCount; i++) { 3448 CompletionNodeDetector detector = new CompletionNodeDetector(astNode, cases[i]); 3449 if (detector.containsCompletionNode()) { 3450 return true; 3451 } 3452 } 3453 } 3454 return false; 3455 } 3456 completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope)3457 private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) { 3458 setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false); 3459 3460 CompletionOnQualifiedAllocationExpression allocExpression = 3461 (CompletionOnQualifiedAllocationExpression) astNode; 3462 TypeBinding[] argTypes = computeTypes(allocExpression.arguments); 3463 3464 ReferenceBinding ref = (ReferenceBinding) qualifiedBinding; 3465 3466 if (ref.problemId() == ProblemReasons.NotFound) { 3467 findConstructorsFromMissingType( 3468 allocExpression.type, 3469 argTypes, 3470 scope, 3471 allocExpression); 3472 } else { 3473 if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) 3474 && ref.isClass() 3475 && !ref.isAbstract()) { 3476 findConstructors( 3477 ref, 3478 argTypes, 3479 scope, 3480 allocExpression, 3481 false, 3482 null, 3483 null, 3484 null, 3485 false); 3486 } 3487 3488 checkCancel(); 3489 3490 if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION) 3491 && !ref.isFinal() 3492 && !ref.isEnum()){ 3493 findAnonymousType( 3494 ref, 3495 argTypes, 3496 scope, 3497 allocExpression, 3498 null, 3499 null, 3500 null, 3501 false); 3502 } 3503 } 3504 } 3505 completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding, Scope scope, boolean insideTypeAnnotation)3506 private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding, 3507 Scope scope, boolean insideTypeAnnotation) { 3508 this.insideQualifiedReference = true; 3509 CompletionOnQualifiedNameReference ref = 3510 (CompletionOnQualifiedNameReference) astNode; 3511 this.completionToken = ref.completionIdentifier; 3512 long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1]; 3513 3514 if (qualifiedBinding.problemId() == ProblemReasons.NotFound) { 3515 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3516 // complete field members with missing fields type 3517 // class X { 3518 // Missing f; 3519 // void foo() { 3520 // f.| 3521 // } 3522 // } 3523 if (this.assistNodeInJavadoc == 0 && 3524 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 3525 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) || 3526 this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) { 3527 if(ref.tokens.length == 1) { 3528 boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation); 3529 3530 if (!foundSomeFields) { 3531 3532 checkCancel(); 3533 3534 findMembersFromMissingType( 3535 ref.tokens[0], 3536 ref.sourcePositions[0], 3537 null, 3538 scope, 3539 ref, 3540 ref.isInsideAnnotationAttribute); 3541 } 3542 } 3543 } 3544 } else if (qualifiedBinding instanceof VariableBinding) { 3545 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3546 TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type; 3547 if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) { 3548 ObjectVector fieldsFound = new ObjectVector(); 3549 ObjectVector methodsFound = new ObjectVector(); 3550 3551 findFieldsAndMethods( 3552 this.completionToken, 3553 receiverType.capture(scope, ref.sourceStart, ref.sourceEnd), 3554 scope, 3555 fieldsFound, 3556 methodsFound, 3557 ref, 3558 scope, 3559 false, 3560 false, 3561 null, 3562 null, 3563 null, 3564 false, 3565 null, 3566 -1, 3567 -1); 3568 3569 checkCancel(); 3570 3571 findFieldsAndMethodsFromCastedReceiver( 3572 enclosingNode, 3573 qualifiedBinding, 3574 scope, 3575 fieldsFound, 3576 methodsFound, 3577 ref, 3578 scope, 3579 ref); 3580 3581 } else if (this.assistNodeInJavadoc == 0 && 3582 (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) || 3583 this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) { 3584 boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF); 3585 boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF); 3586 if (proposeField || proposeMethod) { 3587 if(ref.tokens.length == 1) { 3588 if (qualifiedBinding instanceof LocalVariableBinding) { 3589 // complete local variable members with missing variables type 3590 // class X { 3591 // void foo() { 3592 // Missing f; 3593 // f.| 3594 // } 3595 // } 3596 LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding; 3597 findFieldsAndMethodsFromMissingType( 3598 localVariableBinding.declaration.type, 3599 localVariableBinding.declaringScope, 3600 ref, 3601 scope); 3602 } else { 3603 // complete field members with missing fields type 3604 // class X { 3605 // Missing f; 3606 // void foo() { 3607 // f.| 3608 // } 3609 // } 3610 findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation); 3611 } 3612 3613 } 3614 } 3615 } 3616 3617 } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 3618 boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute; 3619 ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding; 3620 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3621 3622 findMembers( 3623 this.completionToken, 3624 receiverType, 3625 scope, 3626 ref, 3627 isInsideAnnotationAttribute, 3628 null, 3629 null, 3630 null, 3631 false); 3632 3633 } else if (qualifiedBinding instanceof PackageBinding) { 3634 3635 setSourceRange(astNode.sourceStart, (int) completionPosition); 3636 setTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3637 3638 // replace to the end of the completion identifier 3639 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 3640 } 3641 } 3642 completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3643 private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, 3644 Scope scope) { 3645 this.insideQualifiedReference = true; 3646 3647 CompletionOnQualifiedTypeReference ref = 3648 (CompletionOnQualifiedTypeReference) astNode; 3649 3650 this.assistNodeIsClass = ref.isClass(); 3651 this.assistNodeIsException = ref.isException(); 3652 this.assistNodeIsInterface = ref.isInterface(); 3653 this.assistNodeIsConstructor = ref.isConstructorType; 3654 this.assistNodeIsSuperType = ref.isSuperType(); 3655 this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); 3656 this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent); 3657 3658 this.completionToken = ref.completionIdentifier; 3659 long completionPosition = ref.sourcePositions[ref.tokens.length]; 3660 3661 // get the source positions of the completion identifier 3662 if (qualifiedBinding.problemId() == ProblemReasons.NotFound) { 3663 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3664 if (this.assistNodeInJavadoc == 0 && 3665 (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) { 3666 if(ref.tokens.length == 1) { 3667 findMemberTypesFromMissingType( 3668 ref.tokens[0], 3669 ref.sourcePositions[0], 3670 scope); 3671 } 3672 } 3673 } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) { 3674 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 3675 setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3676 3677 ObjectVector typesFound = new ObjectVector(); 3678 3679 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 3680 findExceptionFromTryStatement( 3681 this.completionToken, 3682 (ReferenceBinding)qualifiedBinding, 3683 scope.enclosingSourceType(), 3684 (BlockScope)scope, 3685 typesFound); 3686 } 3687 3688 checkCancel(); 3689 3690 findMemberTypes( 3691 this.completionToken, 3692 (ReferenceBinding) qualifiedBinding, 3693 scope, 3694 scope.enclosingSourceType(), 3695 false, 3696 false, 3697 typesFound, 3698 null, 3699 null, 3700 null, 3701 false); 3702 } 3703 } else if (qualifiedBinding instanceof PackageBinding) { 3704 3705 setSourceRange(astNode.sourceStart, (int) completionPosition); 3706 setTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 3707 // replace to the end of the completion identifier 3708 findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope); 3709 } 3710 } 3711 completionOnProvidesInterfacesQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3712 private void completionOnProvidesInterfacesQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3713 // TODO: Filter the results wrt accessibility and add relevance to the results. 3714 completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 3715 } 3716 completionOnProvidesImplementationsQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3717 private void completionOnProvidesImplementationsQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3718 findImplementations((ProvidesStatement) this.parser.enclosingNode, (TypeReference) astNode); 3719 } 3720 completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope, boolean insideTypeAnnotation)3721 private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope, 3722 boolean insideTypeAnnotation) { 3723 CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode; 3724 this.completionToken = singleNameReference.token; 3725 SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null; 3726 if (switchStatement != null 3727 && switchStatement.expression.resolvedType != null 3728 && switchStatement.expression.resolvedType.isEnum()) { 3729 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 3730 this.assistNodeIsEnum = true; 3731 findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent); 3732 } 3733 } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) { 3734 findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector()); 3735 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 3736 findVariablesAndMethods( 3737 this.completionToken, 3738 scope, 3739 singleNameReference, 3740 scope, 3741 insideTypeAnnotation, 3742 singleNameReference.isInsideAnnotationAttribute); 3743 } 3744 } else { 3745 if (this.expectedTypesPtr > -1) { 3746 this.assistNodeIsEnum = true; 3747 done : for (int i = 0; i <= this.expectedTypesPtr; i++) { 3748 if (!this.expectedTypes[i].isEnum()) { 3749 this.assistNodeIsEnum = false; 3750 break done; 3751 } 3752 } 3753 3754 } 3755 if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 3756 char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference); 3757 3758 findUnresolvedReference( 3759 singleNameReference.sourceStart, 3760 singleNameReference.sourceEnd, 3761 (BlockScope)scope, 3762 alreadyDefinedName); 3763 } 3764 3765 checkCancel(); 3766 3767 findVariablesAndMethods( 3768 this.completionToken, 3769 scope, 3770 singleNameReference, 3771 scope, 3772 insideTypeAnnotation, 3773 singleNameReference.isInsideAnnotationAttribute); 3774 3775 checkCancel(); 3776 3777 // can be the start of a qualified type name 3778 findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector()); 3779 if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 3780 if (this.completionToken != null && this.completionToken.length != 0) { 3781 findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false); 3782 } else { 3783 findTrueOrFalseKeywords(singleNameReference.possibleKeywords); 3784 } 3785 } 3786 if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){ 3787 if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) { 3788 ReferenceBinding ref = scope.enclosingSourceType(); 3789 findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference); 3790 } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) { 3791 ReferenceBinding ref = scope.enclosingSourceType(); 3792 findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference); 3793 } 3794 } 3795 } 3796 } 3797 completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3798 private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3799 CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode; 3800 3801 this.completionToken = singleRef.token; 3802 3803 this.assistNodeIsClass = singleRef.isClass(); 3804 this.assistNodeIsException = singleRef.isException(); 3805 this.assistNodeIsInterface = singleRef.isInterface(); 3806 this.assistNodeIsConstructor = singleRef.isConstructorType; 3807 this.assistNodeIsSuperType = singleRef.isSuperType(); 3808 this.assistNodeIsExtendedType = assistNodeIsExtendedType(astNode, astNodeParent); 3809 this.assistNodeIsInterfaceExcludingAnnotation = assistNodeIsInterfaceExcludingAnnotation(astNode, astNodeParent); 3810 3811 // can be the start of a qualified type name 3812 if (qualifiedBinding == null) { 3813 if (this.completionToken.length == 0 && 3814 (astNodeParent instanceof ParameterizedSingleTypeReference || 3815 astNodeParent instanceof ParameterizedQualifiedTypeReference)) { 3816 this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false); 3817 3818 findParameterizedType((TypeReference)astNodeParent, scope); 3819 } else { 3820 ObjectVector typesFound = new ObjectVector(); 3821 if (this.assistNodeIsException && astNodeParent instanceof TryStatement) { 3822 findExceptionFromTryStatement( 3823 this.completionToken, 3824 null, 3825 scope.enclosingSourceType(), 3826 (BlockScope)scope, 3827 typesFound); 3828 } 3829 3830 checkCancel(); 3831 3832 findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound); 3833 } 3834 } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 3835 findMemberTypes( 3836 this.completionToken, 3837 (ReferenceBinding) qualifiedBinding, 3838 scope, 3839 scope.enclosingSourceType(), 3840 false, 3841 false, 3842 false, 3843 false, 3844 !this.assistNodeIsConstructor, 3845 null, 3846 new ObjectVector(), 3847 null, 3848 null, 3849 null, 3850 false); 3851 } 3852 } 3853 completionOnProvidesInterfacesSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3854 private void completionOnProvidesInterfacesSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3855 completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope); 3856 } completionOnProvidesImplementationsSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope)3857 private void completionOnProvidesImplementationsSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) { 3858 findImplementations((ProvidesStatement) this.parser.enclosingNode, (TypeReference) astNode); 3859 // TODO : filter the results - remove packs without a type in impl. 3860 } 3861 computeAlreadyDefinedName( BlockScope scope, InvocationSite invocationSite)3862 private char[][] computeAlreadyDefinedName( 3863 BlockScope scope, 3864 InvocationSite invocationSite) { 3865 ArrayList result = new ArrayList(); 3866 3867 boolean staticsOnly = false; 3868 3869 Scope currentScope = scope; 3870 3871 done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 3872 3873 switch (currentScope.kind) { 3874 3875 case Scope.METHOD_SCOPE : 3876 // handle the error case inside an explicit constructor call (see MethodScope>>findField) 3877 MethodScope methodScope = (MethodScope) currentScope; 3878 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 3879 3880 //$FALL-THROUGH$ 3881 case Scope.BLOCK_SCOPE : 3882 BlockScope blockScope = (BlockScope) currentScope; 3883 3884 next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { 3885 LocalVariableBinding local = blockScope.locals[i]; 3886 3887 if (local == null) 3888 break next; 3889 3890 if (local.isSecret()) 3891 continue next; 3892 3893 result.add(local.name); 3894 } 3895 break; 3896 3897 case Scope.CLASS_SCOPE : 3898 ClassScope classScope = (ClassScope) currentScope; 3899 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 3900 computeAlreadyDefinedName( 3901 enclosingType, 3902 classScope, 3903 staticsOnly, 3904 invocationSite, 3905 result); 3906 staticsOnly |= enclosingType.isStatic(); 3907 break; 3908 3909 case Scope.COMPILATION_UNIT_SCOPE : 3910 break done1; 3911 } 3912 currentScope = currentScope.parent; 3913 } 3914 3915 if (result.size() == 0) return CharOperation.NO_CHAR_CHAR; 3916 3917 return (char[][])result.toArray(new char[result.size()][]); 3918 } 3919 computeAlreadyDefinedName( FieldBinding[] fields, Scope scope, boolean onlyStaticFields, ReferenceBinding receiverType, InvocationSite invocationSite, ArrayList result)3920 private void computeAlreadyDefinedName( 3921 FieldBinding[] fields, 3922 Scope scope, 3923 boolean onlyStaticFields, 3924 ReferenceBinding receiverType, 3925 InvocationSite invocationSite, 3926 ArrayList result) { 3927 3928 next : for (int f = fields.length; --f >= 0;) { 3929 FieldBinding field = fields[f]; 3930 3931 if (field.isSynthetic()) continue next; 3932 3933 if (onlyStaticFields && !field.isStatic()) continue next; 3934 3935 if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 3936 3937 result.add(field.name); 3938 } 3939 } 3940 computeAlreadyDefinedName( SourceTypeBinding receiverType, ClassScope scope, boolean onlyStaticFields, InvocationSite invocationSite, ArrayList result)3941 private void computeAlreadyDefinedName( 3942 SourceTypeBinding receiverType, 3943 ClassScope scope, 3944 boolean onlyStaticFields, 3945 InvocationSite invocationSite, 3946 ArrayList result) { 3947 3948 ReferenceBinding currentType = receiverType; 3949 ReferenceBinding[] interfacesToVisit = null; 3950 int nextPosition = 0; 3951 do { 3952 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 3953 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 3954 if (interfacesToVisit == null) { 3955 interfacesToVisit = itsInterfaces; 3956 nextPosition = interfacesToVisit.length; 3957 } else { 3958 int itsLength = itsInterfaces.length; 3959 if (nextPosition + itsLength >= interfacesToVisit.length) 3960 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 3961 nextInterface : for (int a = 0; a < itsLength; a++) { 3962 ReferenceBinding next = itsInterfaces[a]; 3963 for (int b = 0; b < nextPosition; b++) 3964 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 3965 interfacesToVisit[nextPosition++] = next; 3966 } 3967 } 3968 } 3969 3970 FieldBinding[] fields = currentType.availableFields(); 3971 if(fields != null && fields.length > 0) { 3972 computeAlreadyDefinedName( 3973 fields, 3974 scope, 3975 onlyStaticFields, 3976 receiverType, 3977 invocationSite, 3978 result); 3979 } 3980 currentType = currentType.superclass(); 3981 } while ( currentType != null); 3982 3983 if (interfacesToVisit != null) { 3984 for (int i = 0; i < nextPosition; i++) { 3985 ReferenceBinding anInterface = interfacesToVisit[i]; 3986 FieldBinding[] fields = anInterface.availableFields(); 3987 if(fields != null) { 3988 computeAlreadyDefinedName( 3989 fields, 3990 scope, 3991 onlyStaticFields, 3992 receiverType, 3993 invocationSite, 3994 result); 3995 } 3996 3997 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 3998 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 3999 int itsLength = itsInterfaces.length; 4000 if (nextPosition + itsLength >= interfacesToVisit.length) 4001 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 4002 nextInterface : for (int a = 0; a < itsLength; a++) { 4003 ReferenceBinding next = itsInterfaces[a]; 4004 for (int b = 0; b < nextPosition; b++) 4005 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 4006 interfacesToVisit[nextPosition++] = next; 4007 } 4008 } 4009 } 4010 } 4011 } 4012 computeBaseRelevance()4013 int computeBaseRelevance(){ 4014 return R_DEFAULT; 4015 } 4016 computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope)4017 private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){ 4018 4019 // default filter 4020 this.expectedTypesFilter = SUBTYPE; 4021 this.hasJavaLangObjectAsExpectedType = false; 4022 4023 // find types from parent 4024 if(parent instanceof AbstractVariableDeclaration && !(parent instanceof TypeParameter)) { 4025 AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent; 4026 TypeBinding binding = variable.type.resolvedType; 4027 if(binding != null) { 4028 if(!(variable.initialization instanceof ArrayInitializer)) { 4029 addExpectedType(binding, scope); 4030 } else { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310747 4031 // If the variable is of type X[], and we're in the initializer 4032 // we should have X as the expected type for the variable initializers. 4033 binding = binding.leafComponentType(); 4034 addExpectedType(binding, scope); 4035 } 4036 } 4037 } else if(parent instanceof Assignment) { 4038 TypeBinding binding = ((Assignment)parent).lhs.resolvedType; 4039 if(binding != null) { 4040 addExpectedType(binding, scope); 4041 } 4042 } else if(parent instanceof ReturnStatement) { 4043 if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) { 4044 MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding; 4045 TypeBinding binding = methodBinding == null ? null : methodBinding.returnType; 4046 if(binding != null) { 4047 addExpectedType(binding, scope); 4048 } 4049 } else if (scope.methodScope().referenceContext instanceof LambdaExpression) { 4050 MethodBinding methodBinding = ((LambdaExpression) scope.methodScope().referenceContext).getMethodBinding(); 4051 TypeBinding binding = methodBinding == null ? null : methodBinding.returnType; 4052 if (binding != null) { 4053 addExpectedType(binding, scope); 4054 } 4055 } 4056 } else if(parent instanceof CastExpression) { 4057 TypeReference e = ((CastExpression)parent).type; 4058 TypeBinding binding = e.resolvedType; 4059 if(binding != null){ 4060 addExpectedType(binding, scope); 4061 this.expectedTypesFilter = SUBTYPE | SUPERTYPE; 4062 } 4063 } else if(parent instanceof MessageSend) { 4064 MessageSend messageSend = (MessageSend) parent; 4065 4066 if(messageSend.actualReceiverType instanceof ReferenceBinding) { 4067 ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType; 4068 boolean isStatic = messageSend.receiver.isTypeReference(); 4069 4070 while(binding != null) { 4071 computeExpectedTypesForMessageSend( 4072 binding, 4073 messageSend.selector, 4074 messageSend.arguments, 4075 (ReferenceBinding)messageSend.actualReceiverType, 4076 scope, 4077 messageSend, 4078 isStatic); 4079 computeExpectedTypesForMessageSendForInterface( 4080 binding, 4081 messageSend.selector, 4082 messageSend.arguments, 4083 (ReferenceBinding)messageSend.actualReceiverType, 4084 scope, 4085 messageSend, 4086 isStatic); 4087 binding = binding.superclass(); 4088 } 4089 } 4090 } else if(parent instanceof AllocationExpression) { 4091 AllocationExpression allocationExpression = (AllocationExpression) parent; 4092 4093 ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType; 4094 4095 if(binding != null) { 4096 computeExpectedTypesForAllocationExpression( 4097 binding, 4098 allocationExpression.arguments, 4099 scope, 4100 allocationExpression); 4101 } 4102 } else if(parent instanceof OperatorExpression) { 4103 int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT; 4104 if(parent instanceof ConditionalExpression) { 4105 // for future use 4106 } else if(parent instanceof InstanceOfExpression) { 4107 InstanceOfExpression e = (InstanceOfExpression) parent; 4108 TypeBinding binding = e.expression.resolvedType; 4109 if (binding == null) { 4110 if (scope instanceof BlockScope) 4111 binding = e.expression.resolveType((BlockScope) scope); 4112 else if (scope instanceof ClassScope) 4113 binding = e.expression.resolveType((ClassScope) scope); 4114 } 4115 if(binding != null){ 4116 addExpectedType(binding, scope); 4117 this.expectedTypesFilter = SUBTYPE | SUPERTYPE; 4118 } 4119 } else if(parent instanceof BinaryExpression) { 4120 BinaryExpression binaryExpression = (BinaryExpression) parent; 4121 switch(operator) { 4122 case OperatorIds.EQUAL_EQUAL : 4123 case OperatorIds.NOT_EQUAL : 4124 // expected type is not relevant in this case 4125 TypeBinding binding = binaryExpression.left.resolvedType; 4126 if (binding != null) { 4127 addExpectedType(binding, scope); 4128 this.expectedTypesFilter = SUBTYPE | SUPERTYPE; 4129 } 4130 break; 4131 case OperatorIds.PLUS : 4132 addExpectedType(TypeBinding.SHORT, scope); 4133 addExpectedType(TypeBinding.INT, scope); 4134 addExpectedType(TypeBinding.LONG, scope); 4135 addExpectedType(TypeBinding.FLOAT, scope); 4136 addExpectedType(TypeBinding.DOUBLE, scope); 4137 addExpectedType(TypeBinding.CHAR, scope); 4138 addExpectedType(TypeBinding.BYTE, scope); 4139 addExpectedType(scope.getJavaLangString(), scope); 4140 break; 4141 case OperatorIds.AND_AND : 4142 case OperatorIds.OR_OR : 4143 case OperatorIds.XOR : 4144 addExpectedType(TypeBinding.BOOLEAN, scope); 4145 break; 4146 default : 4147 addExpectedType(TypeBinding.SHORT, scope); 4148 addExpectedType(TypeBinding.INT, scope); 4149 addExpectedType(TypeBinding.LONG, scope); 4150 addExpectedType(TypeBinding.FLOAT, scope); 4151 addExpectedType(TypeBinding.DOUBLE, scope); 4152 addExpectedType(TypeBinding.CHAR, scope); 4153 addExpectedType(TypeBinding.BYTE, scope); 4154 break; 4155 } 4156 if(operator == OperatorIds.LESS) { 4157 if(binaryExpression.left instanceof SingleNameReference){ 4158 SingleNameReference name = (SingleNameReference) binaryExpression.left; 4159 Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false); 4160 if(b instanceof ReferenceBinding) { 4161 TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables(); 4162 if(typeVariableBindings != null && typeVariableBindings.length > 0) { 4163 addExpectedType(typeVariableBindings[0].firstBound, scope); 4164 } 4165 4166 } 4167 } 4168 } 4169 } else if(parent instanceof UnaryExpression) { 4170 switch(operator) { 4171 case OperatorIds.NOT : 4172 addExpectedType(TypeBinding.BOOLEAN, scope); 4173 break; 4174 case OperatorIds.TWIDDLE : 4175 addExpectedType(TypeBinding.SHORT, scope); 4176 addExpectedType(TypeBinding.INT, scope); 4177 addExpectedType(TypeBinding.LONG, scope); 4178 addExpectedType(TypeBinding.CHAR, scope); 4179 addExpectedType(TypeBinding.BYTE, scope); 4180 break; 4181 case OperatorIds.PLUS : 4182 case OperatorIds.MINUS : 4183 case OperatorIds.PLUS_PLUS : 4184 case OperatorIds.MINUS_MINUS : 4185 addExpectedType(TypeBinding.SHORT, scope); 4186 addExpectedType(TypeBinding.INT, scope); 4187 addExpectedType(TypeBinding.LONG, scope); 4188 addExpectedType(TypeBinding.FLOAT, scope); 4189 addExpectedType(TypeBinding.DOUBLE, scope); 4190 addExpectedType(TypeBinding.CHAR, scope); 4191 addExpectedType(TypeBinding.BYTE, scope); 4192 break; 4193 } 4194 } 4195 } else if(parent instanceof ArrayReference) { 4196 addExpectedType(TypeBinding.SHORT, scope); 4197 addExpectedType(TypeBinding.INT, scope); 4198 addExpectedType(TypeBinding.LONG, scope); 4199 } else if(parent instanceof ParameterizedSingleTypeReference) { 4200 ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent; 4201 TypeBinding expected = null; 4202 if (this.parser.enclosingNode instanceof AbstractVariableDeclaration || 4203 this.parser.enclosingNode instanceof ReturnStatement) { 4204 // completing inside the diamond 4205 if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) { 4206 AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode; 4207 expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null; 4208 } else { 4209 ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode; 4210 if (returnStatement.expression != null) { 4211 expected = returnStatement.expression.expectedType(); 4212 } 4213 } 4214 addExpectedType(expected, scope); 4215 } else { 4216 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 4217 int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; 4218 if(typeVariables != null && typeVariables.length >= length) { 4219 int index = length - 1; 4220 while(index > -1 && ref.typeArguments[index] != node) index--; 4221 4222 TypeBinding bound = typeVariables[index].firstBound; 4223 addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope); 4224 } 4225 } 4226 } else if(parent instanceof ParameterizedQualifiedTypeReference) { 4227 ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent; 4228 TypeReference[][] arguments = ref.typeArguments; 4229 TypeBinding expected = null; 4230 if (this.parser.enclosingNode instanceof AbstractVariableDeclaration || 4231 this.parser.enclosingNode instanceof ReturnStatement) { 4232 // completing inside the diamond 4233 if (this.parser.enclosingNode instanceof AbstractVariableDeclaration) { 4234 AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) this.parser.enclosingNode; 4235 expected = abstractVariableDeclaration.initialization != null ? abstractVariableDeclaration.initialization.expectedType() : null; 4236 } else { 4237 ReturnStatement returnStatement = (ReturnStatement) this.parser.enclosingNode; 4238 if (returnStatement.expression != null) { 4239 expected = returnStatement.expression.expectedType(); 4240 } 4241 } 4242 addExpectedType(expected, scope); 4243 } else { 4244 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 4245 if(typeVariables != null) { 4246 int iLength = arguments == null ? 0 : arguments.length; 4247 done: for (int i = 0; i < iLength; i++) { 4248 int jLength = arguments[i] == null ? 0 : arguments[i].length; 4249 for (int j = 0; j < jLength; j++) { 4250 if(arguments[i][j] == node && typeVariables.length > j) { 4251 TypeBinding bound = typeVariables[j].firstBound; 4252 addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope); 4253 break done; 4254 } 4255 } 4256 } 4257 } 4258 } 4259 } else if(parent instanceof MemberValuePair) { 4260 MemberValuePair memberValuePair = (MemberValuePair) parent; 4261 if(memberValuePair.binding != null) { 4262 addExpectedType(memberValuePair.binding.returnType.leafComponentType(), scope); 4263 } 4264 } else if (parent instanceof NormalAnnotation) { 4265 NormalAnnotation annotation = (NormalAnnotation) parent; 4266 MemberValuePair[] memberValuePairs = annotation.memberValuePairs(); 4267 if(memberValuePairs == null || memberValuePairs.length == 0) { 4268 if(annotation.resolvedType instanceof ReferenceBinding) { 4269 MethodBinding[] methodBindings = 4270 ((ReferenceBinding)annotation.resolvedType).availableMethods(); 4271 if (methodBindings != null && 4272 methodBindings.length > 0 && 4273 CharOperation.equals(methodBindings[0].selector, VALUE)) { 4274 boolean canBeSingleMemberAnnotation = true; 4275 done : for (int i = 1; i < methodBindings.length; i++) { 4276 if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) { 4277 canBeSingleMemberAnnotation = false; 4278 break done; 4279 } 4280 } 4281 if (canBeSingleMemberAnnotation) { 4282 this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation; 4283 addExpectedType(methodBindings[0].returnType.leafComponentType(), scope); 4284 } 4285 } 4286 } 4287 } 4288 } else if (parent instanceof AssistNodeParentAnnotationArrayInitializer) { 4289 AssistNodeParentAnnotationArrayInitializer parent1 = (AssistNodeParentAnnotationArrayInitializer) parent; 4290 if(parent1.type.resolvedType instanceof ReferenceBinding) { 4291 MethodBinding[] methodBindings = 4292 ((ReferenceBinding)parent1.type.resolvedType).availableMethods(); 4293 if (methodBindings != null) { 4294 for (MethodBinding methodBinding : methodBindings) { 4295 if(CharOperation.equals(methodBinding.selector, parent1.name)) { 4296 addExpectedType(methodBinding.returnType.leafComponentType(), scope); 4297 break; 4298 } 4299 } 4300 } 4301 } 4302 } else if (parent instanceof TryStatement) { 4303 boolean isException = false; 4304 if (node instanceof CompletionOnSingleTypeReference) { 4305 isException = ((CompletionOnSingleTypeReference)node).isException(); 4306 } else if (node instanceof CompletionOnQualifiedTypeReference) { 4307 isException = ((CompletionOnQualifiedTypeReference)node).isException(); 4308 } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) { 4309 isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException(); 4310 } 4311 if (isException) { 4312 ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder(); 4313 thrownExceptionFinder.processThrownExceptions((TryStatement) parent, (BlockScope)scope); 4314 ReferenceBinding[] bindings = thrownExceptionFinder.getThrownUncaughtExceptions(); 4315 ReferenceBinding[] alreadyCaughtExceptions = thrownExceptionFinder.getAlreadyCaughtExceptions(); 4316 ReferenceBinding[] discouragedExceptions = thrownExceptionFinder.getDiscouragedExceptions(); 4317 if (bindings != null && bindings.length > 0) { 4318 for (int i = 0; i < bindings.length; i++) { 4319 addExpectedType(bindings[i], scope); 4320 } 4321 this.expectedTypesFilter = SUPERTYPE; 4322 } 4323 if (alreadyCaughtExceptions != null && alreadyCaughtExceptions.length > 0) { 4324 for (int i = 0; i < alreadyCaughtExceptions.length; i++) { 4325 addForbiddenBindings(alreadyCaughtExceptions[i]); 4326 this.knownTypes.put(CharOperation.concat(alreadyCaughtExceptions[i].qualifiedPackageName(), alreadyCaughtExceptions[i].qualifiedSourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS); 4327 } 4328 } 4329 if (discouragedExceptions != null && discouragedExceptions.length > 0) { 4330 for (int i = 0; i < discouragedExceptions.length; i++) { 4331 addUninterestingBindings(discouragedExceptions[i]); 4332 // do not insert into known types. We do need these types to come from 4333 // searchAllTypes(..) albeit with lower relevance 4334 } 4335 } 4336 } 4337 } else if (parent instanceof SwitchStatement) { 4338 SwitchStatement switchStatement = (SwitchStatement) parent; 4339 this.assistNodeIsInsideCase = assistNodeIsInsideCase(node, parent); 4340 if (switchStatement.expression != null && 4341 switchStatement.expression.resolvedType != null) { 4342 if (this.assistNodeIsInsideCase && 4343 switchStatement.expression.resolvedType.id == TypeIds.T_JavaLangString && 4344 this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_7) { 4345 // set the field to true even though the expected types array will contain String as 4346 // expected type to avoid traversing the array in every case later on. 4347 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343476 4348 this.assistNodeIsString = true; 4349 } 4350 addExpectedType(switchStatement.expression.resolvedType, scope); 4351 } 4352 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=253008, flag boolean as the expected 4353 // type if we are completing inside if(), for (; ;), while() and do while() 4354 } else if (parent instanceof WhileStatement) { // covers both while and do-while loops 4355 addExpectedType(TypeBinding.BOOLEAN, scope); 4356 } else if (parent instanceof IfStatement) { 4357 addExpectedType(TypeBinding.BOOLEAN, scope); 4358 } else if (parent instanceof AssertStatement) { 4359 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=274466 4360 // If the assertExpression is same as the node , then the assistNode is the conditional part of the assert statement 4361 AssertStatement assertStatement = (AssertStatement) parent; 4362 if (assertStatement.assertExpression == node) { 4363 addExpectedType(TypeBinding.BOOLEAN, scope); 4364 } 4365 } else if (parent instanceof ForStatement) { // astNodeParent set to ForStatement only for the condition 4366 addExpectedType(TypeBinding.BOOLEAN, scope); 4367 4368 // Expected types for javadoc 4369 } else if (parent instanceof Javadoc) { 4370 if (scope.kind == Scope.METHOD_SCOPE) { 4371 MethodScope methodScope = (MethodScope) scope; 4372 AbstractMethodDeclaration methodDecl = methodScope.referenceMethod(); 4373 if (methodDecl != null && methodDecl.binding != null) { 4374 ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions; 4375 if (exceptions != null) { 4376 for (int i = 0; i < exceptions.length; i++) { 4377 addExpectedType(exceptions[i], scope); 4378 } 4379 } 4380 } 4381 } 4382 } 4383 4384 if(this.expectedTypesPtr + 1 != this.expectedTypes.length) { 4385 System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1); 4386 } 4387 } 4388 computeExpectedTypesForAllocationExpression( ReferenceBinding binding, Expression[] arguments, Scope scope, InvocationSite invocationSite)4389 private void computeExpectedTypesForAllocationExpression( 4390 ReferenceBinding binding, 4391 Expression[] arguments, 4392 Scope scope, 4393 InvocationSite invocationSite) { 4394 4395 MethodBinding[] methods = binding.availableMethods(); 4396 nextMethod : for (int i = 0; i < methods.length; i++) { 4397 MethodBinding method = methods[i]; 4398 4399 if (!method.isConstructor()) continue nextMethod; 4400 4401 if (method.isSynthetic()) continue nextMethod; 4402 4403 if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod; 4404 4405 TypeBinding[] parameters = method.parameters; 4406 if(parameters.length < arguments.length) 4407 continue nextMethod; 4408 4409 int length = arguments.length - 1; 4410 4411 for (int j = 0; j < length; j++) { 4412 Expression argument = arguments[j]; 4413 TypeBinding argType = argument.resolvedType; 4414 if(argType != null && !argType.isCompatibleWith(parameters[j])) 4415 continue nextMethod; 4416 } 4417 4418 TypeBinding expectedType = method.parameters[arguments.length - 1]; 4419 if(expectedType != null) { 4420 addExpectedType(expectedType, scope); 4421 } 4422 } 4423 } computeExpectedTypesForMessageSend( ReferenceBinding binding, char[] selector, Expression[] arguments, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, boolean isStatic)4424 private void computeExpectedTypesForMessageSend( 4425 ReferenceBinding binding, 4426 char[] selector, 4427 Expression[] arguments, 4428 ReferenceBinding receiverType, 4429 Scope scope, 4430 InvocationSite invocationSite, 4431 boolean isStatic) { 4432 4433 MethodBinding[] methods = binding.availableMethods(); 4434 nextMethod : for (int i = 0; i < methods.length; i++) { 4435 MethodBinding method = methods[i]; 4436 4437 if (method.isSynthetic()) continue nextMethod; 4438 4439 if (method.isDefaultAbstract()) continue nextMethod; 4440 4441 if (method.isConstructor()) continue nextMethod; 4442 4443 if (isStatic && !method.isStatic()) continue nextMethod; 4444 4445 if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod; 4446 4447 if(!CharOperation.equals(method.selector, selector)) continue nextMethod; 4448 4449 TypeBinding[] parameters = method.parameters; 4450 if(parameters.length < arguments.length) 4451 continue nextMethod; 4452 4453 int length = arguments.length - 1; 4454 4455 for (int j = 0; j < length; j++) { 4456 Expression argument = arguments[j]; 4457 TypeBinding argType = argument.resolvedType; 4458 if(argType != null && !argType.erasure().isCompatibleWith(parameters[j].erasure())) 4459 continue nextMethod; 4460 } 4461 4462 TypeBinding expectedType = method.parameters[arguments.length - 1]; 4463 if(expectedType != null) { 4464 addExpectedType(expectedType, scope); 4465 } 4466 } 4467 } computeExpectedTypesForMessageSendForInterface( ReferenceBinding binding, char[] selector, Expression[] arguments, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, boolean isStatic)4468 private void computeExpectedTypesForMessageSendForInterface( 4469 ReferenceBinding binding, 4470 char[] selector, 4471 Expression[] arguments, 4472 ReferenceBinding receiverType, 4473 Scope scope, 4474 InvocationSite invocationSite, 4475 boolean isStatic) { 4476 4477 ReferenceBinding[] itsInterfaces = binding.superInterfaces(); 4478 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 4479 ReferenceBinding[] interfacesToVisit = itsInterfaces; 4480 int nextPosition = interfacesToVisit.length; 4481 4482 for (int i = 0; i < nextPosition; i++) { 4483 ReferenceBinding currentType = interfacesToVisit[i]; 4484 computeExpectedTypesForMessageSend( 4485 currentType, 4486 selector, 4487 arguments, 4488 receiverType, 4489 scope, 4490 invocationSite, 4491 isStatic); 4492 4493 if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) { 4494 int itsLength = itsInterfaces.length; 4495 if (nextPosition + itsLength >= interfacesToVisit.length) 4496 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 4497 nextInterface : for (int a = 0; a < itsLength; a++) { 4498 ReferenceBinding next = itsInterfaces[a]; 4499 for (int b = 0; b < nextPosition; b++) 4500 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 4501 interfacesToVisit[nextPosition++] = next; 4502 } 4503 } 4504 } 4505 } 4506 } 4507 computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope)4508 private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) { 4509 if(scope instanceof ClassScope) { 4510 TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext; 4511 if(typeDeclaration.superclass == astNode) { 4512 addForbiddenBindings(typeDeclaration.binding); 4513 addForbiddenBindingsForMemberTypes(typeDeclaration); 4514 return scope.parent; 4515 } 4516 TypeReference[] superInterfaces = typeDeclaration.superInterfaces; 4517 int length = superInterfaces == null ? 0 : superInterfaces.length; 4518 int astNodeIndex = -1; 4519 for (int i = 0; i < length; i++) { 4520 if(superInterfaces[i] == astNode) { 4521 addForbiddenBindings(typeDeclaration.binding); 4522 addForbiddenBindingsForMemberTypes(typeDeclaration); 4523 astNodeIndex = i; 4524 break; 4525 } 4526 } 4527 if (astNodeIndex >= 0) { 4528 // Need to loop only up to astNodeIndex as the rest will be undefined. 4529 for (int i = 0; i < astNodeIndex; i++) { 4530 addForbiddenBindings(superInterfaces[i].resolvedType); 4531 } 4532 return scope.parent; 4533 } 4534 } 4535 // else if(scope instanceof MethodScope) { 4536 // MethodScope methodScope = (MethodScope) scope; 4537 // if(methodScope.insideTypeAnnotation) { 4538 // return methodScope.parent.parent; 4539 // } 4540 // } 4541 return scope; 4542 } 4543 4544 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=270437 addForbiddenBindingsForMemberTypes(TypeDeclaration typeDeclaration)4545 private void addForbiddenBindingsForMemberTypes(TypeDeclaration typeDeclaration) { 4546 TypeDeclaration[] memberTypes = typeDeclaration.memberTypes; 4547 int memberTypesLen = memberTypes == null ? 0 : memberTypes.length; 4548 for (int i = 0; i < memberTypesLen; i++) { 4549 addForbiddenBindings(memberTypes[i].binding); 4550 addForbiddenBindingsForMemberTypes(memberTypes[i]); 4551 } 4552 } 4553 computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic)4554 private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){ 4555 4556 StringBuffer completion = new StringBuffer(10); 4557 4558 if (isStatic) { 4559 completion.append(declarationType.sourceName()); 4560 4561 } else if (TypeBinding.equalsEquals(declarationType, invocationType)) { 4562 completion.append(THIS); 4563 4564 } else { 4565 4566 if (!declarationType.isNestedType()) { 4567 4568 completion.append(declarationType.sourceName()); 4569 completion.append('.'); 4570 completion.append(THIS); 4571 4572 } else if (!declarationType.isAnonymousType()) { 4573 4574 completion.append(declarationType.sourceName()); 4575 completion.append('.'); 4576 completion.append(THIS); 4577 4578 } 4579 } 4580 4581 return completion.toString().toCharArray(); 4582 } 4583 computeRelevanceForAnnotation()4584 private int computeRelevanceForAnnotation(){ 4585 if(this.assistNodeIsAnnotation) { 4586 return R_ANNOTATION; 4587 } 4588 return 0; 4589 } 4590 computeRelevanceForAnnotationTarget(TypeBinding typeBinding)4591 private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){ 4592 if (this.assistNodeIsAnnotation && 4593 (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) { 4594 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 4595 if(target == 0 || (target & this.targetedElement) != 0) { 4596 return R_TARGET; 4597 } 4598 } 4599 return 0; 4600 } computeRelevanceForCaseMatching(char[] token, char[] proposalName)4601 int computeRelevanceForCaseMatching(char[] token, char[] proposalName){ 4602 if(CharOperation.equals(token, proposalName, true)) { 4603 return R_EXACT_NAME + R_CASE; 4604 } else if(CharOperation.equals(token, proposalName, false)) { 4605 return R_EXACT_NAME; 4606 } else if (CharOperation.prefixEquals(token, proposalName, false)) { 4607 if (CharOperation.prefixEquals(token, proposalName, true)) 4608 return R_CASE; 4609 } else if (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, proposalName)){ 4610 return R_CAMEL_CASE; 4611 } else if (this.options.substringMatch && CharOperation.substringMatch(token, proposalName)) { 4612 return R_SUBSTRING; 4613 } else if (this.options.subwordMatch && CharOperation.subWordMatch(token, proposalName)) { 4614 return R_SUBWORD; 4615 } 4616 return 0; 4617 } 4618 computeRelevanceForClass()4619 private int computeRelevanceForClass(){ 4620 if(this.assistNodeIsClass) { 4621 return R_CLASS; 4622 } 4623 return 0; 4624 } 4625 computeRelevanceForConstructor()4626 private int computeRelevanceForConstructor() { 4627 if (this.assistNodeIsConstructor) { 4628 return R_CONSTRUCTOR; 4629 } 4630 return 0; 4631 } 4632 computeRelevanceForEnum()4633 private int computeRelevanceForEnum(){ 4634 if(this.assistNodeIsEnum) { 4635 return R_ENUM; 4636 } 4637 return 0; 4638 } 4639 computeRelevanceForEnumConstant(TypeBinding proposalType)4640 private int computeRelevanceForEnumConstant(TypeBinding proposalType){ 4641 if(this.assistNodeIsEnum && 4642 proposalType != null && 4643 this.expectedTypes != null) { 4644 for (int i = 0; i <= this.expectedTypesPtr; i++) { 4645 if (proposalType.isEnum() && 4646 TypeBinding.equalsEquals(proposalType, this.expectedTypes[i])) { 4647 return R_ENUM + R_ENUM_CONSTANT; 4648 } 4649 4650 } 4651 } 4652 return 0; 4653 } 4654 computeRelevanceForException()4655 private int computeRelevanceForException(){ 4656 if (this.assistNodeIsException) { 4657 return R_EXCEPTION; 4658 } 4659 return 0; 4660 } 4661 computeRelevanceForException(char[] proposalName)4662 private int computeRelevanceForException(char[] proposalName){ 4663 4664 if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&& 4665 (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) || 4666 CharOperation.match(ERROR_PATTERN, proposalName, false))) { 4667 return R_EXCEPTION; 4668 } 4669 return 0; 4670 } 4671 computeRelevanceForExpectingType(char[] packageName, char[] typeName)4672 private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){ 4673 if(this.expectedTypes != null) { 4674 for (int i = 0; i <= this.expectedTypesPtr; i++) { 4675 if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) && 4676 CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) { 4677 return R_EXACT_EXPECTED_TYPE; 4678 } 4679 } 4680 if(this.hasJavaLangObjectAsExpectedType) { 4681 return R_EXPECTED_TYPE; 4682 } 4683 } 4684 return 0; 4685 } 4686 computeRelevanceForExpectingType(TypeBinding proposalType)4687 private int computeRelevanceForExpectingType(TypeBinding proposalType){ 4688 if(this.expectedTypes != null && proposalType != null) { 4689 int relevance = 0; 4690 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=271296 4691 // If there is at least one expected type, then void proposal types attract a degraded relevance. 4692 if (proposalType == TypeBinding.VOID && this.expectedTypesPtr >=0) { 4693 return R_VOID; 4694 } 4695 for (int i = 0; i <= this.expectedTypesPtr; i++) { 4696 if((this.expectedTypesFilter & SUBTYPE) != 0 4697 && (proposalType.erasure().isCompatibleWith(this.expectedTypes[i].erasure()))) { 4698 4699 if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) && 4700 CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) { 4701 return R_EXACT_EXPECTED_TYPE; 4702 } 4703 4704 relevance = R_EXPECTED_TYPE; 4705 } 4706 if((this.expectedTypesFilter & SUPERTYPE) != 0 4707 && this.expectedTypes[i].isCompatibleWith(proposalType)) { 4708 4709 if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) && 4710 CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) { 4711 return R_EXACT_EXPECTED_TYPE; 4712 } 4713 4714 relevance = R_EXPECTED_TYPE; 4715 } 4716 // Bug 84720 - [1.5][assist] proposal ranking by return value should consider auto(un)boxing 4717 // Just ensuring that the unitScope is not null, even though it's an unlikely case. 4718 if (this.unitScope != null && this.unitScope.isBoxingCompatibleWith(proposalType, this.expectedTypes[i])) { 4719 relevance = R_EXPECTED_TYPE; 4720 } 4721 } 4722 return relevance; 4723 } 4724 return 0; 4725 } 4726 computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass)4727 private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) { 4728 if (TypeBinding.equalsEquals(receiverType, declaringClass)) return R_NON_INHERITED; 4729 return 0; 4730 } 4731 computeRelevanceForInterestingProposal()4732 int computeRelevanceForInterestingProposal(){ 4733 return computeRelevanceForInterestingProposal(null); 4734 } 4735 computeRelevanceForInterestingProposal(Binding binding)4736 private int computeRelevanceForInterestingProposal(Binding binding){ 4737 if(this.uninterestingBindings != null) { 4738 for (int i = 0; i <= this.uninterestingBindingsPtr; i++) { 4739 if(this.uninterestingBindings[i] == binding) { 4740 return 0; 4741 } 4742 if((this.uninterestingBindingsFilter & SUBTYPE) != 0) { 4743 if (binding instanceof TypeBinding && 4744 this.uninterestingBindings[i] instanceof TypeBinding && 4745 ((TypeBinding)binding).isCompatibleWith((TypeBinding)this.uninterestingBindings[i])) { 4746 return 0; 4747 } 4748 } 4749 if ((this.uninterestingBindingsFilter & SUPERTYPE) != 0) { 4750 if (binding instanceof TypeBinding && 4751 this.uninterestingBindings[i] instanceof TypeBinding && 4752 ((TypeBinding)this.uninterestingBindings[i]).isCompatibleWith((TypeBinding)binding)) { 4753 return 0; 4754 } 4755 } 4756 } 4757 } 4758 return R_INTERESTING; 4759 } 4760 computeRelevanceForInterestingProposal(char[] givenPkgName, char[] fullTypeName)4761 private int computeRelevanceForInterestingProposal(char[] givenPkgName, char[] fullTypeName) { 4762 for (int i = 0; i <= this.uninterestingBindingsPtr; i++) { 4763 if (this.uninterestingBindings[i] instanceof TypeBinding) { 4764 TypeBinding typeBinding = (TypeBinding) this.uninterestingBindings[i]; 4765 char[] currPkgName = typeBinding.qualifiedPackageName(); 4766 if (CharOperation.equals(givenPkgName, currPkgName)) { 4767 char[] currTypeName = typeBinding.qualifiedSourceName(); 4768 if (CharOperation.equals(fullTypeName, currTypeName)) { 4769 return 0; 4770 } 4771 } 4772 } 4773 } 4774 return R_INTERESTING; 4775 } 4776 computeRelevanceForInterface()4777 private int computeRelevanceForInterface(){ 4778 if(this.assistNodeIsInterface) { 4779 return R_INTERFACE; 4780 } 4781 return 0; 4782 } 4783 computeRelevanceForMissingElements(boolean hasProblems)4784 private int computeRelevanceForMissingElements(boolean hasProblems) { 4785 if (!hasProblems) { 4786 return R_NO_PROBLEMS; 4787 } 4788 return 0; 4789 } computeRelevanceForQualification(boolean prefixRequired)4790 int computeRelevanceForQualification(boolean prefixRequired) { 4791 if(!prefixRequired && !this.insideQualifiedReference) { 4792 return R_UNQUALIFIED; 4793 } 4794 4795 if(prefixRequired && this.insideQualifiedReference) { 4796 return R_QUALIFIED; 4797 } 4798 return 0; 4799 } 4800 computeRelevanceForResolution()4801 int computeRelevanceForResolution(){ 4802 return computeRelevanceForResolution(true); 4803 } 4804 computeRelevanceForResolution(boolean isResolved)4805 int computeRelevanceForResolution(boolean isResolved){ 4806 if (isResolved) { 4807 return R_RESOLVED; 4808 } 4809 return 0; 4810 } 4811 computeRelevanceForRestrictions(int accessRuleKind)4812 int computeRelevanceForRestrictions(int accessRuleKind) { 4813 if(accessRuleKind == IAccessRule.K_ACCESSIBLE) { 4814 return R_NON_RESTRICTED; 4815 } 4816 return 0; 4817 } 4818 computeRelevanceForStatic(boolean onlyStatic, boolean isStatic)4819 private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) { 4820 if(this.insideQualifiedReference && !onlyStatic && !isStatic) { 4821 return R_NON_STATIC; 4822 } 4823 return 0; 4824 } 4825 computeRelevanceForFinal(boolean onlyFinal, boolean isFinal)4826 private int computeRelevanceForFinal(boolean onlyFinal, boolean isFinal) { 4827 if (onlyFinal && isFinal) { 4828 return R_FINAL; 4829 } 4830 return 0; 4831 } 4832 computeRelevanceForSuper(MethodBinding method, Scope scope, InvocationSite site)4833 private int computeRelevanceForSuper(MethodBinding method, Scope scope, InvocationSite site) { 4834 if (site instanceof CompletionOnMemberAccess) { 4835 CompletionOnMemberAccess access = (CompletionOnMemberAccess) site; 4836 if (access.isSuperAccess() && this.parser.assistNodeParent == null) { 4837 ReferenceContext referenceContext = scope.referenceContext(); 4838 if (referenceContext instanceof AbstractMethodDeclaration) { // LE is anonymous. 4839 MethodBinding binding = ((AbstractMethodDeclaration) referenceContext).binding; 4840 if (binding != null) { 4841 if (CharOperation.equals(binding.selector, method.selector)) { 4842 if (binding.areParameterErasuresEqual(method)) { 4843 return R_EXACT_NAME + R_METHOD_OVERIDE; 4844 } 4845 return R_EXACT_NAME; 4846 } 4847 } 4848 } 4849 } 4850 } 4851 return 0; 4852 } 4853 computeTargetedElement(CompletionOnAnnotationOfType fakeNode)4854 private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) { 4855 ASTNode annotatedElement = fakeNode.potentialAnnotatedNode; 4856 4857 if (annotatedElement instanceof TypeDeclaration) { 4858 TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement; 4859 if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) { 4860 return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType | TagBits.AnnotationForTypeUse; 4861 } 4862 return TagBits.AnnotationForType | TagBits.AnnotationForTypeUse; 4863 } else if (annotatedElement instanceof FieldDeclaration) { 4864 if (fakeNode.isParameter) { 4865 return TagBits.AnnotationForParameter; 4866 } 4867 return TagBits.AnnotationForField; 4868 } else if (annotatedElement instanceof MethodDeclaration) { 4869 return TagBits.AnnotationForMethod; 4870 } else if (annotatedElement instanceof Argument) { 4871 return TagBits.AnnotationForParameter; 4872 } else if (annotatedElement instanceof ConstructorDeclaration) { 4873 return TagBits.AnnotationForConstructor; 4874 } else if (annotatedElement instanceof LocalDeclaration) { 4875 return TagBits.AnnotationForLocalVariable; 4876 } else if (annotatedElement instanceof ImportReference) { 4877 return TagBits.AnnotationForPackage; 4878 } 4879 return 0; 4880 } computeTypes(Expression[] arguments)4881 private TypeBinding[] computeTypes(Expression[] arguments) { 4882 if (arguments == null) return null; 4883 int argsLength = arguments.length; 4884 TypeBinding[] argTypes = new TypeBinding[argsLength]; 4885 for (int a = argsLength; --a >= 0;) { 4886 argTypes[a] = arguments[a].resolvedType; 4887 } 4888 return argTypes; 4889 } 4890 computeTypesIfCorrect(Expression[] arguments)4891 private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) { 4892 if (arguments == null) return null; 4893 int argsLength = arguments.length; 4894 TypeBinding[] argTypes = new TypeBinding[argsLength]; 4895 for (int a = argsLength; --a >= 0;) { 4896 TypeBinding typeBinding = arguments[a].resolvedType; 4897 if(typeBinding == null || !typeBinding.isValidBinding()) return null; 4898 argTypes[a] = typeBinding; 4899 } 4900 return argTypes; 4901 } 4902 computeUninterestingBindings(ASTNode astNode, ASTNode parent, Scope scope)4903 private void computeUninterestingBindings(ASTNode astNode, ASTNode parent, Scope scope){ 4904 this.uninterestingBindingsFilter = NONE; 4905 if(parent instanceof LocalDeclaration) { 4906 addUninterestingBindings(((LocalDeclaration)parent).binding); 4907 } else if (parent instanceof FieldDeclaration) { 4908 addUninterestingBindings(((FieldDeclaration)parent).binding); 4909 } else if (parent instanceof TryStatement) { 4910 boolean isException = false; 4911 if (astNode instanceof CompletionOnSingleTypeReference) { 4912 isException = ((CompletionOnSingleTypeReference)astNode).isException(); 4913 } else if (astNode instanceof CompletionOnQualifiedTypeReference) { 4914 isException = ((CompletionOnQualifiedTypeReference)astNode).isException(); 4915 } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) { 4916 isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException(); 4917 } 4918 if (isException) { 4919 this.uninterestingBindingsFilter |= SUBTYPE; 4920 // super-types also need to be discouraged if we're in a union type (bug 350652) 4921 Argument[] args = ((TryStatement)parent).catchArguments; 4922 for (int i = 0; i < args.length; i++) { 4923 if (args[i].type instanceof UnionTypeReference) { 4924 CompletionNodeDetector detector = new CompletionNodeDetector(astNode, args[i]); 4925 if (detector.containsCompletionNode()) { 4926 this.uninterestingBindingsFilter |= SUPERTYPE; 4927 break; 4928 } 4929 } 4930 } 4931 4932 } 4933 } 4934 } 4935 createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand)4936 private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) { 4937 char[] result = IMPORT; 4938 if (isStatic) { 4939 result = CharOperation.concat(result, STATIC, ' '); 4940 } 4941 result = CharOperation.concat(result, importedElement, ' '); 4942 if (onDemand) { 4943 result = CharOperation.concat(result, ON_DEMAND); 4944 } 4945 return CharOperation.concat(result, IMPORT_END); 4946 } 4947 createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion)4948 private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) { 4949 //// Modifiers 4950 // flush uninteresting modifiers 4951 int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract); 4952 if(insertedModifiers != ClassFileConstants.AccDefault){ 4953 ASTNode.printModifiers(insertedModifiers, completion); 4954 } 4955 4956 //// Type parameters 4957 4958 TypeVariableBinding[] typeVariableBindings = method.typeVariables; 4959 if(typeVariableBindings != null && typeVariableBindings.length != 0) { 4960 completion.append('<'); 4961 for (int i = 0; i < typeVariableBindings.length; i++) { 4962 if(i != 0) { 4963 completion.append(','); 4964 completion.append(' '); 4965 } 4966 createTypeVariable(typeVariableBindings[i], scope, completion); 4967 } 4968 completion.append('>'); 4969 completion.append(' '); 4970 } 4971 4972 //// Return type 4973 createType(method.returnType, scope, completion); 4974 completion.append(' '); 4975 4976 //// Selector 4977 completion.append(method.selector); 4978 4979 completion.append('('); 4980 4981 ////Parameters 4982 TypeBinding[] parameterTypes = method.parameters; 4983 int length = parameterTypes.length; 4984 for (int i = 0; i < length; i++) { 4985 if(i != 0) { 4986 completion.append(','); 4987 completion.append(' '); 4988 } 4989 createType(parameterTypes[i], scope, completion); 4990 completion.append(' '); 4991 if(parameterNames != null){ 4992 completion.append(parameterNames[i]); 4993 } else { 4994 completion.append('%'); 4995 } 4996 } 4997 4998 completion.append(')'); 4999 5000 //// Exceptions 5001 ReferenceBinding[] exceptions = method.thrownExceptions; 5002 5003 if (exceptions != null && exceptions.length > 0){ 5004 completion.append(' '); 5005 completion.append(THROWS); 5006 completion.append(' '); 5007 for(int i = 0; i < exceptions.length ; i++){ 5008 if(i != 0) { 5009 completion.append(' '); 5010 completion.append(','); 5011 } 5012 createType(exceptions[i], scope, completion); 5013 } 5014 } 5015 } 5016 createProposal(int kind, int completionOffset)5017 protected InternalCompletionProposal createProposal(int kind, int completionOffset) { 5018 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset); 5019 proposal.nameLookup = this.nameEnvironment.nameLookup; 5020 proposal.completionEngine = this; 5021 return proposal; 5022 } 5023 createRequiredTypeProposal(Binding binding, int start, int end, int relevance)5024 private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) { 5025 InternalCompletionProposal proposal = null; 5026 if (binding instanceof ReferenceBinding) { 5027 ReferenceBinding typeBinding = (ReferenceBinding) binding; 5028 5029 char[] packageName = typeBinding.qualifiedPackageName(); 5030 char[] typeName = typeBinding.qualifiedSourceName(); 5031 char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.'); 5032 5033 proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 5034 proposal.nameLookup = this.nameEnvironment.nameLookup; 5035 proposal.completionEngine = this; 5036 proposal.setDeclarationSignature(packageName); 5037 proposal.setSignature(getRequiredTypeSignature(typeBinding)); 5038 proposal.setPackageName(packageName); 5039 proposal.setTypeName(typeName); 5040 proposal.setCompletion(fullyQualifiedName); 5041 proposal.setFlags(typeBinding.modifiers); 5042 proposal.setReplaceRange(start - this.offset, end - this.offset); 5043 proposal.setTokenRange(start - this.offset, end - this.offset); 5044 proposal.setRelevance(relevance); 5045 } else if (binding instanceof PackageBinding) { 5046 PackageBinding packageBinding = (PackageBinding) binding; 5047 5048 char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.'); 5049 5050 proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition); 5051 proposal.setDeclarationSignature(packageName); 5052 proposal.setPackageName(packageName); 5053 proposal.setCompletion(packageName); 5054 proposal.setReplaceRange(start - this.offset, end - this.offset); 5055 proposal.setTokenRange(start - this.offset, end - this.offset); 5056 proposal.setRelevance(relevance); 5057 } 5058 return proposal; 5059 } 5060 createType(TypeBinding type, Scope scope, StringBuffer completion)5061 private void createType(TypeBinding type, Scope scope, StringBuffer completion) { 5062 switch (type.kind()) { 5063 case Binding.BASE_TYPE : 5064 completion.append(type.sourceName()); 5065 break; 5066 case Binding.WILDCARD_TYPE : 5067 case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically 5068 WildcardBinding wildcardBinding = (WildcardBinding) type; 5069 completion.append('?'); 5070 switch (wildcardBinding.boundKind) { 5071 case Wildcard.EXTENDS: 5072 completion.append(' '); 5073 completion.append(EXTENDS); 5074 completion.append(' '); 5075 createType(wildcardBinding.bound, scope, completion); 5076 if(wildcardBinding.otherBounds != null) { 5077 5078 int length = wildcardBinding.otherBounds.length; 5079 for (int i = 0; i < length; i++) { 5080 completion.append(' '); 5081 completion.append('&'); 5082 completion.append(' '); 5083 createType(wildcardBinding.otherBounds[i], scope, completion); 5084 } 5085 } 5086 break; 5087 case Wildcard.SUPER: 5088 completion.append(' '); 5089 completion.append(SUPER); 5090 completion.append(' '); 5091 createType(wildcardBinding.bound, scope, completion); 5092 break; 5093 } 5094 break; 5095 case Binding.ARRAY_TYPE : 5096 createType(type.leafComponentType(), scope, completion); 5097 int dim = type.dimensions(); 5098 for (int i = 0; i < dim; i++) { 5099 completion.append('['); 5100 completion.append(']'); 5101 } 5102 break; 5103 case Binding.PARAMETERIZED_TYPE : 5104 ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type; 5105 if (type.isMemberType()) { 5106 createType(parameterizedType.enclosingType(), scope, completion); 5107 completion.append('.'); 5108 completion.append(parameterizedType.sourceName); 5109 } else { 5110 completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.')); 5111 } 5112 if (parameterizedType.arguments != null) { 5113 completion.append('<'); 5114 for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) { 5115 if (i != 0) completion.append(','); 5116 createType(parameterizedType.arguments[i], scope, completion); 5117 } 5118 completion.append('>'); 5119 } 5120 break; 5121 default : 5122 char[] packageName = type.qualifiedPackageName(); 5123 char[] typeName = type.qualifiedSourceName(); 5124 if(mustQualifyType( 5125 (ReferenceBinding)type, 5126 packageName, 5127 scope)) { 5128 completion.append(CharOperation.concat(packageName, typeName,'.')); 5129 } else { 5130 completion.append(type.sourceName()); 5131 } 5132 break; 5133 } 5134 } 5135 5136 /* 5137 * Create a completion proposal for a member type. 5138 */ createTypeParameterProposal(TypeParameter typeParameter, int relevance)5139 private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) { 5140 char[] completionName = typeParameter.name; 5141 5142 // Create standard type proposal 5143 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 5144 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 5145 proposal.nameLookup = this.nameEnvironment.nameLookup; 5146 proposal.completionEngine = this; 5147 proposal.setSignature(getSignature(typeParameter.binding)); 5148 proposal.setTypeName(completionName); 5149 proposal.setCompletion(completionName); 5150 proposal.setFlags(typeParameter.modifiers); 5151 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5152 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5153 proposal.setRelevance(relevance); 5154 this.requestor.accept(proposal); 5155 if(DEBUG) { 5156 this.printDebug(proposal); 5157 } 5158 } 5159 5160 // Create javadoc text proposal if necessary 5161 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 5162 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 5163 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 5164 proposal.nameLookup = this.nameEnvironment.nameLookup; 5165 proposal.completionEngine = this; 5166 proposal.setSignature(getSignature(typeParameter.binding)); 5167 proposal.setTypeName(javadocCompletion); 5168 proposal.setCompletion(javadocCompletion); 5169 proposal.setFlags(typeParameter.modifiers); 5170 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5171 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5172 proposal.setRelevance(relevance+R_INLINE_TAG); 5173 this.requestor.accept(proposal); 5174 if(DEBUG) { 5175 this.printDebug(proposal); 5176 } 5177 } 5178 } 5179 5180 /* 5181 * Create a completion proposal for a type. 5182 */ createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance)5183 private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) { 5184 5185 // Create standard type proposal 5186 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 5187 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 5188 proposal.nameLookup = this.nameEnvironment.nameLookup; 5189 proposal.completionEngine = this; 5190 proposal.setDeclarationSignature(packageName); 5191 proposal.setSignature(createNonGenericTypeSignature(packageName, typeName)); 5192 proposal.setPackageName(packageName); 5193 proposal.setTypeName(typeName); 5194 proposal.setCompletion(completionName); 5195 proposal.setFlags(modifiers); 5196 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5197 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5198 proposal.setRelevance(relevance); 5199 proposal.setAccessibility(accessibility); 5200 this.requestor.accept(proposal); 5201 if(DEBUG) { 5202 this.printDebug(proposal); 5203 } 5204 } 5205 5206 // Create javadoc text proposal if necessary 5207 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 5208 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 5209 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 5210 proposal.nameLookup = this.nameEnvironment.nameLookup; 5211 proposal.completionEngine = this; 5212 proposal.setDeclarationSignature(packageName); 5213 proposal.setSignature(createNonGenericTypeSignature(packageName, typeName)); 5214 proposal.setPackageName(packageName); 5215 proposal.setTypeName(typeName); 5216 proposal.setCompletion(javadocCompletion); 5217 proposal.setFlags(modifiers); 5218 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 5219 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 5220 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5221 proposal.setRelevance(relevance+R_INLINE_TAG); 5222 proposal.setAccessibility(accessibility); 5223 this.requestor.accept(proposal); 5224 if(DEBUG) { 5225 this.printDebug(proposal); 5226 } 5227 } 5228 } 5229 5230 /* 5231 * Create a completion proposal for a member type. 5232 */ createTypeProposal( ReferenceBinding refBinding, char[] typeName, int accessibility, char[] completionName, int relevance, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)5233 private void createTypeProposal( 5234 ReferenceBinding refBinding, 5235 char[] typeName, 5236 int accessibility, 5237 char[] completionName, 5238 int relevance, 5239 Binding[] missingElements, 5240 int[] missingElementsStarts, 5241 int[] missingElementsEnds, 5242 boolean missingElementsHaveProblems) { 5243 5244 // Create standard type proposal 5245 if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 5246 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset); 5247 proposal.nameLookup = this.nameEnvironment.nameLookup; 5248 proposal.completionEngine = this; 5249 proposal.setDeclarationSignature(refBinding.qualifiedPackageName()); 5250 proposal.setSignature(getCompletedTypeSignature(refBinding)); 5251 proposal.setPackageName(refBinding.qualifiedPackageName()); 5252 proposal.setTypeName(typeName); 5253 if (missingElements != null) { 5254 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 5255 for (int i = 0; i < missingElements.length; i++) { 5256 subProposals[i] = 5257 createRequiredTypeProposal( 5258 missingElements[i], 5259 missingElementsStarts[i], 5260 missingElementsEnds[i], 5261 relevance); 5262 } 5263 proposal.setRequiredProposals(subProposals); 5264 } 5265 proposal.setCompletion(completionName); 5266 proposal.setFlags(refBinding.modifiers); 5267 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5268 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5269 proposal.setRelevance(relevance); 5270 this.requestor.accept(proposal); 5271 if(DEBUG) { 5272 this.printDebug(proposal); 5273 } 5274 } 5275 5276 // Create javadoc text proposal if necessary 5277 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) { 5278 char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK); 5279 InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset); 5280 proposal.nameLookup = this.nameEnvironment.nameLookup; 5281 proposal.completionEngine = this; 5282 proposal.setDeclarationSignature(refBinding.qualifiedPackageName()); 5283 proposal.setSignature(getCompletedTypeSignature(refBinding)); 5284 proposal.setPackageName(refBinding.qualifiedPackageName()); 5285 proposal.setTypeName(typeName); 5286 proposal.setCompletion(javadocCompletion); 5287 proposal.setFlags(refBinding.modifiers); 5288 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 5289 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 5290 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5291 proposal.setRelevance(relevance+R_INLINE_TAG); 5292 this.requestor.accept(proposal); 5293 if(DEBUG) { 5294 this.printDebug(proposal); 5295 } 5296 } 5297 } createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion)5298 private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) { 5299 completion.append(typeVariable.sourceName); 5300 5301 if (typeVariable.superclass != null && TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) { 5302 completion.append(' '); 5303 completion.append(EXTENDS); 5304 completion.append(' '); 5305 createType(typeVariable.superclass, scope, completion); 5306 } 5307 if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) { 5308 if (TypeBinding.notEquals(typeVariable.firstBound, typeVariable.superclass)) { 5309 completion.append(' '); 5310 completion.append(EXTENDS); 5311 completion.append(' '); 5312 } 5313 for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) { 5314 if (i > 0 || TypeBinding.equalsEquals(typeVariable.firstBound, typeVariable.superclass)) { 5315 completion.append(' '); 5316 completion.append(EXTENDS); 5317 completion.append(' '); 5318 } 5319 createType(typeVariable.superInterfaces[i], scope, completion); 5320 } 5321 } 5322 } createVargsType(TypeBinding type, Scope scope, StringBuffer completion)5323 private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) { 5324 if (type.isArrayType()) { 5325 createType(type.leafComponentType(), scope, completion); 5326 int dim = type.dimensions() - 1; 5327 for (int i = 0; i < dim; i++) { 5328 completion.append('['); 5329 completion.append(']'); 5330 } 5331 completion.append(VARARGS); 5332 } else { 5333 createType(type, scope, completion); 5334 } 5335 } findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation)5336 private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) { 5337 MethodBinding[] methods = annotation.availableMethods(); 5338 nextAttribute: for (int i = 0; i < methods.length; i++) { 5339 MethodBinding method = methods[i]; 5340 5341 if(isFailedMatch(token, method.selector)) continue nextAttribute; 5342 5343 int length = attributesFound == null ? 0 : attributesFound.length; 5344 for (int j = 0; j < length; j++) { 5345 if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute; 5346 } 5347 5348 int relevance = computeBaseRelevance(); 5349 relevance += computeRelevanceForResolution(); 5350 relevance += computeRelevanceForInterestingProposal(method); 5351 relevance += computeRelevanceForCaseMatching(token, method.selector); 5352 relevance += computeRelevanceForQualification(false); 5353 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5354 5355 this.noProposal = false; 5356 if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) { 5357 CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition); 5358 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 5359 proposal.setSignature(getSignature(method.returnType)); 5360 proposal.setName(method.selector); 5361 // add "=" to completion since it will always be needed 5362 char[] completion= method.selector; 5363 if (JavaCore.INSERT.equals(this.javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, true))) { 5364 completion= CharOperation.concat(completion, new char[] {' '}); 5365 } 5366 completion= CharOperation.concat(completion, new char[] {'='}); 5367 if (JavaCore.INSERT.equals(this.javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_AFTER_ASSIGNMENT_OPERATOR, true))) { 5368 completion= CharOperation.concat(completion, new char[] {' '}); 5369 } 5370 proposal.setCompletion(completion); 5371 proposal.setFlags(method.modifiers); 5372 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5373 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5374 proposal.setRelevance(relevance); 5375 this.requestor.accept(proposal); 5376 if(DEBUG) { 5377 this.printDebug(proposal); 5378 } 5379 } 5380 } 5381 } findAnonymousType( ReferenceBinding currentType, TypeBinding[] argTypes, Scope scope, InvocationSite invocationSite, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)5382 void findAnonymousType( 5383 ReferenceBinding currentType, 5384 TypeBinding[] argTypes, 5385 Scope scope, 5386 InvocationSite invocationSite, 5387 Binding[] missingElements, 5388 int[] missingElementsStarts, 5389 int[] missingElementsEnds, 5390 boolean missingElementsHaveProblems) { 5391 5392 int relevance = computeBaseRelevance(); 5393 relevance += computeRelevanceForResolution(); 5394 relevance += computeRelevanceForInterestingProposal(currentType); 5395 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5396 5397 if (missingElements != null) { 5398 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 5399 } 5400 5401 findAnonymousType( 5402 currentType, 5403 argTypes, 5404 scope, 5405 invocationSite, 5406 missingElements, 5407 missingElementsStarts, 5408 missingElementsEnds, 5409 missingElementsHaveProblems, 5410 true, 5411 false, 5412 relevance); 5413 } findAnonymousType( ReferenceBinding currentType, TypeBinding[] argTypes, Scope scope, InvocationSite invocationSite, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, boolean exactMatch, boolean isQualified, int relevance)5414 private void findAnonymousType( 5415 ReferenceBinding currentType, 5416 TypeBinding[] argTypes, 5417 Scope scope, 5418 InvocationSite invocationSite, 5419 Binding[] missingElements, 5420 int[] missingElementsStarts, 5421 int[] missingElementsEnds, 5422 boolean missingElementsHaveProblems, 5423 boolean exactMatch, 5424 boolean isQualified, 5425 int relevance) { 5426 5427 if (currentType.isInterface()) { 5428 char[] completion = CharOperation.NO_CHAR; 5429 char[] typeCompletion = null; 5430 if (!exactMatch) { 5431 typeCompletion = 5432 isQualified ? 5433 CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') : 5434 currentType.sourceName(); 5435 if (this.source != null 5436 && this.source.length > this.endPosition 5437 && this.source[this.endPosition] == '(') { 5438 completion = CharOperation.NO_CHAR; 5439 } else { 5440 completion = new char[] { '(', ')' }; 5441 } 5442 } 5443 5444 this.noProposal = false; 5445 if (!exactMatch) { 5446 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 5447 char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName(); 5448 char[] typeName = currentType.qualifiedSourceName(); 5449 5450 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 5451 proposal.setDeclarationSignature(getSignature(currentType)); 5452 proposal.setDeclarationKey(currentType.computeUniqueKey()); 5453 proposal.setSignature( 5454 createMethodSignature( 5455 CharOperation.NO_CHAR_CHAR, 5456 CharOperation.NO_CHAR_CHAR, 5457 CharOperation.NO_CHAR, 5458 CharOperation.NO_CHAR)); 5459 //proposal.setOriginalSignature(null); 5460 //proposal.setUniqueKey(null); 5461 proposal.setDeclarationPackageName(packageName); 5462 proposal.setDeclarationTypeName(typeName); 5463 //proposal.setParameterPackageNames(null); 5464 //proposal.setParameterTypeNames(null); 5465 //proposal.setPackageName(null); 5466 //proposal.setTypeName(null); 5467 proposal.setName(currentType.sourceName()); 5468 5469 InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 5470 typeProposal.nameLookup = this.nameEnvironment.nameLookup; 5471 typeProposal.completionEngine = this; 5472 typeProposal.setDeclarationSignature(packageName); 5473 typeProposal.setSignature(getRequiredTypeSignature(currentType)); 5474 typeProposal.setPackageName(packageName); 5475 typeProposal.setTypeName(typeName); 5476 typeProposal.setCompletion(typeCompletion); 5477 typeProposal.setFlags(currentType.modifiers); 5478 typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5479 typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset); 5480 typeProposal.setRelevance(relevance); 5481 proposal.setRequiredProposals( new CompletionProposal[]{typeProposal}); 5482 5483 proposal.setCompletion(completion); 5484 proposal.setFlags(Flags.AccPublic); 5485 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 5486 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5487 proposal.setRelevance(relevance); 5488 this.requestor.accept(proposal); 5489 if(DEBUG) { 5490 this.printDebug(proposal); 5491 } 5492 } 5493 } else { 5494 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) { 5495 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition); 5496 proposal.setDeclarationSignature(getSignature(currentType)); 5497 proposal.setDeclarationKey(currentType.computeUniqueKey()); 5498 proposal.setSignature( 5499 createMethodSignature( 5500 CharOperation.NO_CHAR_CHAR, 5501 CharOperation.NO_CHAR_CHAR, 5502 CharOperation.NO_CHAR, 5503 CharOperation.NO_CHAR)); 5504 //proposal.setOriginalSignature(null); 5505 //proposal.setUniqueKey(null); 5506 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 5507 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 5508 //proposal.setParameterPackageNames(null); 5509 //proposal.setParameterTypeNames(null); 5510 //proposal.setPackageName(null); 5511 //proposal.setTypeName(null); 5512 if (missingElements != null) { 5513 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 5514 for (int i = 0; i < missingElements.length; i++) { 5515 subProposals[i] = 5516 createRequiredTypeProposal( 5517 missingElements[i], 5518 missingElementsStarts[i], 5519 missingElementsEnds[i], 5520 relevance); 5521 } 5522 proposal.setRequiredProposals(subProposals); 5523 } 5524 proposal.setCompletion(completion); 5525 proposal.setFlags(Flags.AccPublic); 5526 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 5527 proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset); 5528 proposal.setRelevance(relevance); 5529 this.requestor.accept(proposal); 5530 if(DEBUG) { 5531 this.printDebug(proposal); 5532 } 5533 } 5534 } 5535 } else { 5536 findConstructors( 5537 currentType, 5538 argTypes, 5539 scope, 5540 invocationSite, 5541 true, 5542 missingElements, 5543 missingElementsStarts, 5544 missingElementsEnds, 5545 missingElementsHaveProblems, 5546 exactMatch, 5547 isQualified, 5548 relevance); 5549 } 5550 } findClassField( char[] token, TypeBinding receiverType, Scope scope, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)5551 private void findClassField( 5552 char[] token, 5553 TypeBinding receiverType, 5554 Scope scope, 5555 Binding[] missingElements, 5556 int[] missingElementsStarts, 5557 int[] missingElementsEnds, 5558 boolean missingElementsHaveProblems) { 5559 5560 if (token == null) return; 5561 5562 if (token.length <= classField.length 5563 && CharOperation.prefixEquals(token, classField, false /* ignore case */ 5564 )) { 5565 int relevance = computeBaseRelevance(); 5566 relevance += computeRelevanceForResolution(); 5567 relevance += computeRelevanceForInterestingProposal(); 5568 relevance += computeRelevanceForCaseMatching(token, classField); 5569 relevance += computeRelevanceForExpectingType(scope.getJavaLangClass()); 5570 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field 5571 relevance += R_NON_INHERITED; 5572 5573 if (missingElements != null) { 5574 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 5575 } 5576 5577 this.noProposal = false; 5578 if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) { 5579 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 5580 //proposal.setDeclarationSignature(null); 5581 char[] signature = 5582 createNonGenericTypeSignature( 5583 CharOperation.concatWith(JAVA_LANG, '.'), 5584 CLASS); 5585 if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) { 5586 // add type argument 5587 char[] typeArgument = getTypeSignature(receiverType); 5588 int oldLength = signature.length; 5589 int argumentLength = typeArgument.length; 5590 int newLength = oldLength + argumentLength + 2; 5591 System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1); 5592 signature[oldLength - 1] = '<'; 5593 System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength); 5594 signature[newLength - 2] = '>'; 5595 signature[newLength - 1] = ';'; 5596 } 5597 proposal.setSignature(signature); 5598 //proposal.setDeclarationPackageName(null); 5599 //proposal.setDeclarationTypeName(null); 5600 proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.')); 5601 proposal.setTypeName(CLASS); 5602 proposal.setName(classField); 5603 if (missingElements != null) { 5604 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 5605 for (int i = 0; i < missingElements.length; i++) { 5606 subProposals[i] = 5607 createRequiredTypeProposal( 5608 missingElements[i], 5609 missingElementsStarts[i], 5610 missingElementsEnds[i], 5611 relevance); 5612 } 5613 proposal.setRequiredProposals(subProposals); 5614 } 5615 proposal.setCompletion(classField); 5616 proposal.setFlags(Flags.AccStatic | Flags.AccPublic); 5617 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5618 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5619 proposal.setRelevance(relevance); 5620 this.requestor.accept(proposal); 5621 if(DEBUG) { 5622 this.printDebug(proposal); 5623 } 5624 } 5625 } 5626 } 5627 findConstructors( ReferenceBinding currentType, TypeBinding[] argTypes, Scope scope, InvocationSite invocationSite, boolean forAnonymousType, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)5628 void findConstructors( 5629 ReferenceBinding currentType, 5630 TypeBinding[] argTypes, 5631 Scope scope, 5632 InvocationSite invocationSite, 5633 boolean forAnonymousType, 5634 Binding[] missingElements, 5635 int[] missingElementsStarts, 5636 int[] missingElementsEnds, 5637 boolean missingElementsHaveProblems) { 5638 5639 int relevance = computeBaseRelevance(); 5640 relevance += computeRelevanceForResolution(); 5641 relevance += computeRelevanceForInterestingProposal(); 5642 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 5643 5644 if (missingElements != null) { 5645 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 5646 } 5647 5648 findConstructors( 5649 currentType, 5650 argTypes, 5651 scope, 5652 invocationSite, 5653 forAnonymousType, 5654 missingElements, 5655 missingElementsStarts, 5656 missingElementsEnds, 5657 missingElementsHaveProblems, 5658 true, 5659 false, 5660 relevance); 5661 } 5662 5663 findConstructorsFromMissingType( TypeReference typeRef, final TypeBinding[] argTypes, final Scope scope, final InvocationSite invocationSite)5664 private void findConstructorsFromMissingType( 5665 TypeReference typeRef, 5666 final TypeBinding[] argTypes, 5667 final Scope scope, 5668 final InvocationSite invocationSite) { 5669 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 5670 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 5671 new MissingTypesGuesser.GuessedTypeRequestor() { 5672 @Override 5673 public void accept( 5674 TypeBinding guessedType, 5675 Binding[] missingElements, 5676 int[] missingElementsStarts, 5677 int[] missingElementsEnds, 5678 boolean hasProblems) { 5679 if (guessedType instanceof ReferenceBinding) { 5680 ReferenceBinding ref = (ReferenceBinding) guessedType; 5681 if (!isIgnored(CompletionProposal.METHOD_REF, missingElements != null) 5682 && ref.isClass() 5683 && !ref.isAbstract()) { 5684 findConstructors( 5685 ref, 5686 argTypes, 5687 scope, 5688 invocationSite, 5689 false, 5690 missingElements, 5691 missingElementsStarts, 5692 missingElementsEnds, 5693 hasProblems); 5694 } 5695 5696 checkCancel(); 5697 5698 if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null) 5699 && !ref.isFinal() 5700 && !ref.isEnum()){ 5701 findAnonymousType( 5702 ref, 5703 argTypes, 5704 scope, 5705 invocationSite, 5706 missingElements, 5707 missingElementsStarts, 5708 missingElementsEnds, 5709 hasProblems); 5710 } 5711 } 5712 } 5713 }; 5714 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 5715 } 5716 findConstructors( ReferenceBinding currentType, TypeBinding[] argTypes, Scope scope, InvocationSite invocationSite, boolean forAnonymousType, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, boolean exactMatch, boolean isQualified, int relevance)5717 private void findConstructors( 5718 ReferenceBinding currentType, 5719 TypeBinding[] argTypes, 5720 Scope scope, 5721 InvocationSite invocationSite, 5722 boolean forAnonymousType, 5723 Binding[] missingElements, 5724 int[] missingElementsStarts, 5725 int[] missingElementsEnds, 5726 boolean missingElementsHaveProblems, 5727 boolean exactMatch, 5728 boolean isQualified, 5729 int relevance) { 5730 5731 // No visibility checks can be performed without the scope & invocationSite 5732 MethodBinding[] methods = null; 5733 if (currentType instanceof ParameterizedTypeBinding && invocationSite instanceof CompletionOnQualifiedAllocationExpression) { 5734 CompletionOnQualifiedAllocationExpression alloc = (CompletionOnQualifiedAllocationExpression) invocationSite; 5735 if ((alloc.bits & ASTNode.IsDiamond) != 0) { 5736 // inference failed. So don't substitute type arguments. Just return the unsubstituted methods 5737 // and let the user decide what to substitute. 5738 ParameterizedTypeBinding binding = (ParameterizedTypeBinding) currentType; 5739 ReferenceBinding originalGenericType = binding.genericType(); 5740 if (originalGenericType != null) 5741 methods = originalGenericType.methods(); 5742 } else { 5743 methods = currentType.availableMethods(); 5744 } 5745 } else { 5746 methods = currentType.availableMethods(); 5747 } 5748 if(methods != null) { 5749 int minArgLength = argTypes == null ? 0 : argTypes.length; 5750 next : for (int f = methods.length; --f >= 0;) { 5751 MethodBinding constructor = methods[f]; 5752 if (constructor.isConstructor()) { 5753 5754 if (constructor.isSynthetic()) continue next; 5755 5756 if (this.options.checkDeprecation && 5757 constructor.isViewedAsDeprecated() && 5758 !scope.isDefinedInSameUnit(constructor.declaringClass)) 5759 continue next; 5760 5761 if (this.options.checkVisibility 5762 && !constructor.canBeSeenBy(invocationSite, scope)) { 5763 if(!forAnonymousType || !constructor.isProtected()) 5764 continue next; 5765 } 5766 5767 TypeBinding[] parameters = constructor.parameters; 5768 int paramLength = parameters.length; 5769 if (minArgLength > paramLength) 5770 continue next; 5771 for (int a = minArgLength; --a >= 0;) 5772 if (argTypes[a] != null) { // can be null if it could not be resolved properly 5773 if (!argTypes[a].isCompatibleWith(constructor.parameters[a])) 5774 continue next; 5775 } 5776 5777 char[][] parameterPackageNames = new char[paramLength][]; 5778 char[][] parameterTypeNames = new char[paramLength][]; 5779 for (int i = 0; i < paramLength; i++) { 5780 TypeBinding type = parameters[i]; 5781 parameterPackageNames[i] = type.qualifiedPackageName(); 5782 parameterTypeNames[i] = type.qualifiedSourceName(); 5783 } 5784 char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames); 5785 5786 char[] completion = CharOperation.NO_CHAR; 5787 5788 if(forAnonymousType){ 5789 char[] typeCompletion = null; 5790 if (!exactMatch) { 5791 typeCompletion = 5792 isQualified ? 5793 CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') : 5794 currentType.sourceName(); 5795 if (this.source != null 5796 && this.source.length > this.endPosition 5797 && this.source[this.endPosition] == '(') { 5798 completion = CharOperation.NO_CHAR; 5799 } else { 5800 completion = new char[] { '(', ')' }; 5801 } 5802 } 5803 5804 this.noProposal = false; 5805 if (!exactMatch) { 5806 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 5807 char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName(); 5808 char[] typeName = currentType.qualifiedSourceName(); 5809 5810 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 5811 proposal.setBinding(constructor); 5812 proposal.setDeclarationSignature(getSignature(currentType)); 5813 proposal.setDeclarationKey(currentType.computeUniqueKey()); 5814 proposal.setSignature(getSignature(constructor)); 5815 MethodBinding original = constructor.original(); 5816 if(original != constructor) { 5817 proposal.setOriginalSignature(getSignature(original)); 5818 } 5819 proposal.setKey(constructor.computeUniqueKey()); 5820 proposal.setDeclarationPackageName(packageName); 5821 proposal.setDeclarationTypeName(typeName); 5822 proposal.setParameterPackageNames(parameterPackageNames); 5823 proposal.setParameterTypeNames(parameterTypeNames); 5824 //proposal.setPackageName(null); 5825 //proposal.setTypeName(null); 5826 proposal.setName(currentType.sourceName()); 5827 5828 InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 5829 typeProposal.nameLookup = this.nameEnvironment.nameLookup; 5830 typeProposal.completionEngine = this; 5831 typeProposal.setDeclarationSignature(packageName); 5832 typeProposal.setSignature(getRequiredTypeSignature(currentType)); 5833 typeProposal.setPackageName(packageName); 5834 typeProposal.setTypeName(typeName); 5835 typeProposal.setCompletion(typeCompletion); 5836 typeProposal.setFlags(currentType.modifiers); 5837 typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5838 typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset); 5839 typeProposal.setRelevance(relevance); 5840 proposal.setRequiredProposals( new CompletionProposal[]{typeProposal}); 5841 5842 proposal.setCompletion(completion); 5843 proposal.setFlags(constructor.modifiers); 5844 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 5845 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 5846 proposal.setRelevance(relevance); 5847 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5848 this.requestor.accept(proposal); 5849 if(DEBUG) { 5850 this.printDebug(proposal); 5851 } 5852 } 5853 } else { 5854 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, missingElements != null)) { 5855 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition); 5856 proposal.setDeclarationSignature(getSignature(currentType)); 5857 proposal.setDeclarationKey(currentType.computeUniqueKey()); 5858 proposal.setSignature(getSignature(constructor)); 5859 MethodBinding original = constructor.original(); 5860 if(original != constructor) { 5861 proposal.setOriginalSignature(getSignature(original)); 5862 } 5863 proposal.setKey(constructor.computeUniqueKey()); 5864 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 5865 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 5866 proposal.setParameterPackageNames(parameterPackageNames); 5867 proposal.setParameterTypeNames(parameterTypeNames); 5868 //proposal.setPackageName(null); 5869 //proposal.setTypeName(null); 5870 if (missingElements != null) { 5871 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 5872 for (int i = 0; i < missingElements.length; i++) { 5873 subProposals[i] = 5874 createRequiredTypeProposal( 5875 missingElements[i], 5876 missingElementsStarts[i], 5877 missingElementsEnds[i], 5878 relevance); 5879 } 5880 proposal.setRequiredProposals(subProposals); 5881 } 5882 proposal.setCompletion(completion); 5883 proposal.setFlags(constructor.modifiers); 5884 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 5885 proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset); 5886 proposal.setRelevance(relevance); 5887 if(parameterNames != null) proposal.setParameterNames(parameterNames); 5888 this.requestor.accept(proposal); 5889 if(DEBUG) { 5890 this.printDebug(proposal); 5891 } 5892 } 5893 } 5894 } else { 5895 char[] typeCompletion = null; 5896 // Special case for completion in javadoc 5897 if (this.assistNodeInJavadoc > 0) { 5898 Expression receiver = null; 5899 char[] selector = null; 5900 if (invocationSite instanceof CompletionOnJavadocAllocationExpression) { 5901 CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite; 5902 receiver = alloc.type; 5903 } else if (invocationSite instanceof CompletionOnJavadocFieldReference) { 5904 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 5905 receiver = fieldRef.receiver; 5906 } 5907 if (receiver != null) { 5908 StringBuffer javadocCompletion = new StringBuffer(); 5909 if (receiver.isThis()) { 5910 selector = (((JavadocImplicitTypeReference)receiver).token); 5911 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 5912 javadocCompletion.append('#'); 5913 } 5914 } else if (receiver instanceof JavadocSingleTypeReference) { 5915 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver; 5916 selector = typeRef.token; 5917 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 5918 javadocCompletion.append(typeRef.token); 5919 javadocCompletion.append('#'); 5920 } 5921 } else if (receiver instanceof JavadocQualifiedTypeReference) { 5922 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver; 5923 selector = typeRef.tokens[typeRef.tokens.length-1]; 5924 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 5925 javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.')); 5926 javadocCompletion.append('#'); 5927 } 5928 } 5929 // Append parameters types 5930 javadocCompletion.append(selector); 5931 javadocCompletion.append('('); 5932 if (constructor.parameters != null) { 5933 boolean isVarargs = constructor.isVarargs(); 5934 for (int p=0, ln=constructor.parameters.length; p<ln; p++) { 5935 if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$ 5936 TypeBinding argTypeBinding = constructor.parameters[p]; 5937 if (isVarargs && p == ln - 1) { 5938 createVargsType(argTypeBinding.erasure(), scope, javadocCompletion); 5939 } else { 5940 createType(argTypeBinding.erasure(), scope, javadocCompletion); 5941 } 5942 } 5943 } 5944 javadocCompletion.append(')'); 5945 completion = javadocCompletion.toString().toCharArray(); 5946 } 5947 } else { 5948 if (!exactMatch) { 5949 typeCompletion = 5950 isQualified ? 5951 CharOperation.concat(currentType.qualifiedPackageName(), currentType.qualifiedSourceName(), '.') : 5952 currentType.sourceName(); 5953 5954 if (this.source != null 5955 && this.source.length > this.endPosition 5956 && this.source[this.endPosition] == '(') { 5957 completion = CharOperation.NO_CHAR; 5958 } else { 5959 completion = new char[] { '(', ')' }; 5960 } 5961 } 5962 } 5963 5964 // Create standard proposal 5965 this.noProposal = false; 5966 if (!exactMatch) { 5967 if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 5968 char[] packageName = currentType.isLocalType() ? null : currentType.qualifiedPackageName(); 5969 char[] typeName = currentType.qualifiedSourceName(); 5970 int constructorRelevance = relevance + computeRelevanceForConstructor(); 5971 InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 5972 proposal.setBinding(constructor); 5973 proposal.setDeclarationSignature(getSignature(currentType)); 5974 proposal.setSignature(getSignature(constructor)); 5975 MethodBinding original = constructor.original(); 5976 if(original != constructor) { 5977 proposal.setOriginalSignature(getSignature(original)); 5978 } 5979 proposal.setDeclarationPackageName(packageName); 5980 proposal.setDeclarationTypeName(typeName); 5981 proposal.setParameterPackageNames(parameterPackageNames); 5982 proposal.setParameterTypeNames(parameterTypeNames); 5983 //proposal.setPackageName(null); 5984 //proposal.setTypeName(null); 5985 proposal.setName(currentType.sourceName()); 5986 5987 InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 5988 typeProposal.nameLookup = this.nameEnvironment.nameLookup; 5989 typeProposal.completionEngine = this; 5990 typeProposal.setDeclarationSignature(packageName); 5991 typeProposal.setSignature(getRequiredTypeSignature(currentType)); 5992 typeProposal.setPackageName(packageName); 5993 typeProposal.setTypeName(typeName); 5994 typeProposal.setCompletion(typeCompletion); 5995 typeProposal.setFlags(currentType.modifiers); 5996 typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 5997 typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset); 5998 typeProposal.setRelevance(constructorRelevance); 5999 proposal.setRequiredProposals( new CompletionProposal[]{typeProposal}); 6000 6001 proposal.setIsContructor(true); 6002 proposal.setCompletion(completion); 6003 proposal.setFlags(constructor.modifiers); 6004 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 6005 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6006 proposal.setRelevance(constructorRelevance); 6007 if(parameterNames != null) proposal.setParameterNames(parameterNames); 6008 this.requestor.accept(proposal); 6009 if(DEBUG) { 6010 this.printDebug(proposal); 6011 } 6012 } 6013 } else { 6014 if(!isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 6015 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 6016 proposal.setBinding(constructor); 6017 proposal.setDeclarationSignature(getSignature(currentType)); 6018 proposal.setSignature(getSignature(constructor)); 6019 MethodBinding original = constructor.original(); 6020 if(original != constructor) { 6021 proposal.setOriginalSignature(getSignature(original)); 6022 } 6023 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 6024 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 6025 proposal.setParameterPackageNames(parameterPackageNames); 6026 proposal.setParameterTypeNames(parameterTypeNames); 6027 //proposal.setPackageName(null); 6028 //proposal.setTypeName(null); 6029 proposal.setName(currentType.sourceName()); 6030 if (missingElements != null) { 6031 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 6032 for (int i = 0; i < missingElements.length; i++) { 6033 subProposals[i] = 6034 createRequiredTypeProposal( 6035 missingElements[i], 6036 missingElementsStarts[i], 6037 missingElementsEnds[i], 6038 relevance); 6039 } 6040 proposal.setRequiredProposals(subProposals); 6041 } 6042 proposal.setIsContructor(true); 6043 proposal.setCompletion(completion); 6044 proposal.setFlags(constructor.modifiers); 6045 int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition; 6046 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 6047 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6048 proposal.setRelevance(relevance); 6049 if(parameterNames != null) proposal.setParameterNames(parameterNames); 6050 this.requestor.accept(proposal); 6051 if(DEBUG) { 6052 this.printDebug(proposal); 6053 } 6054 } 6055 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 6056 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 6057 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition); 6058 proposal.setBinding(constructor); 6059 proposal.setDeclarationSignature(getSignature(currentType)); 6060 proposal.setSignature(getSignature(constructor)); 6061 MethodBinding original = constructor.original(); 6062 if(original != constructor) { 6063 proposal.setOriginalSignature(getSignature(original)); 6064 } 6065 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 6066 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 6067 proposal.setParameterPackageNames(parameterPackageNames); 6068 proposal.setParameterTypeNames(parameterTypeNames); 6069 //proposal.setPackageName(null); 6070 //proposal.setTypeName(null); 6071 proposal.setName(currentType.sourceName()); 6072 proposal.setIsContructor(true); 6073 proposal.setCompletion(javadocCompletion); 6074 proposal.setFlags(constructor.modifiers); 6075 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 6076 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 6077 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6078 proposal.setRelevance(relevance+R_INLINE_TAG); 6079 if(parameterNames != null) proposal.setParameterNames(parameterNames); 6080 this.requestor.accept(proposal); 6081 if(DEBUG) { 6082 this.printDebug(proposal); 6083 } 6084 } 6085 } 6086 } 6087 } 6088 } 6089 } 6090 } 6091 getResolvedSignature(char[][] parameterTypes, char[] fullyQualifiedTypeName, int parameterCount, Scope scope)6092 private char[] getResolvedSignature(char[][] parameterTypes, char[] fullyQualifiedTypeName, int parameterCount, Scope scope) { 6093 char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName); 6094 6095 TypeReference ref; 6096 if (cn.length == 1) { 6097 ref = new SingleTypeReference(cn[0], 0); 6098 } else { 6099 ref = new QualifiedTypeReference(cn,new long[cn.length]); 6100 } 6101 6102 TypeBinding guessedType = null; 6103 INameEnvironment oldNameEnvironment = this.lookupEnvironment.nameEnvironment; 6104 this.lookupEnvironment.nameEnvironment = getNoCacheNameEnvironment(); 6105 try { 6106 switch (scope.kind) { 6107 case Scope.METHOD_SCOPE : 6108 case Scope.BLOCK_SCOPE : 6109 guessedType = ref.resolveType((BlockScope)scope); 6110 break; 6111 case Scope.CLASS_SCOPE : 6112 guessedType = ref.resolveType((ClassScope)scope); 6113 break; 6114 } 6115 6116 6117 if (guessedType != null && guessedType.isValidBinding()) { 6118 // the erasure must be used because guessedType can be a RawTypeBinding (https://bugs.eclipse.org/bugs/show_bug.cgi?id=276890) 6119 guessedType = guessedType.erasure(); 6120 6121 if (guessedType instanceof SourceTypeBinding) { 6122 SourceTypeBinding refBinding = (SourceTypeBinding) guessedType; 6123 6124 if (refBinding.scope == null || refBinding.scope.referenceContext == null) return null; 6125 6126 TypeDeclaration typeDeclaration = refBinding.scope.referenceContext; 6127 AbstractMethodDeclaration[] methods = typeDeclaration.methods; 6128 6129 next : for (int i = 0; i < methods.length; i++) { 6130 AbstractMethodDeclaration method = methods[i]; 6131 6132 if (!method.isConstructor()) continue next; 6133 6134 Argument[] arguments = method.arguments; 6135 int argumentsLength = arguments == null ? 0 : arguments.length; 6136 6137 if (parameterCount != argumentsLength) continue next; 6138 6139 for (int j = 0; j < argumentsLength; j++) { 6140 char[] argumentTypeName = getTypeName(arguments[j].type); 6141 6142 if (!CharOperation.equals(argumentTypeName, parameterTypes[j])) { 6143 continue next; 6144 } 6145 } 6146 6147 refBinding.resolveTypesFor(method.binding); // force resolution 6148 if (method.binding == null) continue next; 6149 return getSignature(method.binding); 6150 } 6151 } 6152 } 6153 } finally { 6154 this.lookupEnvironment.nameEnvironment = oldNameEnvironment; 6155 } 6156 6157 return null; 6158 } 6159 findConstructorsOrAnonymousTypes( ReferenceBinding currentType, Scope scope, InvocationSite invocationSite, boolean isQualified, int relevance)6160 private void findConstructorsOrAnonymousTypes( 6161 ReferenceBinding currentType, 6162 Scope scope, 6163 InvocationSite invocationSite, 6164 boolean isQualified, 6165 int relevance) { 6166 6167 if (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) 6168 && currentType.isClass() 6169 && !currentType.isAbstract()) { 6170 findConstructors( 6171 currentType, 6172 null, 6173 scope, 6174 invocationSite, 6175 false, 6176 null, 6177 null, 6178 null, 6179 false, 6180 false, 6181 isQualified, 6182 relevance); 6183 } 6184 6185 // This code is disabled because there is too much proposals when constructors and anonymous are proposed 6186 if (!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) 6187 && !currentType.isFinal() 6188 && (currentType.isInterface() || (currentType.isClass() && currentType.isAbstract()))){ 6189 findAnonymousType( 6190 currentType, 6191 null, 6192 scope, 6193 invocationSite, 6194 null, 6195 null, 6196 null, 6197 false, 6198 false, 6199 isQualified, 6200 relevance); 6201 } 6202 } findEnclosingTypeNames(Scope scope)6203 private char[][] findEnclosingTypeNames(Scope scope){ 6204 char[][] excludedNames = new char[10][]; 6205 int excludedNameCount = 0; 6206 6207 Scope currentScope = scope; 6208 while(currentScope != null) { 6209 switch (currentScope.kind) { 6210 case Scope.CLASS_SCOPE : 6211 ClassScope classScope = (ClassScope) currentScope; 6212 6213 TypeDeclaration typeDeclaration = classScope.referenceContext; 6214 6215 if(excludedNameCount == excludedNames.length) { 6216 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 6217 } 6218 excludedNames[excludedNameCount++] = typeDeclaration.name; 6219 6220 TypeParameter[] classTypeParameters = typeDeclaration.typeParameters; 6221 if(classTypeParameters != null) { 6222 for (int i = 0; i < classTypeParameters.length; i++) { 6223 TypeParameter typeParameter = classTypeParameters[i]; 6224 if(excludedNameCount == excludedNames.length) { 6225 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 6226 } 6227 excludedNames[excludedNameCount++] = typeParameter.name; 6228 } 6229 } 6230 break; 6231 case Scope.METHOD_SCOPE : 6232 MethodScope methodScope = (MethodScope) currentScope; 6233 if(methodScope.referenceContext instanceof AbstractMethodDeclaration) { 6234 TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters(); 6235 if(methodTypeParameters != null) { 6236 for (int i = 0; i < methodTypeParameters.length; i++) { 6237 TypeParameter typeParameter = methodTypeParameters[i]; 6238 if(excludedNameCount == excludedNames.length) { 6239 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount); 6240 } 6241 excludedNames[excludedNameCount++] = typeParameter.name; 6242 } 6243 } 6244 } 6245 break; 6246 } 6247 6248 currentScope = currentScope.parent; 6249 } 6250 6251 if(excludedNameCount == 0) { 6252 return CharOperation.NO_CHAR_CHAR; 6253 } 6254 System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount); 6255 return excludedNames; 6256 } findEnumConstants( char[] enumConstantName, ReferenceBinding enumType, Scope invocationScope, ObjectVector fieldsFound, char[][] alreadyUsedConstants, int alreadyUsedConstantCount, boolean needQualification)6257 private void findEnumConstants( 6258 char[] enumConstantName, 6259 ReferenceBinding enumType, 6260 Scope invocationScope, 6261 ObjectVector fieldsFound, 6262 char[][] alreadyUsedConstants, 6263 int alreadyUsedConstantCount, 6264 boolean needQualification) { 6265 6266 FieldBinding[] fields = enumType.fields(); 6267 6268 int enumConstantLength = enumConstantName.length; 6269 next : for (int f = fields.length; --f >= 0;) { 6270 FieldBinding field = fields[f]; 6271 6272 if (field.isSynthetic()) continue next; 6273 6274 if ((field.modifiers & Flags.AccEnum) == 0) continue next; 6275 6276 if (enumConstantLength > field.name.length) continue next; 6277 6278 if (isFailedMatch(enumConstantName, field.name)) continue next; 6279 6280 char[] fieldName = field.name; 6281 6282 for (int i = 0; i < alreadyUsedConstantCount; i++) { 6283 if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next; 6284 } 6285 6286 int relevance = computeBaseRelevance(); 6287 relevance += computeRelevanceForResolution(); 6288 relevance += computeRelevanceForInterestingProposal(field); 6289 relevance += computeRelevanceForCaseMatching(enumConstantName, field.name); 6290 relevance += computeRelevanceForExpectingType(field.type); 6291 relevance += computeRelevanceForEnumConstant(field.type); 6292 relevance += computeRelevanceForQualification(needQualification); 6293 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6294 6295 this.noProposal = false; 6296 if (!needQualification) { 6297 char[] completion = fieldName; 6298 6299 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 6300 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 6301 proposal.setBinding(field); 6302 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 6303 proposal.setSignature(getSignature(field.type)); 6304 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6305 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6306 proposal.setPackageName(field.type.qualifiedPackageName()); 6307 proposal.setTypeName(field.type.qualifiedSourceName()); 6308 proposal.setName(field.name); 6309 proposal.setCompletion(completion); 6310 proposal.setFlags(field.modifiers); 6311 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6312 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6313 proposal.setRelevance(relevance); 6314 this.requestor.accept(proposal); 6315 if(DEBUG) { 6316 this.printDebug(proposal); 6317 } 6318 } 6319 6320 } else { 6321 TypeBinding visibleType = invocationScope.getType(field.type.sourceName()); 6322 boolean needImport = visibleType == null || !visibleType.isValidBinding(); 6323 6324 char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.'); 6325 6326 if (!needImport) { 6327 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 6328 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 6329 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 6330 proposal.setSignature(getSignature(field.type)); 6331 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6332 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6333 proposal.setPackageName(field.type.qualifiedPackageName()); 6334 proposal.setTypeName(field.type.qualifiedSourceName()); 6335 proposal.setName(field.name); 6336 proposal.setCompletion(completion); 6337 proposal.setFlags(field.modifiers); 6338 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6339 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6340 proposal.setRelevance(relevance); 6341 this.requestor.accept(proposal); 6342 if(DEBUG) { 6343 this.printDebug(proposal); 6344 } 6345 } 6346 } else { 6347 if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) { 6348 CompilationUnitDeclaration cu = this.unitScope.referenceContext; 6349 int importStart = cu.types[0].declarationSourceStart; 6350 int importEnd = importStart; 6351 6352 ReferenceBinding fieldType = (ReferenceBinding)field.type; 6353 6354 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 6355 proposal.setBinding(field); 6356 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 6357 proposal.setSignature(getSignature(field.type)); 6358 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6359 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6360 proposal.setPackageName(field.type.qualifiedPackageName()); 6361 proposal.setTypeName(field.type.qualifiedSourceName()); 6362 proposal.setName(field.name); 6363 proposal.setCompletion(completion); 6364 proposal.setFlags(field.modifiers); 6365 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6366 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6367 proposal.setRelevance(relevance); 6368 6369 char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false); 6370 6371 InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition); 6372 typeImportProposal.nameLookup = this.nameEnvironment.nameLookup; 6373 typeImportProposal.completionEngine = this; 6374 char[] packageName = fieldType.qualifiedPackageName(); 6375 typeImportProposal.setDeclarationSignature(packageName); 6376 typeImportProposal.setSignature(getSignature(fieldType)); 6377 typeImportProposal.setPackageName(packageName); 6378 typeImportProposal.setTypeName(fieldType.qualifiedSourceName()); 6379 typeImportProposal.setCompletion(typeImportCompletion); 6380 typeImportProposal.setFlags(fieldType.modifiers); 6381 typeImportProposal.setAdditionalFlags(CompletionFlags.Default); 6382 typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 6383 typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset); 6384 typeImportProposal.setRelevance(relevance); 6385 6386 proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal}); 6387 6388 this.requestor.accept(proposal); 6389 if(DEBUG) { 6390 this.printDebug(proposal); 6391 } 6392 } 6393 } 6394 } 6395 } 6396 } findEnumConstantsFromExpectedTypes( char[] token, Scope invocationScope, ObjectVector fieldsFound)6397 private void findEnumConstantsFromExpectedTypes( 6398 char[] token, 6399 Scope invocationScope, 6400 ObjectVector fieldsFound) { 6401 int length = this.expectedTypesPtr + 1; 6402 for (int i = 0; i < length; i++) { 6403 if (this.expectedTypes[i].isEnum()) { 6404 findEnumConstants( 6405 token, 6406 (ReferenceBinding)this.expectedTypes[i], 6407 invocationScope, 6408 fieldsFound, 6409 CharOperation.NO_CHAR_CHAR, 6410 0, 6411 true); 6412 } 6413 } 6414 6415 } findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement)6416 private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) { 6417 TypeBinding expressionType = switchStatement.expression.resolvedType; 6418 if(expressionType != null && expressionType.isEnum()) { 6419 ReferenceBinding enumType = (ReferenceBinding) expressionType; 6420 6421 CaseStatement[] cases = switchStatement.cases; 6422 6423 char[][] alreadyUsedConstants = new char[switchStatement.caseCount][]; 6424 int alreadyUsedConstantCount = 0; 6425 for (int i = 0; i < switchStatement.caseCount; i++) { 6426 Expression caseExpression = cases[i].constantExpression; 6427 if((caseExpression instanceof SingleNameReference) 6428 && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) { 6429 alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token; 6430 } 6431 } 6432 6433 findEnumConstants( 6434 enumConstantName, 6435 enumType, 6436 null /* doesn't need invocation scope */, 6437 new ObjectVector(), 6438 alreadyUsedConstants, 6439 alreadyUsedConstantCount, 6440 false); 6441 } 6442 } findExceptionFromTryStatement( char[] typeName, ReferenceBinding exceptionType, ReferenceBinding receiverType, SourceTypeBinding invocationType, BlockScope scope, ObjectVector typesFound, boolean searchSuperClasses)6443 private void findExceptionFromTryStatement( 6444 char[] typeName, 6445 ReferenceBinding exceptionType, 6446 ReferenceBinding receiverType, 6447 SourceTypeBinding invocationType, 6448 BlockScope scope, 6449 ObjectVector typesFound, 6450 boolean searchSuperClasses) { 6451 6452 if (searchSuperClasses) { 6453 ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable(); 6454 if (TypeBinding.notEquals(exceptionType, javaLangThrowable)) { 6455 ReferenceBinding superClass = exceptionType.superclass(); 6456 while(superClass != null && TypeBinding.notEquals(superClass, javaLangThrowable)) { 6457 findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false); 6458 superClass = superClass.superclass(); 6459 } 6460 } 6461 } 6462 6463 if (typeName.length > exceptionType.sourceName.length) 6464 return; 6465 6466 if (isFailedMatch(typeName, exceptionType.sourceName)) 6467 return; 6468 6469 if (this.options.checkDeprecation && 6470 exceptionType.isViewedAsDeprecated() && 6471 !scope.isDefinedInSameUnit(exceptionType)) 6472 return; 6473 6474 if (this.options.checkVisibility) { 6475 if (invocationType != null) { 6476 if (receiverType != null) { 6477 if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return; 6478 } else { 6479 if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return; 6480 } 6481 } else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) { 6482 return; 6483 } 6484 } 6485 6486 if (isForbidden(exceptionType)) return; 6487 6488 for (int j = typesFound.size; --j >= 0;) { 6489 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 6490 6491 if (TypeBinding.equalsEquals(exceptionType, otherType)) 6492 return; 6493 6494 if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) { 6495 6496 if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType())) 6497 return; 6498 6499 if (otherType.enclosingType().isInterface()) 6500 if (exceptionType.enclosingType() 6501 .implementsInterface(otherType.enclosingType(), true)) 6502 return; 6503 6504 if (exceptionType.enclosingType().isInterface()) 6505 if (otherType.enclosingType() 6506 .implementsInterface(exceptionType.enclosingType(), true)) 6507 return; 6508 } 6509 } 6510 6511 typesFound.add(exceptionType); 6512 6513 char[] completionName = exceptionType.sourceName(); 6514 6515 boolean isQualified = false; 6516 6517 if(!this.insideQualifiedReference) { 6518 isQualified = true; 6519 6520 char[] memberPackageName = exceptionType.qualifiedPackageName(); 6521 char[] memberTypeName = exceptionType.sourceName(); 6522 char[] memberEnclosingTypeNames = null; 6523 6524 ReferenceBinding enclosingType = exceptionType.enclosingType(); 6525 if (enclosingType != null) { 6526 memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName(); 6527 } 6528 6529 Scope currentScope = scope; 6530 done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found 6531 6532 switch (currentScope.kind) { 6533 6534 case Scope.METHOD_SCOPE : 6535 case Scope.BLOCK_SCOPE : 6536 BlockScope blockScope = (BlockScope) currentScope; 6537 6538 for (int j = 0, length = blockScope.subscopeCount; j < length; j++) { 6539 6540 if (blockScope.subscopes[j] instanceof ClassScope) { 6541 SourceTypeBinding localType = 6542 ((ClassScope) blockScope.subscopes[j]).referenceContext.binding; 6543 6544 if (TypeBinding.equalsEquals(localType, exceptionType)) { 6545 isQualified = false; 6546 break done; 6547 } 6548 } 6549 } 6550 break; 6551 6552 case Scope.CLASS_SCOPE : 6553 SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding; 6554 ReferenceBinding[] memberTypes = type.memberTypes(); 6555 if (memberTypes != null) { 6556 for (int j = 0; j < memberTypes.length; j++) { 6557 if (TypeBinding.equalsEquals(memberTypes[j], exceptionType)) { 6558 isQualified = false; 6559 break done; 6560 } 6561 } 6562 } 6563 6564 6565 break; 6566 6567 case Scope.COMPILATION_UNIT_SCOPE : 6568 SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes; 6569 if (types != null) { 6570 for (int j = 0; j < types.length; j++) { 6571 if (TypeBinding.equalsEquals(types[j], exceptionType)) { 6572 isQualified = false; 6573 break done; 6574 } 6575 } 6576 } 6577 break done; 6578 } 6579 currentScope = currentScope.parent; 6580 } 6581 6582 if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) { 6583 if (memberPackageName == null || memberPackageName.length == 0) 6584 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 6585 return; // ignore types from the default package from outside it 6586 } else { 6587 isQualified = false; 6588 } 6589 6590 if (isQualified) { 6591 completionName = 6592 CharOperation.concat( 6593 memberPackageName, 6594 CharOperation.concat( 6595 memberEnclosingTypeNames, 6596 memberTypeName, 6597 '.'), 6598 '.'); 6599 } 6600 } 6601 6602 int relevance = computeBaseRelevance(); 6603 relevance += computeRelevanceForResolution(); 6604 relevance += computeRelevanceForInterestingProposal(exceptionType); 6605 relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName); 6606 relevance += computeRelevanceForExpectingType(exceptionType); 6607 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6608 if(!this.insideQualifiedReference) { 6609 relevance += computeRelevanceForQualification(isQualified); 6610 } 6611 relevance += computeRelevanceForClass(); 6612 relevance += computeRelevanceForException(); 6613 6614 this.noProposal = false; 6615 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 6616 createTypeProposal( 6617 exceptionType, 6618 exceptionType.qualifiedSourceName(), 6619 IAccessRule.K_ACCESSIBLE, 6620 completionName, 6621 relevance, 6622 null, 6623 null, 6624 null, 6625 false); 6626 } 6627 } findExceptionFromTryStatement( char[] typeName, ReferenceBinding receiverType, SourceTypeBinding invocationType, BlockScope scope, ObjectVector typesFound)6628 private void findExceptionFromTryStatement( 6629 char[] typeName, 6630 ReferenceBinding receiverType, 6631 SourceTypeBinding invocationType, 6632 BlockScope scope, 6633 ObjectVector typesFound) { 6634 6635 for (int i = 0; i <= this.expectedTypesPtr; i++) { 6636 ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i]; 6637 6638 findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true); 6639 } 6640 } findExplicitConstructors( char[] name, ReferenceBinding currentType, MethodScope scope, InvocationSite invocationSite)6641 private void findExplicitConstructors( 6642 char[] name, 6643 ReferenceBinding currentType, 6644 MethodScope scope, 6645 InvocationSite invocationSite) { 6646 6647 ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext; 6648 MethodBinding enclosingConstructor = constructorDeclaration.binding; 6649 6650 // No visibility checks can be performed without the scope & invocationSite 6651 MethodBinding[] methods = currentType.availableMethods(); 6652 if(methods != null) { 6653 next : for (int f = methods.length; --f >= 0;) { 6654 MethodBinding constructor = methods[f]; 6655 if (constructor != enclosingConstructor && constructor.isConstructor()) { 6656 6657 if (constructor.isSynthetic()) continue next; 6658 6659 if (this.options.checkDeprecation && 6660 constructor.isViewedAsDeprecated() && 6661 !scope.isDefinedInSameUnit(constructor.declaringClass)) 6662 continue next; 6663 6664 if (this.options.checkVisibility 6665 && !constructor.canBeSeenBy(invocationSite, scope)) continue next; 6666 6667 TypeBinding[] parameters = constructor.parameters; 6668 int paramLength = parameters.length; 6669 6670 char[][] parameterPackageNames = new char[paramLength][]; 6671 char[][] parameterTypeNames = new char[paramLength][]; 6672 for (int i = 0; i < paramLength; i++) { 6673 TypeBinding type = parameters[i]; 6674 parameterPackageNames[i] = type.qualifiedPackageName(); 6675 parameterTypeNames[i] = type.qualifiedSourceName(); 6676 } 6677 char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames); 6678 6679 char[] completion = CharOperation.NO_CHAR; 6680 if (this.source != null 6681 && this.source.length > this.endPosition 6682 && this.source[this.endPosition] == '(') 6683 completion = name; 6684 else 6685 completion = CharOperation.concat(name, new char[] { '(', ')' }); 6686 6687 int relevance = computeBaseRelevance(); 6688 relevance += computeRelevanceForResolution(); 6689 relevance += computeRelevanceForInterestingProposal(); 6690 relevance += computeRelevanceForCaseMatching(this.completionToken, name); 6691 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6692 6693 this.noProposal = false; 6694 if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 6695 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 6696 proposal.setBinding(constructor); 6697 proposal.setDeclarationSignature(getSignature(currentType)); 6698 proposal.setSignature(getSignature(constructor)); 6699 MethodBinding original = constructor.original(); 6700 if(original != constructor) { 6701 proposal.setOriginalSignature(getSignature(original)); 6702 } 6703 proposal.setDeclarationPackageName(currentType.qualifiedPackageName()); 6704 proposal.setDeclarationTypeName(currentType.qualifiedSourceName()); 6705 proposal.setParameterPackageNames(parameterPackageNames); 6706 proposal.setParameterTypeNames(parameterTypeNames); 6707 //proposal.setPackageName(null); 6708 //proposal.setTypeName(null); 6709 proposal.setName(name); 6710 proposal.setIsContructor(true); 6711 proposal.setCompletion(completion); 6712 proposal.setFlags(constructor.modifiers); 6713 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6714 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6715 proposal.setRelevance(relevance); 6716 if(parameterNames != null) proposal.setParameterNames(parameterNames); 6717 this.requestor.accept(proposal); 6718 if(DEBUG) { 6719 this.printDebug(proposal); 6720 } 6721 } 6722 } 6723 } 6724 } 6725 } 6726 // Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean) findFields( char[] fieldName, FieldBinding[] fields, Scope scope, ObjectVector fieldsFound, ObjectVector localsFound, boolean onlyStaticFields, ReferenceBinding receiverType, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean canBePrefixed, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)6727 private void findFields( 6728 char[] fieldName, 6729 FieldBinding[] fields, 6730 Scope scope, 6731 ObjectVector fieldsFound, 6732 ObjectVector localsFound, 6733 boolean onlyStaticFields, 6734 ReferenceBinding receiverType, 6735 InvocationSite invocationSite, 6736 Scope invocationScope, 6737 boolean implicitCall, 6738 boolean canBePrefixed, 6739 Binding[] missingElements, 6740 int[] missingElementsStarts, 6741 int[] missingElementsEnds, 6742 boolean missingElementsHaveProblems, 6743 char[] castedReceiver, 6744 int receiverStart, 6745 int receiverEnd) { 6746 6747 ObjectVector newFieldsFound = new ObjectVector(); 6748 // if the proposal is being asked inside a field's initialization, we'll record its id 6749 int fieldBeingCompletedId = -1; 6750 boolean isFieldBeingCompletedStatic = false; 6751 for (int f = fields.length; --f >=0;) { 6752 FieldBinding field = fields[f]; 6753 FieldDeclaration fieldDeclaration = field.sourceField(); 6754 // We maybe asking for a proposal inside this field's initialization. So record its id 6755 ASTNode astNode = this.parser.assistNode; 6756 if (fieldDeclaration != null && fieldDeclaration.initialization != null && astNode != null) { 6757 if (CharOperation.equals(this.fileName, field.declaringClass.getFileName()) && fieldDeclaration.initialization.sourceEnd > 0) { 6758 if (fieldDeclaration.initialization.sourceStart <= astNode.sourceStart && 6759 astNode.sourceEnd <= fieldDeclaration.initialization.sourceEnd) { 6760 // completion is inside a field initializer 6761 fieldBeingCompletedId = field.id; 6762 isFieldBeingCompletedStatic = field.isStatic(); 6763 break; 6764 } 6765 } else { // The sourceEnd may not yet be set 6766 CompletionNodeDetector detector = new CompletionNodeDetector(astNode, fieldDeclaration.initialization); 6767 if (detector.containsCompletionNode()) { // completion is inside a field initializer 6768 fieldBeingCompletedId = field.id; 6769 isFieldBeingCompletedStatic = field.isStatic(); 6770 break; 6771 } 6772 } 6773 } 6774 } 6775 // Inherited fields which are hidden by subclasses are filtered out 6776 // No visibility checks can be performed without the scope & invocationSite 6777 6778 int fieldLength = fieldName.length; 6779 next : for (int f = fields.length; --f >= 0;) { 6780 FieldBinding field = fields[f]; 6781 6782 // Content assist invoked inside some field's initialization. 6783 // bug 310427 and 325481 6784 if (fieldBeingCompletedId >= 0 && field.id >= fieldBeingCompletedId) { 6785 // Don't propose field which is being declared currently 6786 // Don't propose fields declared after the current field declaration statement 6787 // Though, if field is static or completion happens in Javadoc, then it can be still be proposed 6788 if (this.assistNodeInJavadoc == 0) { 6789 if (!field.isStatic()) { 6790 continue next; 6791 } else if (isFieldBeingCompletedStatic) { 6792 // static fields can't be proposed before they are actually declared if the 6793 // field currently being declared is also static 6794 continue next; 6795 } 6796 } 6797 } 6798 6799 if (field.isSynthetic()) continue next; 6800 6801 if (onlyStaticFields && !field.isStatic()) continue next; 6802 6803 if (fieldLength > field.name.length) continue next; 6804 6805 if (isFailedMatch(fieldName, field.name)) continue next; 6806 6807 if (this.options.checkDeprecation && 6808 field.isViewedAsDeprecated() && 6809 !scope.isDefinedInSameUnit(field.declaringClass)) 6810 continue next; 6811 6812 if (this.options.checkVisibility 6813 && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 6814 6815 // don't propose non constant fields or strings (1.6 or below) in case expression 6816 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346 6817 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342 6818 if (this.assistNodeIsInsideCase) { 6819 if (field.isFinal()) { 6820 if (this.assistNodeIsString){ 6821 if (field.type == null || field.type.id != TypeIds.T_JavaLangString) 6822 continue next; 6823 } else if (!(field.type instanceof BaseTypeBinding)) 6824 continue next; 6825 } else { 6826 continue next; // non-constants not allowed in case. 6827 } 6828 } 6829 6830 boolean prefixRequired = false; 6831 6832 for (int i = fieldsFound.size; --i >= 0;) { 6833 Object[] other = (Object[])fieldsFound.elementAt(i); 6834 FieldBinding otherField = (FieldBinding) other[0]; 6835 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 6836 if (field == otherField && TypeBinding.equalsEquals(receiverType, otherReceiverType)) 6837 continue next; 6838 if (CharOperation.equals(field.name, otherField.name, true)) { 6839 if (field.declaringClass.isSuperclassOf(otherField.declaringClass)) 6840 continue next; 6841 if (otherField.declaringClass.isInterface()) { 6842 if (TypeBinding.equalsEquals(field.declaringClass, scope.getJavaLangObject())) 6843 continue next; 6844 if (field.declaringClass.implementsInterface(otherField.declaringClass, true)) 6845 continue next; 6846 } 6847 if (field.declaringClass.isInterface()) 6848 if (otherField.declaringClass.implementsInterface(field.declaringClass, true)) 6849 continue next; 6850 if(canBePrefixed) { 6851 prefixRequired = true; 6852 } else { 6853 continue next; 6854 } 6855 } 6856 } 6857 6858 for (int l = localsFound.size; --l >= 0;) { 6859 LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l); 6860 6861 if (CharOperation.equals(field.name, local.name, true)) { 6862 SourceTypeBinding declarationType = scope.enclosingSourceType(); 6863 if (declarationType.isAnonymousType() && TypeBinding.notEquals(declarationType, invocationScope.enclosingSourceType())) { 6864 continue next; 6865 } 6866 if(canBePrefixed) { 6867 prefixRequired = true; 6868 } else { 6869 continue next; 6870 } 6871 break; 6872 } 6873 } 6874 6875 newFieldsFound.add(new Object[]{field, receiverType}); 6876 6877 char[] completion = field.name; 6878 6879 if(prefixRequired || this.options.forceImplicitQualification){ 6880 char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic()); 6881 completion = CharOperation.concat(prefix,completion,'.'); 6882 } 6883 6884 6885 if (castedReceiver != null) { 6886 completion = CharOperation.concat(castedReceiver, completion); 6887 } 6888 6889 // Special case for javadoc completion 6890 if (this.assistNodeInJavadoc > 0) { 6891 if (invocationSite instanceof CompletionOnJavadocFieldReference) { 6892 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 6893 if (fieldRef.receiver.isThis()) { 6894 if (fieldRef.completeInText()) { 6895 completion = CharOperation.concat(new char[] { '#' }, field.name); 6896 } 6897 } else if (fieldRef.completeInText()) { 6898 if (fieldRef.receiver instanceof JavadocSingleTypeReference) { 6899 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver; 6900 completion = CharOperation.concat(typeRef.token, field.name, '#'); 6901 } else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) { 6902 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver; 6903 completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#'); 6904 } 6905 } 6906 } 6907 } 6908 6909 int relevance = computeBaseRelevance(); 6910 relevance += computeRelevanceForResolution(); 6911 relevance += computeRelevanceForInterestingProposal(field); 6912 relevance += computeRelevanceForCaseMatching(fieldName, field.name); 6913 relevance += computeRelevanceForExpectingType(field.type); 6914 relevance += computeRelevanceForEnumConstant(field.type); 6915 relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic()); 6916 relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, field.isFinal()); 6917 relevance += computeRelevanceForQualification(prefixRequired); 6918 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 6919 if (onlyStaticFields && this.insideQualifiedReference) { 6920 relevance += computeRelevanceForInheritance(receiverType, field.declaringClass); 6921 } 6922 if (missingElements != null) { 6923 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 6924 } 6925 6926 this.noProposal = false; 6927 if (castedReceiver == null) { 6928 // Standard proposal 6929 if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 6930 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 6931 proposal.setBinding(field); 6932 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 6933 proposal.setSignature(getSignature(field.type)); 6934 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6935 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6936 proposal.setPackageName(field.type.qualifiedPackageName()); 6937 proposal.setTypeName(field.type.qualifiedSourceName()); 6938 proposal.setName(field.name); 6939 if (missingElements != null) { 6940 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 6941 for (int i = 0; i < missingElements.length; i++) { 6942 subProposals[i] = 6943 createRequiredTypeProposal( 6944 missingElements[i], 6945 missingElementsStarts[i], 6946 missingElementsEnds[i], 6947 relevance); 6948 } 6949 proposal.setRequiredProposals(subProposals); 6950 } 6951 proposal.setCompletion(completion); 6952 proposal.setFlags(field.modifiers); 6953 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 6954 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6955 proposal.setRelevance(relevance); 6956 this.requestor.accept(proposal); 6957 if(DEBUG) { 6958 this.printDebug(proposal); 6959 } 6960 } 6961 6962 // Javadoc completions 6963 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) { 6964 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 6965 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition); 6966 proposal.setBinding(field); 6967 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 6968 proposal.setSignature(getSignature(field.type)); 6969 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6970 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6971 proposal.setPackageName(field.type.qualifiedPackageName()); 6972 proposal.setTypeName(field.type.qualifiedSourceName()); 6973 proposal.setName(field.name); 6974 proposal.setCompletion(javadocCompletion); 6975 proposal.setFlags(field.modifiers); 6976 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 6977 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 6978 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6979 proposal.setRelevance(relevance+R_INLINE_TAG); 6980 this.requestor.accept(proposal); 6981 if(DEBUG) { 6982 this.printDebug(proposal); 6983 } 6984 // Javadoc value completion for static fields 6985 if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) { 6986 javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE); 6987 InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition); 6988 valueProposal.setDeclarationSignature(getSignature(field.declaringClass)); 6989 valueProposal.setSignature(getSignature(field.type)); 6990 valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 6991 valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 6992 valueProposal.setPackageName(field.type.qualifiedPackageName()); 6993 valueProposal.setTypeName(field.type.qualifiedSourceName()); 6994 valueProposal.setName(field.name); 6995 valueProposal.setCompletion(javadocCompletion); 6996 valueProposal.setFlags(field.modifiers); 6997 valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 6998 valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 6999 valueProposal.setRelevance(relevance+R_VALUE_TAG); 7000 this.requestor.accept(valueProposal); 7001 if(DEBUG) { 7002 this.printDebug(valueProposal); 7003 } 7004 } 7005 } 7006 } else { 7007 if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) { 7008 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition); 7009 proposal.setBinding(field); 7010 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 7011 proposal.setSignature(getSignature(field.type)); 7012 proposal.setReceiverSignature(getSignature(receiverType)); 7013 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 7014 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 7015 proposal.setPackageName(field.type.qualifiedPackageName()); 7016 proposal.setTypeName(field.type.qualifiedSourceName()); 7017 proposal.setName(field.name); 7018 if (missingElements != null) { 7019 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 7020 for (int i = 0; i < missingElements.length; i++) { 7021 subProposals[i] = 7022 createRequiredTypeProposal( 7023 missingElements[i], 7024 missingElementsStarts[i], 7025 missingElementsEnds[i], 7026 relevance); 7027 } 7028 proposal.setRequiredProposals(subProposals); 7029 } 7030 proposal.setCompletion(completion); 7031 proposal.setFlags(field.modifiers); 7032 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7033 proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset); 7034 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 7035 proposal.setRelevance(relevance); 7036 this.requestor.accept(proposal); 7037 if(DEBUG) { 7038 this.printDebug(proposal); 7039 } 7040 } 7041 } 7042 } 7043 7044 fieldsFound.addAll(newFieldsFound); 7045 } findFields( char[] fieldName, ReferenceBinding receiverType, Scope scope, ObjectVector fieldsFound, ObjectVector localsFound, boolean onlyStaticFields, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean canBePrefixed, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)7046 private void findFields( 7047 char[] fieldName, 7048 ReferenceBinding receiverType, 7049 Scope scope, 7050 ObjectVector fieldsFound, 7051 ObjectVector localsFound, 7052 boolean onlyStaticFields, 7053 InvocationSite invocationSite, 7054 Scope invocationScope, 7055 boolean implicitCall, 7056 boolean canBePrefixed, 7057 Binding[] missingElements, 7058 int[] missingElementsStarts, 7059 int[] missingElementsEnds, 7060 boolean missingElementsHaveProblems, 7061 char[] castedReceiver, 7062 int receiverStart, 7063 int receiverEnd) { 7064 7065 boolean notInJavadoc = this.assistNodeInJavadoc == 0; 7066 if (fieldName == null && notInJavadoc) 7067 return; 7068 7069 ReferenceBinding currentType = receiverType; 7070 ReferenceBinding[] interfacesToVisit = null; 7071 int nextPosition = 0; 7072 do { 7073 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 7074 if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) { 7075 if (interfacesToVisit == null) { 7076 interfacesToVisit = itsInterfaces; 7077 nextPosition = interfacesToVisit.length; 7078 } else { 7079 int itsLength = itsInterfaces.length; 7080 if (nextPosition + itsLength >= interfacesToVisit.length) 7081 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 7082 nextInterface : for (int a = 0; a < itsLength; a++) { 7083 ReferenceBinding next = itsInterfaces[a]; 7084 for (int b = 0; b < nextPosition; b++) 7085 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 7086 interfacesToVisit[nextPosition++] = next; 7087 } 7088 } 7089 } 7090 7091 FieldBinding[] fields = currentType.availableFields(); 7092 if(fields != null && fields.length > 0) { 7093 findFields( 7094 fieldName, 7095 fields, 7096 scope, 7097 fieldsFound, 7098 localsFound, 7099 onlyStaticFields, 7100 receiverType, 7101 invocationSite, 7102 invocationScope, 7103 implicitCall, 7104 canBePrefixed, 7105 missingElements, 7106 missingElementsStarts, 7107 missingElementsEnds, 7108 missingElementsHaveProblems, 7109 castedReceiver, 7110 receiverStart, 7111 receiverEnd); 7112 } 7113 currentType = currentType.superclass(); 7114 } while (notInJavadoc && currentType != null); 7115 7116 if (notInJavadoc && interfacesToVisit != null) { 7117 for (int i = 0; i < nextPosition; i++) { 7118 ReferenceBinding anInterface = interfacesToVisit[i]; 7119 FieldBinding[] fields = anInterface.availableFields(); 7120 if(fields != null) { 7121 findFields( 7122 fieldName, 7123 fields, 7124 scope, 7125 fieldsFound, 7126 localsFound, 7127 onlyStaticFields, 7128 receiverType, 7129 invocationSite, 7130 invocationScope, 7131 implicitCall, 7132 canBePrefixed, 7133 missingElements, 7134 missingElementsStarts, 7135 missingElementsEnds, 7136 missingElementsHaveProblems, 7137 castedReceiver, 7138 receiverStart, 7139 receiverEnd); 7140 } 7141 7142 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 7143 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 7144 int itsLength = itsInterfaces.length; 7145 if (nextPosition + itsLength >= interfacesToVisit.length) 7146 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 7147 nextInterface : for (int a = 0; a < itsLength; a++) { 7148 ReferenceBinding next = itsInterfaces[a]; 7149 for (int b = 0; b < nextPosition; b++) 7150 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 7151 interfacesToVisit[nextPosition++] = next; 7152 } 7153 } 7154 } 7155 } 7156 } 7157 findFieldsAndMethods( char[] token, TypeBinding receiverType, Scope scope, ObjectVector fieldsFound, ObjectVector methodsFound, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean superCall, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)7158 protected void findFieldsAndMethods( 7159 char[] token, 7160 TypeBinding receiverType, 7161 Scope scope, 7162 ObjectVector fieldsFound, 7163 ObjectVector methodsFound, 7164 InvocationSite invocationSite, 7165 Scope invocationScope, 7166 boolean implicitCall, 7167 boolean superCall, 7168 Binding[] missingElements, 7169 int[] missingElementsStarts, 7170 int[] missingElementsEnds, 7171 boolean missingElementsHaveProblems, 7172 char[] castedReceiver, 7173 int receiverStart, 7174 int receiverEnd) { 7175 7176 if (token == null) 7177 return; 7178 7179 if (receiverType.isBaseType()) 7180 return; // nothing else is possible with base types 7181 7182 boolean proposeField = 7183 castedReceiver == null ? 7184 !this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) : 7185 !this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ; 7186 boolean proposeMethod = 7187 castedReceiver == null ? 7188 !this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) : 7189 !this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null); 7190 7191 if (receiverType.isArrayType()) { 7192 if (proposeField 7193 && token.length <= lengthField.length 7194 && CharOperation.prefixEquals(token, lengthField, false /* ignore case */ 7195 )) { 7196 7197 int relevance = computeBaseRelevance(); 7198 relevance += computeRelevanceForResolution(); 7199 relevance += computeRelevanceForInterestingProposal(); 7200 relevance += computeRelevanceForCaseMatching(token,lengthField); 7201 relevance += computeRelevanceForExpectingType(TypeBinding.INT); 7202 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field 7203 if (missingElements != null) { 7204 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 7205 } 7206 this.noProposal = false; 7207 if (castedReceiver == null) { 7208 if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) { 7209 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 7210 proposal.setDeclarationSignature(getSignature(receiverType)); 7211 proposal.setSignature(INT_SIGNATURE); 7212 proposal.setTypeName(INT); 7213 proposal.setName(lengthField); 7214 if (missingElements != null) { 7215 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 7216 for (int i = 0; i < missingElements.length; i++) { 7217 subProposals[i] = 7218 createRequiredTypeProposal( 7219 missingElements[i], 7220 missingElementsStarts[i], 7221 missingElementsEnds[i], 7222 relevance); 7223 } 7224 proposal.setRequiredProposals(subProposals); 7225 } 7226 proposal.setCompletion(lengthField); 7227 proposal.setFlags(Flags.AccPublic); 7228 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7229 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 7230 proposal.setRelevance(relevance); 7231 this.requestor.accept(proposal); 7232 if(DEBUG) { 7233 this.printDebug(proposal); 7234 } 7235 } 7236 } else { 7237 char[] completion = CharOperation.concat(castedReceiver, lengthField); 7238 7239 if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) { 7240 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition); 7241 proposal.setDeclarationSignature(getSignature(receiverType)); 7242 proposal.setSignature(INT_SIGNATURE); 7243 proposal.setReceiverSignature(getSignature(receiverType)); 7244 proposal.setTypeName(INT); 7245 proposal.setName(lengthField); 7246 if (missingElements != null) { 7247 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 7248 for (int i = 0; i < missingElements.length; i++) { 7249 subProposals[i] = 7250 createRequiredTypeProposal( 7251 missingElements[i], 7252 missingElementsStarts[i], 7253 missingElementsEnds[i], 7254 relevance); 7255 } 7256 proposal.setRequiredProposals(subProposals); 7257 } 7258 proposal.setCompletion(completion); 7259 proposal.setFlags(Flags.AccPublic); 7260 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7261 proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset); 7262 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 7263 proposal.setRelevance(relevance); 7264 this.requestor.accept(proposal); 7265 if(DEBUG) { 7266 this.printDebug(proposal); 7267 } 7268 } 7269 } 7270 } 7271 if (proposeMethod 7272 && token.length <= cloneMethod.length 7273 && CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */) 7274 ) { 7275 ReferenceBinding objectRef = scope.getJavaLangObject(); 7276 7277 int relevance = computeBaseRelevance(); 7278 relevance += computeRelevanceForResolution(); 7279 relevance += computeRelevanceForInterestingProposal(); 7280 relevance += computeRelevanceForCaseMatching(token, cloneMethod); 7281 relevance += computeRelevanceForExpectingType(objectRef); 7282 relevance += computeRelevanceForStatic(false, false); 7283 relevance += computeRelevanceForQualification(false); 7284 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method 7285 if (missingElements != null) { 7286 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 7287 } 7288 char[] completion; 7289 if (this.source != null 7290 && this.source.length > this.endPosition 7291 && this.source[this.endPosition] == '(') { 7292 completion = cloneMethod; 7293 } else { 7294 completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' }); 7295 } 7296 7297 if (castedReceiver != null) { 7298 completion = CharOperation.concat(castedReceiver, completion); 7299 } 7300 7301 this.noProposal = false; 7302 if (castedReceiver == null) { 7303 if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) { 7304 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 7305 proposal.setDeclarationSignature(getSignature(receiverType)); 7306 proposal.setSignature( 7307 this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ? 7308 createMethodSignature( 7309 CharOperation.NO_CHAR_CHAR, 7310 CharOperation.NO_CHAR_CHAR, 7311 getSignature(receiverType)) : 7312 createMethodSignature( 7313 CharOperation.NO_CHAR_CHAR, 7314 CharOperation.NO_CHAR_CHAR, 7315 CharOperation.concatWith(JAVA_LANG, '.'), 7316 OBJECT)); 7317 //proposal.setOriginalSignature(null); 7318 //proposal.setDeclarationPackageName(null); 7319 //proposal.setDeclarationTypeName(null); 7320 //proposal.setParameterPackageNames(null); 7321 //proposal.setParameterTypeNames(null); 7322 proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.')); 7323 proposal.setTypeName(OBJECT); 7324 proposal.setName(cloneMethod); 7325 if (missingElements != null) { 7326 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 7327 for (int i = 0; i < missingElements.length; i++) { 7328 subProposals[i] = 7329 createRequiredTypeProposal( 7330 missingElements[i], 7331 missingElementsStarts[i], 7332 missingElementsEnds[i], 7333 relevance); 7334 } 7335 proposal.setRequiredProposals(subProposals); 7336 } 7337 proposal.setCompletion(completion); 7338 proposal.setFlags(Flags.AccPublic); 7339 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7340 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 7341 proposal.setRelevance(relevance); 7342 this.requestor.accept(proposal); 7343 if(DEBUG) { 7344 this.printDebug(proposal); 7345 } 7346 } 7347 methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef}); 7348 } else { 7349 if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) { 7350 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition); 7351 proposal.setDeclarationSignature(getSignature(receiverType)); 7352 proposal.setSignature( 7353 this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ? 7354 createMethodSignature( 7355 CharOperation.NO_CHAR_CHAR, 7356 CharOperation.NO_CHAR_CHAR, 7357 getSignature(receiverType)) : 7358 createMethodSignature( 7359 CharOperation.NO_CHAR_CHAR, 7360 CharOperation.NO_CHAR_CHAR, 7361 CharOperation.concatWith(JAVA_LANG, '.'), 7362 OBJECT)); 7363 proposal.setReceiverSignature(getSignature(receiverType)); 7364 proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.')); 7365 proposal.setTypeName(OBJECT); 7366 proposal.setName(cloneMethod); 7367 if (missingElements != null) { 7368 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 7369 for (int i = 0; i < missingElements.length; i++) { 7370 subProposals[i] = 7371 createRequiredTypeProposal( 7372 missingElements[i], 7373 missingElementsStarts[i], 7374 missingElementsEnds[i], 7375 relevance); 7376 } 7377 proposal.setRequiredProposals(subProposals); 7378 } 7379 proposal.setCompletion(completion); 7380 proposal.setFlags(Flags.AccPublic); 7381 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 7382 proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset); 7383 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 7384 proposal.setRelevance(relevance); 7385 this.requestor.accept(proposal); 7386 if(DEBUG) { 7387 this.printDebug(proposal); 7388 } 7389 } 7390 } 7391 } 7392 7393 receiverType = scope.getJavaLangObject(); 7394 } 7395 7396 checkCancel(); 7397 7398 if(proposeField) { 7399 findFields( 7400 token, 7401 (ReferenceBinding) receiverType, 7402 scope, 7403 fieldsFound, 7404 new ObjectVector(), 7405 false, 7406 invocationSite, 7407 invocationScope, 7408 implicitCall, 7409 false, 7410 missingElements, 7411 missingElementsStarts, 7412 missingElementsEnds, 7413 missingElementsHaveProblems, 7414 castedReceiver, 7415 receiverStart, 7416 receiverEnd); 7417 } 7418 7419 if(proposeMethod) { 7420 findMethods( 7421 token, 7422 null, 7423 null, 7424 (ReferenceBinding) receiverType, 7425 scope, 7426 methodsFound, 7427 false, 7428 false, 7429 invocationSite, 7430 invocationScope, 7431 implicitCall, 7432 superCall, 7433 false, 7434 missingElements, 7435 missingElementsStarts, 7436 missingElementsEnds, 7437 missingElementsHaveProblems, 7438 castedReceiver, 7439 receiverStart, 7440 receiverEnd); 7441 } 7442 } 7443 findFieldsAndMethodsFromAnotherReceiver( char[] token, TypeReference receiverType, Scope scope, ObjectVector fieldsFound, ObjectVector methodsFound, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean superCall, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[][] receiverName, int receiverStart, int receiverEnd)7444 protected void findFieldsAndMethodsFromAnotherReceiver( 7445 char[] token, 7446 TypeReference receiverType, 7447 Scope scope, 7448 ObjectVector fieldsFound, 7449 ObjectVector methodsFound, 7450 InvocationSite invocationSite, 7451 Scope invocationScope, 7452 boolean implicitCall, 7453 boolean superCall, 7454 Binding[] missingElements, 7455 int[] missingElementsStarts, 7456 int[] missingElementsEnds, 7457 boolean missingElementsHaveProblems, 7458 char[][] receiverName, 7459 int receiverStart, 7460 int receiverEnd) { 7461 7462 if (receiverType.resolvedType == null) return; 7463 7464 TypeBinding receiverTypeBinding = receiverType.resolvedType; 7465 char[] castedReceiver = null; 7466 7467 char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.'); 7468 if(this.source != null) { 7469 int memberRefStart = this.startPosition; 7470 7471 char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd); 7472 char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart); 7473 7474 castedReceiver = 7475 CharOperation.concat( 7476 CharOperation.concat( 7477 '(', 7478 CharOperation.concat( 7479 CharOperation.concat('(', castedTypeChars, ')'), 7480 receiverChars), 7481 ')'), 7482 dotChars); 7483 } else { 7484 castedReceiver = 7485 CharOperation.concat( 7486 CharOperation.concat( 7487 '(', 7488 CharOperation.concat( 7489 CharOperation.concat('(', castedTypeChars, ')'), 7490 CharOperation.concatWith(receiverName, '.')), 7491 ')'), 7492 DOT); 7493 } 7494 7495 if (castedReceiver == null) return; 7496 7497 int oldStartPosition = this.startPosition; 7498 this.startPosition = receiverStart; 7499 7500 findFieldsAndMethods( 7501 token, 7502 receiverTypeBinding, 7503 scope, 7504 fieldsFound, 7505 methodsFound, 7506 invocationSite, 7507 invocationScope, 7508 implicitCall, 7509 superCall, 7510 missingElements, 7511 missingElementsStarts, 7512 missingElementsEnds, 7513 missingElementsHaveProblems, 7514 castedReceiver, 7515 receiverStart, 7516 receiverEnd); 7517 7518 this.startPosition = oldStartPosition; 7519 } findFieldsAndMethodsFromCastedReceiver( ASTNode enclosingNode, Binding qualifiedBinding, Scope scope, ObjectVector fieldsFound, ObjectVector methodsFound, InvocationSite invocationSite, Scope invocationScope, Expression receiver)7520 private void findFieldsAndMethodsFromCastedReceiver( 7521 ASTNode enclosingNode, 7522 Binding qualifiedBinding, 7523 Scope scope, 7524 ObjectVector fieldsFound, 7525 ObjectVector methodsFound, 7526 InvocationSite invocationSite, 7527 Scope invocationScope, 7528 Expression receiver) { 7529 7530 if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return; 7531 7532 IfStatement ifStatement = (IfStatement)enclosingNode; 7533 while (true) { 7534 if (!(ifStatement.condition instanceof InstanceOfExpression)) return; 7535 7536 InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition; 7537 7538 TypeReference instanceOfType = instanceOfExpression.type; 7539 7540 if (instanceOfType.resolvedType == null) return; 7541 7542 boolean findFromAnotherReceiver = false; 7543 7544 char[][] receiverName = null; 7545 int receiverStart = -1; 7546 int receiverEnd = -1; 7547 7548 if (receiver instanceof QualifiedNameReference) { 7549 QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver; 7550 7551 receiverName = qualifiedNameReference.tokens; 7552 7553 if (receiverName.length != 1) return; 7554 7555 receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32); 7556 receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1; 7557 7558 // if (local instanceof X) local.| 7559 // if (field instanceof X) field.| 7560 if (instanceOfExpression.expression instanceof SingleNameReference && 7561 ((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding && 7562 (qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) { 7563 findFromAnotherReceiver = true; 7564 } 7565 7566 // if (this.field instanceof X) field.| 7567 if (instanceOfExpression.expression instanceof FieldReference) { 7568 FieldReference fieldReference = (FieldReference)instanceOfExpression.expression; 7569 7570 if (fieldReference.receiver instanceof ThisReference && 7571 qualifiedBinding instanceof FieldBinding && 7572 fieldReference.binding == qualifiedBinding) { 7573 findFromAnotherReceiver = true; 7574 } 7575 } 7576 } else if (receiver instanceof FieldReference) { 7577 FieldReference fieldReference1 = (FieldReference) receiver; 7578 7579 receiverStart = fieldReference1.sourceStart; 7580 receiverEnd = fieldReference1.sourceEnd + 1; 7581 7582 if (fieldReference1.receiver instanceof ThisReference) { 7583 7584 receiverName = new char[][] {THIS, fieldReference1.token}; 7585 7586 // if (field instanceof X) this.field.| 7587 if (instanceOfExpression.expression instanceof SingleNameReference && 7588 ((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) { 7589 findFromAnotherReceiver = true; 7590 } 7591 7592 // if (this.field instanceof X) this.field.| 7593 if (instanceOfExpression.expression instanceof FieldReference) { 7594 FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression; 7595 7596 if (fieldReference2.receiver instanceof ThisReference && 7597 fieldReference2.binding == fieldReference1.binding) { 7598 findFromAnotherReceiver = true; 7599 } 7600 } 7601 } 7602 } 7603 7604 if (findFromAnotherReceiver) { 7605 TypeBinding receiverTypeBinding = instanceOfType.resolvedType; 7606 char[] castedReceiver = null; 7607 7608 char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.'); 7609 if(this.source != null) { 7610 int memberRefStart = this.startPosition; 7611 7612 char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd); 7613 char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart); 7614 7615 castedReceiver = 7616 CharOperation.concat( 7617 CharOperation.concat( 7618 '(', 7619 CharOperation.concat( 7620 CharOperation.concat('(', castedTypeChars, ')'), 7621 receiverChars), 7622 ')'), 7623 dotChars); 7624 } else { 7625 castedReceiver = 7626 CharOperation.concat( 7627 CharOperation.concat( 7628 '(', 7629 CharOperation.concat( 7630 CharOperation.concat('(', castedTypeChars, ')'), 7631 CharOperation.concatWith(receiverName, '.')), 7632 ')'), 7633 DOT); 7634 } 7635 7636 if (castedReceiver == null) return; 7637 7638 int oldStartPosition = this.startPosition; 7639 this.startPosition = receiverStart; 7640 7641 findFieldsAndMethods( 7642 this.completionToken, 7643 receiverTypeBinding, 7644 scope, 7645 fieldsFound, 7646 methodsFound, 7647 invocationSite, 7648 invocationScope, 7649 false, 7650 false, 7651 null, 7652 null, 7653 null, 7654 false, 7655 castedReceiver, 7656 receiverStart, 7657 receiverEnd); 7658 7659 this.startPosition = oldStartPosition; 7660 } 7661 // traverse the enclosing node to find the instanceof expression corresponding 7662 // to the completion node (if any) 7663 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=304006 7664 if (ifStatement.thenStatement instanceof IfStatement) { 7665 ifStatement = (IfStatement) ifStatement.thenStatement; 7666 } else { 7667 break; 7668 } 7669 } 7670 } findFieldsAndMethodsFromFavorites( char[] token, Scope scope, InvocationSite invocationSite, Scope invocationScope, ObjectVector localsFound, ObjectVector fieldsFound, ObjectVector methodsFound)7671 private void findFieldsAndMethodsFromFavorites( 7672 char[] token, 7673 Scope scope, 7674 InvocationSite invocationSite, 7675 Scope invocationScope, 7676 ObjectVector localsFound, 7677 ObjectVector fieldsFound, 7678 ObjectVector methodsFound) { 7679 7680 ObjectVector methodsFoundFromFavorites = new ObjectVector(); 7681 7682 ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope); 7683 7684 if (favoriteBindings != null && favoriteBindings.length > 0) { 7685 for (int i = 0; i < favoriteBindings.length; i++) { 7686 ImportBinding favoriteBinding = favoriteBindings[i]; 7687 switch (favoriteBinding.resolvedImport.kind()) { 7688 case Binding.FIELD: 7689 FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport; 7690 findFieldsFromFavorites( 7691 token, 7692 new FieldBinding[]{fieldBinding}, 7693 scope, 7694 fieldsFound, 7695 localsFound, 7696 fieldBinding.declaringClass, 7697 invocationSite, 7698 invocationScope); 7699 break; 7700 case Binding.METHOD: 7701 MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport; 7702 MethodBinding[] methods = methodBinding.declaringClass.availableMethods(); 7703 long range; 7704 if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) { 7705 int start = (int) range, end = (int) (range >> 32); 7706 int length = end - start + 1; 7707 System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length); 7708 } else { 7709 methods = Binding.NO_METHODS; 7710 } 7711 findLocalMethodsFromFavorites( 7712 token, 7713 methods, 7714 scope, 7715 methodsFound, 7716 methodsFoundFromFavorites, 7717 methodBinding.declaringClass, 7718 invocationSite, 7719 invocationScope); 7720 break; 7721 case Binding.TYPE: 7722 ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport; 7723 if(favoriteBinding.onDemand) { 7724 findFieldsFromFavorites( 7725 token, 7726 referenceBinding.availableFields(), 7727 scope, 7728 fieldsFound, 7729 localsFound, 7730 referenceBinding, 7731 invocationSite, 7732 invocationScope); 7733 7734 findLocalMethodsFromFavorites( 7735 token, 7736 referenceBinding.availableMethods(), 7737 scope, 7738 methodsFound, 7739 methodsFoundFromFavorites, 7740 referenceBinding, 7741 invocationSite, 7742 invocationScope); 7743 } 7744 break; 7745 } 7746 } 7747 } 7748 7749 methodsFound.addAll(methodsFoundFromFavorites); 7750 } 7751 findFieldsAndMethodsFromMissingFieldType( char[] token, Scope scope, InvocationSite invocationSite, boolean insideTypeAnnotation)7752 private boolean findFieldsAndMethodsFromMissingFieldType( 7753 char[] token, 7754 Scope scope, 7755 InvocationSite invocationSite, 7756 boolean insideTypeAnnotation) { 7757 7758 boolean foundSomeFields = false; 7759 7760 Scope currentScope = scope; 7761 7762 done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 7763 7764 switch (currentScope.kind) { 7765 7766 case Scope.CLASS_SCOPE : 7767 ClassScope classScope = (ClassScope) currentScope; 7768 if(!insideTypeAnnotation) { 7769 7770 FieldDeclaration[] fields = classScope.referenceContext.fields; 7771 7772 int fieldsCount = fields == null ? 0 : fields.length; 7773 for (int i = 0; i < fieldsCount; i++) { 7774 FieldDeclaration fieldDeclaration = fields[i]; 7775 if (CharOperation.equals(fieldDeclaration.name, token)) { 7776 FieldBinding fieldBinding = fieldDeclaration.binding; 7777 if (fieldBinding == null || fieldBinding.type == null || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) { 7778 foundSomeFields = true; 7779 findFieldsAndMethodsFromMissingType( 7780 fieldDeclaration.type, 7781 currentScope, 7782 invocationSite, 7783 scope); 7784 } 7785 break done; 7786 } 7787 } 7788 } 7789 insideTypeAnnotation = false; 7790 break; 7791 case Scope.COMPILATION_UNIT_SCOPE : 7792 break done; 7793 } 7794 currentScope = currentScope.parent; 7795 } 7796 return foundSomeFields; 7797 } 7798 findFieldsAndMethodsFromMissingReturnType( char[] token, TypeBinding[] arguments, Scope scope, InvocationSite invocationSite, boolean insideTypeAnnotation)7799 private void findFieldsAndMethodsFromMissingReturnType( 7800 char[] token, 7801 TypeBinding[] arguments, 7802 Scope scope, 7803 InvocationSite invocationSite, 7804 boolean insideTypeAnnotation) { 7805 7806 Scope currentScope = scope; 7807 7808 done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 7809 7810 switch (currentScope.kind) { 7811 7812 case Scope.CLASS_SCOPE : 7813 ClassScope classScope = (ClassScope) currentScope; 7814 if(!insideTypeAnnotation) { 7815 7816 AbstractMethodDeclaration[] methods = classScope.referenceContext.methods; 7817 7818 int methodsCount = methods == null ? 0 : methods.length; 7819 for (int i = 0; i < methodsCount; i++) { 7820 AbstractMethodDeclaration methodDeclaration = methods[i]; 7821 if (methodDeclaration instanceof MethodDeclaration && 7822 CharOperation.equals(methodDeclaration.selector, token)) { 7823 MethodDeclaration method = (MethodDeclaration) methodDeclaration; 7824 MethodBinding methodBinding = method.binding; 7825 if (methodBinding == null || methodBinding.returnType == null || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) { 7826 Argument[] parameters = method.arguments; 7827 int parametersLength = parameters == null ? 0 : parameters.length; 7828 int argumentsLength = arguments == null ? 0 : arguments.length; 7829 7830 if (parametersLength == 0) { 7831 if (argumentsLength == 0) { 7832 findFieldsAndMethodsFromMissingType( 7833 method.returnType, 7834 currentScope, 7835 invocationSite, 7836 scope); 7837 break done; 7838 } 7839 } else { 7840 TypeBinding[] parametersBindings; 7841 if (methodBinding == null) { // since no binding, extra types from type references 7842 parametersBindings = new TypeBinding[parametersLength]; 7843 for (int j = 0; j < parametersLength; j++) { 7844 TypeBinding parameterType = parameters[j].type.resolvedType; 7845 if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) { 7846 parameterType = parameterType.closestMatch(); 7847 } 7848 parametersBindings[j] = parameterType; 7849 } 7850 } else { 7851 parametersBindings = methodBinding.parameters; 7852 } 7853 if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) { 7854 findFieldsAndMethodsFromMissingType( 7855 method.returnType, 7856 currentScope, 7857 invocationSite, 7858 scope); 7859 break done; 7860 } 7861 } 7862 } 7863 7864 } 7865 } 7866 } 7867 insideTypeAnnotation = false; 7868 break; 7869 case Scope.COMPILATION_UNIT_SCOPE : 7870 break done; 7871 } 7872 currentScope = currentScope.parent; 7873 } 7874 } 7875 findFieldsAndMethodsFromMissingType( TypeReference typeRef, final Scope scope, final InvocationSite invocationSite, final Scope invocationScope)7876 private void findFieldsAndMethodsFromMissingType( 7877 TypeReference typeRef, 7878 final Scope scope, 7879 final InvocationSite invocationSite, 7880 final Scope invocationScope) { 7881 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 7882 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 7883 new MissingTypesGuesser.GuessedTypeRequestor() { 7884 @Override 7885 public void accept( 7886 TypeBinding guessedType, 7887 Binding[] missingElements, 7888 int[] missingElementsStarts, 7889 int[] missingElementsEnds, 7890 boolean hasProblems) { 7891 findFieldsAndMethods( 7892 CompletionEngine.this.completionToken, 7893 guessedType, 7894 scope, 7895 new ObjectVector(), 7896 new ObjectVector(), 7897 invocationSite, 7898 invocationScope, 7899 false, 7900 false, 7901 missingElements, 7902 missingElementsStarts, 7903 missingElementsEnds, 7904 hasProblems, 7905 null, 7906 -1, 7907 -1); 7908 7909 } 7910 }; 7911 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 7912 } 7913 findFieldsAndMethodsFromStaticImports( char[] token, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean exactMatch, boolean insideAnnotationAttribute, ObjectVector localsFound, ObjectVector fieldsFound, ObjectVector methodsFound, boolean proposeField, boolean proposeMethod)7914 private void findFieldsAndMethodsFromStaticImports( 7915 char[] token, 7916 Scope scope, 7917 InvocationSite invocationSite, 7918 Scope invocationScope, 7919 boolean exactMatch, 7920 boolean insideAnnotationAttribute, 7921 ObjectVector localsFound, 7922 ObjectVector fieldsFound, 7923 ObjectVector methodsFound, 7924 boolean proposeField, 7925 boolean proposeMethod) { 7926 // search in static import 7927 ImportBinding[] importBindings = scope.compilationUnitScope().imports; 7928 for (int i = 0; i < importBindings.length; i++) { 7929 ImportBinding importBinding = importBindings[i]; 7930 if(importBinding.isValidBinding() && importBinding.isStatic()) { 7931 Binding binding = importBinding.resolvedImport; 7932 if(binding != null && binding.isValidBinding()) { 7933 if(importBinding.onDemand) { 7934 if((binding.kind() & Binding.TYPE) != 0) { 7935 if(proposeField) { 7936 findFields( 7937 token, 7938 (ReferenceBinding)binding, 7939 scope, 7940 fieldsFound, 7941 localsFound, 7942 true, 7943 invocationSite, 7944 invocationScope, 7945 true, 7946 false, 7947 null, 7948 null, 7949 null, 7950 false, 7951 null, 7952 -1, 7953 -1); 7954 } 7955 if(proposeMethod && !insideAnnotationAttribute) { 7956 findMethods( 7957 token, 7958 null, 7959 null, 7960 (ReferenceBinding)binding, 7961 scope, 7962 methodsFound, 7963 true, 7964 exactMatch, 7965 invocationSite, 7966 invocationScope, 7967 true, 7968 false, 7969 false, 7970 null, 7971 null, 7972 null, 7973 false, 7974 null, 7975 -1, 7976 -1); 7977 } 7978 } 7979 } else { 7980 if ((binding.kind() & Binding.FIELD) != 0) { 7981 if(proposeField) { 7982 findFields( 7983 token, 7984 new FieldBinding[]{(FieldBinding)binding}, 7985 scope, 7986 fieldsFound, 7987 localsFound, 7988 true, 7989 ((FieldBinding)binding).declaringClass, 7990 invocationSite, 7991 invocationScope, 7992 true, 7993 false, 7994 null, 7995 null, 7996 null, 7997 false, 7998 null, 7999 -1, 8000 -1); 8001 } 8002 } else if ((binding.kind() & Binding.METHOD) != 0) { 8003 if(proposeMethod && !insideAnnotationAttribute) { 8004 MethodBinding methodBinding = (MethodBinding)binding; 8005 if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) || 8006 !exactMatch && CharOperation.prefixEquals(token, methodBinding.selector, false) || 8007 (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, methodBinding.selector))) { 8008 findLocalMethodsFromStaticImports( 8009 token, 8010 methodBinding.declaringClass.getMethods(methodBinding.selector), 8011 scope, 8012 exactMatch, 8013 methodsFound, 8014 methodBinding.declaringClass, 8015 invocationSite); 8016 } 8017 } 8018 } 8019 } 8020 } 8021 } 8022 } 8023 } 8024 findFieldsFromFavorites( char[] fieldName, FieldBinding[] fields, Scope scope, ObjectVector fieldsFound, ObjectVector localsFound, ReferenceBinding receiverType, InvocationSite invocationSite, Scope invocationScope)8025 private void findFieldsFromFavorites( 8026 char[] fieldName, 8027 FieldBinding[] fields, 8028 Scope scope, 8029 ObjectVector fieldsFound, 8030 ObjectVector localsFound, 8031 ReferenceBinding receiverType, 8032 InvocationSite invocationSite, 8033 Scope invocationScope) { 8034 8035 char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.'); 8036 8037 int fieldLength = fieldName.length; 8038 next : for (int f = fields.length; --f >= 0;) { 8039 FieldBinding field = fields[f]; 8040 8041 if (field.isSynthetic()) continue next; 8042 8043 // only static fields must be proposed 8044 if (!field.isStatic()) continue next; 8045 8046 if (fieldLength > field.name.length) continue next; 8047 8048 if (isFailedMatch(fieldName, field.name)) continue next; 8049 8050 if (this.options.checkDeprecation && 8051 field.isViewedAsDeprecated() && 8052 !scope.isDefinedInSameUnit(field.declaringClass)) 8053 continue next; 8054 8055 if (this.options.checkVisibility 8056 && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 8057 8058 for (int i = fieldsFound.size; --i >= 0;) { 8059 Object[] other = (Object[])fieldsFound.elementAt(i); 8060 FieldBinding otherField = (FieldBinding) other[0]; 8061 8062 if (field == otherField) continue next; 8063 } 8064 8065 fieldsFound.add(new Object[]{field, receiverType}); 8066 8067 int relevance = computeBaseRelevance(); 8068 relevance += computeRelevanceForResolution(); 8069 relevance += computeRelevanceForInterestingProposal(field); 8070 relevance += computeRelevanceForCaseMatching(fieldName, field.name); 8071 relevance += computeRelevanceForExpectingType(field.type); 8072 relevance += computeRelevanceForEnumConstant(field.type); 8073 relevance += computeRelevanceForStatic(true, true); 8074 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8075 8076 CompilationUnitDeclaration cu = this.unitScope.referenceContext; 8077 int importStart = cu.types[0].declarationSourceStart; 8078 int importEnd = importStart; 8079 8080 this.noProposal = false; 8081 8082 if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 || 8083 !this.options.suggestStaticImport) { 8084 if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) { 8085 char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.'); 8086 8087 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 8088 proposal.setBinding(field); 8089 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 8090 proposal.setSignature(getSignature(field.type)); 8091 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 8092 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 8093 proposal.setPackageName(field.type.qualifiedPackageName()); 8094 proposal.setTypeName(field.type.qualifiedSourceName()); 8095 proposal.setName(field.name); 8096 proposal.setCompletion(completion); 8097 proposal.setFlags(field.modifiers); 8098 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8099 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8100 proposal.setRelevance(relevance); 8101 8102 char[] typeImportCompletion = createImportCharArray(typeName, false, false); 8103 8104 InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition); 8105 typeImportProposal.nameLookup = this.nameEnvironment.nameLookup; 8106 typeImportProposal.completionEngine = this; 8107 char[] packageName = receiverType.qualifiedPackageName(); 8108 typeImportProposal.setDeclarationSignature(packageName); 8109 typeImportProposal.setSignature(getSignature(receiverType)); 8110 typeImportProposal.setPackageName(packageName); 8111 typeImportProposal.setTypeName(receiverType.qualifiedSourceName()); 8112 typeImportProposal.setCompletion(typeImportCompletion); 8113 typeImportProposal.setFlags(receiverType.modifiers); 8114 typeImportProposal.setAdditionalFlags(CompletionFlags.Default); 8115 typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 8116 typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset); 8117 typeImportProposal.setRelevance(relevance); 8118 8119 proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal}); 8120 8121 this.requestor.accept(proposal); 8122 if(DEBUG) { 8123 this.printDebug(proposal); 8124 } 8125 } 8126 } else { 8127 if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) { 8128 char[] completion = field.name; 8129 8130 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 8131 proposal.setBinding(field); 8132 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 8133 proposal.setSignature(getSignature(field.type)); 8134 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 8135 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 8136 proposal.setPackageName(field.type.qualifiedPackageName()); 8137 proposal.setTypeName(field.type.qualifiedSourceName()); 8138 proposal.setName(field.name); 8139 proposal.setCompletion(completion); 8140 proposal.setFlags(field.modifiers); 8141 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8142 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8143 proposal.setRelevance(relevance); 8144 8145 char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false); 8146 8147 InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition); 8148 fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass)); 8149 fieldImportProposal.setSignature(getSignature(field.type)); 8150 fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 8151 fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 8152 fieldImportProposal.setPackageName(field.type.qualifiedPackageName()); 8153 fieldImportProposal.setTypeName(field.type.qualifiedSourceName()); 8154 fieldImportProposal.setName(field.name); 8155 fieldImportProposal.setCompletion(fieldImportCompletion); 8156 fieldImportProposal.setFlags(field.modifiers); 8157 fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport); 8158 fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 8159 fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset); 8160 fieldImportProposal.setRelevance(relevance); 8161 8162 proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal}); 8163 8164 this.requestor.accept(proposal); 8165 if(DEBUG) { 8166 this.printDebug(proposal); 8167 } 8168 } 8169 } 8170 } 8171 } findImplicitMessageSends( char[] token, TypeBinding[] argTypes, Scope scope, InvocationSite invocationSite, Scope invocationScope, ObjectVector methodsFound)8172 private void findImplicitMessageSends( 8173 char[] token, 8174 TypeBinding[] argTypes, 8175 Scope scope, 8176 InvocationSite invocationSite, 8177 Scope invocationScope, 8178 ObjectVector methodsFound) { 8179 8180 if (token == null) 8181 return; 8182 8183 boolean staticsOnly = false; 8184 // need to know if we're in a static context (or inside a constructor) 8185 8186 done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 8187 8188 switch (scope.kind) { 8189 8190 case Scope.METHOD_SCOPE : 8191 // handle the error case inside an explicit constructor call (see MethodScope>>findField) 8192 MethodScope methodScope = (MethodScope) scope; 8193 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 8194 break; 8195 8196 case Scope.CLASS_SCOPE : 8197 ClassScope classScope = (ClassScope) scope; 8198 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 8199 findMethods( 8200 token, 8201 null, 8202 argTypes, 8203 enclosingType, 8204 classScope, 8205 methodsFound, 8206 staticsOnly, 8207 true, 8208 invocationSite, 8209 invocationScope, 8210 true, 8211 false, 8212 true, 8213 null, 8214 null, 8215 null, 8216 false, 8217 null, 8218 -1, 8219 -1); 8220 staticsOnly |= enclosingType.isStatic(); 8221 break; 8222 8223 case Scope.COMPILATION_UNIT_SCOPE : 8224 break done; 8225 } 8226 scope = scope.parent; 8227 } 8228 } findImports(CompletionOnImportReference importReference, boolean findMembers)8229 private void findImports(CompletionOnImportReference importReference, boolean findMembers) { 8230 char[][] tokens = importReference.tokens; 8231 8232 char[] importName = CharOperation.concatWith(tokens, '.'); 8233 8234 if (importName.length == 0) 8235 return; 8236 8237 char[] lastToken = tokens[tokens.length - 1]; 8238 if(lastToken != null && lastToken.length == 0) 8239 importName = CharOperation.concat(importName, new char[]{'.'}); 8240 8241 this.resolvingImports = true; 8242 this.resolvingStaticImports = importReference.isStatic(); 8243 8244 this.completionToken = lastToken; 8245 this.qualifiedCompletionToken = importName; 8246 8247 // want to replace the existing .*; 8248 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 8249 int oldStart = this.startPosition; 8250 int oldEnd = this.endPosition; 8251 setSourceRange( 8252 importReference.sourceStart, 8253 importReference.declarationSourceEnd); 8254 try { 8255 this.nameEnvironment.findPackages(importName, this, this.javaProject.getAllPackageFragmentRoots(), true); 8256 } catch (JavaModelException e) { 8257 // silent 8258 } 8259 setSourceRange( 8260 oldStart, 8261 oldEnd - 1, 8262 false); 8263 } 8264 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 8265 this.foundTypesCount = 0; 8266 this.nameEnvironment.findTypes( 8267 importName, 8268 findMembers, 8269 this.options.camelCaseMatch, 8270 IJavaSearchConstants.TYPE, 8271 this, 8272 this.monitor); 8273 acceptTypes(null); 8274 } 8275 } 8276 findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic)8277 private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) { 8278 ReferenceBinding[] memberTypes = ref.memberTypes(); 8279 8280 int typeLength = typeName.length; 8281 next : for (int m = memberTypes.length; --m >= 0;) { 8282 ReferenceBinding memberType = memberTypes[m]; 8283 // if (!wantClasses && memberType.isClass()) continue next; 8284 // if (!wantInterfaces && memberType.isInterface()) continue next; 8285 8286 if (onlyStatic && !memberType.isStatic()) 8287 continue next; 8288 8289 if (typeLength > memberType.sourceName.length) 8290 continue next; 8291 8292 if (isFailedMatch(typeName, memberType.sourceName)) 8293 continue next; 8294 8295 if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next; 8296 8297 if (this.options.checkVisibility 8298 && !memberType.canBeSeenBy(this.unitScope.fPackage)) 8299 continue next; 8300 8301 char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON); 8302 8303 int relevance = computeBaseRelevance(); 8304 relevance += computeRelevanceForResolution(); 8305 relevance += computeRelevanceForInterestingProposal(); 8306 relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName); 8307 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8308 8309 if (memberType.isClass()) { 8310 relevance += computeRelevanceForClass(); 8311 } else if(memberType.isEnum()) { 8312 relevance += computeRelevanceForEnum(); 8313 } else if (memberType.isInterface()) { 8314 relevance += computeRelevanceForInterface(); 8315 } 8316 this.noProposal = false; 8317 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 8318 createTypeProposal( 8319 memberType, 8320 memberType.qualifiedSourceName(), 8321 IAccessRule.K_ACCESSIBLE, 8322 completionName, 8323 relevance, 8324 null, 8325 null, 8326 null, 8327 false); 8328 } 8329 } 8330 } 8331 findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref)8332 private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) { 8333 FieldBinding[] fields = ref.availableFields(); 8334 8335 int fieldLength = fieldName.length; 8336 next : for (int m = fields.length; --m >= 0;) { 8337 FieldBinding field = fields[m]; 8338 8339 if (fieldLength > field.name.length) 8340 continue next; 8341 8342 if (field.isSynthetic()) 8343 continue next; 8344 8345 if (!field.isStatic()) 8346 continue next; 8347 8348 if (isFailedMatch(fieldName, field.name)) 8349 continue next; 8350 8351 if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next; 8352 8353 if (this.options.checkVisibility 8354 && !field.canBeSeenBy(this.unitScope.fPackage)) 8355 continue next; 8356 8357 char[] completionName = CharOperation.concat(field.name, SEMICOLON); 8358 8359 int relevance = computeBaseRelevance(); 8360 relevance += computeRelevanceForResolution(); 8361 relevance += computeRelevanceForInterestingProposal(); 8362 relevance += computeRelevanceForCaseMatching(fieldName, field.name); 8363 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8364 8365 this.noProposal = false; 8366 if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 8367 InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition); 8368 proposal.setBinding(field); 8369 proposal.setDeclarationSignature(getSignature(field.declaringClass)); 8370 proposal.setSignature(getSignature(field.type)); 8371 proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName()); 8372 proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName()); 8373 proposal.setPackageName(field.type.qualifiedPackageName()); 8374 proposal.setTypeName(field.type.qualifiedSourceName()); 8375 proposal.setName(field.name); 8376 proposal.setCompletion(completionName); 8377 proposal.setFlags(field.modifiers); 8378 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8379 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8380 proposal.setRelevance(relevance); 8381 this.requestor.accept(proposal); 8382 if(DEBUG) { 8383 this.printDebug(proposal); 8384 } 8385 } 8386 } 8387 } 8388 findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref)8389 private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) { 8390 MethodBinding[] methods = ref.availableMethods(); 8391 8392 int methodLength = methodName.length; 8393 next : for (int m = methods.length; --m >= 0;) { 8394 MethodBinding method = methods[m]; 8395 8396 if (method.isSynthetic()) continue next; 8397 8398 if (method.isDefaultAbstract()) continue next; 8399 8400 if (method.isConstructor()) continue next; 8401 8402 if (!method.isStatic()) continue next; 8403 8404 if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next; 8405 8406 if (this.options.checkVisibility 8407 && !method.canBeSeenBy(this.unitScope.fPackage)) continue next; 8408 8409 if (methodLength > method.selector.length) 8410 continue next; 8411 8412 if (isFailedMatch(methodName, method.selector)) 8413 continue next; 8414 8415 int length = method.parameters.length; 8416 char[][] parameterPackageNames = new char[length][]; 8417 char[][] parameterTypeNames = new char[length][]; 8418 8419 for (int i = 0; i < length; i++) { 8420 TypeBinding type = method.original().parameters[i]; 8421 parameterPackageNames[i] = type.qualifiedPackageName(); 8422 parameterTypeNames[i] = type.qualifiedSourceName(); 8423 } 8424 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 8425 8426 char[] completionName = CharOperation.concat(method.selector, SEMICOLON); 8427 8428 int relevance = computeBaseRelevance(); 8429 relevance += computeRelevanceForResolution(); 8430 relevance += computeRelevanceForInterestingProposal(); 8431 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 8432 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8433 8434 this.noProposal = false; 8435 if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) { 8436 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition); 8437 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 8438 proposal.setSignature(getSignature(method)); 8439 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 8440 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 8441 proposal.setParameterPackageNames(parameterPackageNames); 8442 proposal.setParameterTypeNames(parameterTypeNames); 8443 proposal.setPackageName(method.returnType.qualifiedPackageName()); 8444 proposal.setTypeName(method.returnType.qualifiedSourceName()); 8445 proposal.setName(method.selector); 8446 proposal.setCompletion(completionName); 8447 proposal.setFlags(method.modifiers); 8448 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8449 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8450 proposal.setRelevance(relevance); 8451 if(parameterNames != null) proposal.setParameterNames(parameterNames); 8452 this.requestor.accept(proposal); 8453 if(DEBUG) { 8454 this.printDebug(proposal); 8455 } 8456 } 8457 } 8458 } 8459 findInterfacesMethodDeclarations( char[] selector, ReferenceBinding receiverType, ReferenceBinding[] itsInterfaces, Scope scope, ObjectVector methodsFound, Binding[] missingElements, int[] missingElementssStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)8460 private void findInterfacesMethodDeclarations( 8461 char[] selector, 8462 ReferenceBinding receiverType, 8463 ReferenceBinding[] itsInterfaces, 8464 Scope scope, 8465 ObjectVector methodsFound, 8466 Binding[] missingElements, 8467 int[] missingElementssStarts, 8468 int[] missingElementsEnds, 8469 boolean missingElementsHaveProblems) { 8470 8471 if (selector == null) 8472 return; 8473 8474 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 8475 ReferenceBinding[] interfacesToVisit = itsInterfaces; 8476 int nextPosition = interfacesToVisit.length; 8477 8478 for (int i = 0; i < nextPosition; i++) { 8479 ReferenceBinding currentType = interfacesToVisit[i]; 8480 MethodBinding[] methods = currentType.availableMethods(); 8481 if(methods != null) { 8482 findLocalMethodDeclarations( 8483 selector, 8484 methods, 8485 scope, 8486 methodsFound, 8487 false, 8488 receiverType); 8489 } 8490 8491 itsInterfaces = currentType.superInterfaces(); 8492 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 8493 int itsLength = itsInterfaces.length; 8494 if (nextPosition + itsLength >= interfacesToVisit.length) 8495 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 8496 nextInterface : for (int a = 0; a < itsLength; a++) { 8497 ReferenceBinding next = itsInterfaces[a]; 8498 for (int b = 0; b < nextPosition; b++) 8499 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 8500 interfacesToVisit[nextPosition++] = next; 8501 } 8502 } 8503 } 8504 } 8505 } 8506 findInterfacesMethods( char[] selector, TypeBinding[] typeArgTypes, TypeBinding[] argTypes, ReferenceBinding receiverType, ReferenceBinding[] itsInterfaces, Scope scope, ObjectVector methodsFound, boolean onlyStaticMethods, boolean exactMatch, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean superCall, boolean canBePrefixed, Binding[] missingElements, int[] missingElementssStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)8507 private void findInterfacesMethods( 8508 char[] selector, 8509 TypeBinding[] typeArgTypes, 8510 TypeBinding[] argTypes, 8511 ReferenceBinding receiverType, 8512 ReferenceBinding[] itsInterfaces, 8513 Scope scope, 8514 ObjectVector methodsFound, 8515 boolean onlyStaticMethods, 8516 boolean exactMatch, 8517 InvocationSite invocationSite, 8518 Scope invocationScope, 8519 boolean implicitCall, 8520 boolean superCall, 8521 boolean canBePrefixed, 8522 Binding[] missingElements, 8523 int[] missingElementssStarts, 8524 int[] missingElementsEnds, 8525 boolean missingElementsHaveProblems, 8526 char[] castedReceiver, 8527 int receiverStart, 8528 int receiverEnd) { 8529 8530 if (selector == null) 8531 return; 8532 8533 if (itsInterfaces != Binding.NO_SUPERINTERFACES) { 8534 ReferenceBinding[] interfacesToVisit = itsInterfaces; 8535 int nextPosition = interfacesToVisit.length; 8536 8537 for (int i = 0; i < nextPosition; i++) { 8538 ReferenceBinding currentType = interfacesToVisit[i]; 8539 MethodBinding[] methods = currentType.availableMethods(); 8540 if(methods != null) { 8541 findLocalMethods( 8542 selector, 8543 typeArgTypes, 8544 argTypes, 8545 methods, 8546 scope, 8547 methodsFound, 8548 onlyStaticMethods, 8549 exactMatch, 8550 receiverType, 8551 invocationSite, 8552 invocationScope, 8553 implicitCall, 8554 superCall, 8555 canBePrefixed, 8556 missingElements, 8557 missingElementssStarts, 8558 missingElementsEnds, 8559 missingElementsHaveProblems, 8560 castedReceiver, 8561 receiverStart, 8562 receiverEnd); 8563 } 8564 8565 itsInterfaces = currentType.superInterfaces(); 8566 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 8567 int itsLength = itsInterfaces.length; 8568 if (nextPosition + itsLength >= interfacesToVisit.length) 8569 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 8570 nextInterface : for (int a = 0; a < itsLength; a++) { 8571 ReferenceBinding next = itsInterfaces[a]; 8572 for (int b = 0; b < nextPosition; b++) 8573 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 8574 interfacesToVisit[nextPosition++] = next; 8575 } 8576 } 8577 } 8578 } 8579 } 8580 /* 8581 * Find javadoc block tags for a given completion javadoc tag node 8582 */ findJavadocBlockTags(CompletionOnJavadocTag javadocTag)8583 private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) { 8584 char[][] possibleTags = javadocTag.getPossibleBlockTags(); 8585 if (possibleTags == null) return; 8586 int length = possibleTags.length; 8587 for (int i=0; i<length; i++) { 8588 int relevance = computeBaseRelevance(); 8589 relevance += computeRelevanceForInterestingProposal(); 8590 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors 8591 8592 this.noProposal = false; 8593 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) { 8594 char[] possibleTag = possibleTags[i]; 8595 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition); 8596 proposal.setName(possibleTag); 8597 int tagLength = possibleTag.length; 8598 char[] completion = new char[1+tagLength]; 8599 completion[0] = '@'; 8600 System.arraycopy(possibleTag, 0, completion, 1, tagLength); 8601 proposal.setCompletion(completion); 8602 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8603 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8604 proposal.setRelevance(relevance); 8605 this.requestor.accept(proposal); 8606 if (DEBUG) { 8607 this.printDebug(proposal); 8608 } 8609 } 8610 } 8611 } 8612 8613 /* 8614 * Find javadoc inline tags for a given completion javadoc tag node 8615 */ findJavadocInlineTags(CompletionOnJavadocTag javadocTag)8616 private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) { 8617 char[][] possibleTags = javadocTag.getPossibleInlineTags(); 8618 if (possibleTags == null) return; 8619 int length = possibleTags.length; 8620 for (int i=0; i<length; i++) { 8621 int relevance = computeBaseRelevance(); 8622 relevance += computeRelevanceForInterestingProposal(); 8623 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors 8624 8625 this.noProposal = false; 8626 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) { 8627 char[] possibleTag = possibleTags[i]; 8628 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition); 8629 proposal.setName(possibleTag); 8630 int tagLength = possibleTag.length; 8631 // boolean inlineTagStarted = javadocTag.completeInlineTagStarted(); 8632 char[] completion = new char[2+tagLength+1]; 8633 completion[0] = '{'; 8634 completion[1] = '@'; 8635 System.arraycopy(possibleTag, 0, completion, 2, tagLength); 8636 // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026) 8637 //completion[tagLength+2] = ' '; 8638 completion[tagLength+2] = '}'; 8639 proposal.setCompletion(completion); 8640 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8641 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8642 proposal.setRelevance(relevance); 8643 this.requestor.accept(proposal); 8644 if (DEBUG) { 8645 this.printDebug(proposal); 8646 } 8647 } 8648 } 8649 } 8650 8651 /* 8652 * Find javadoc parameter names. 8653 */ findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam)8654 private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) { 8655 8656 if (missingParams == null) return; 8657 8658 // Get relevance 8659 int relevance = computeBaseRelevance(); 8660 relevance += computeRelevanceForInterestingProposal(); 8661 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name 8662 if (!isTypeParam) relevance += R_INTERESTING; 8663 8664 // Propose missing param 8665 int length = missingParams.length; 8666 relevance += length; 8667 for (int i=0; i<length; i++) { 8668 char[] argName = missingParams[i]; 8669 if (token == null || CharOperation.prefixEquals(token, argName)) { 8670 8671 this.noProposal = false; 8672 if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) { 8673 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition); 8674 proposal.setName(argName); 8675 char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName; 8676 proposal.setCompletion(completion); 8677 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8678 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8679 proposal.setRelevance(--relevance); 8680 this.requestor.accept(proposal); 8681 if (DEBUG) { 8682 this.printDebug(proposal); 8683 } 8684 } 8685 } 8686 } 8687 } 8688 8689 // what about onDemand types? Ignore them since it does not happen! 8690 // import p1.p2.A.*; findKeywords(char[] keyword, char[][] choices, boolean staticFieldsAndMethodOnly, boolean ignorePackageKeyword)8691 private void findKeywords(char[] keyword, char[][] choices, boolean staticFieldsAndMethodOnly, boolean ignorePackageKeyword) { 8692 if(choices == null || choices.length == 0) return; 8693 int length = keyword.length; 8694 for (int i = 0; i < choices.length; i++) 8695 if (length <= choices[i].length && (CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */) 8696 || (this.options.substringMatch && CharOperation.substringMatch(keyword, choices[i])))) { 8697 if (ignorePackageKeyword && CharOperation.equals(choices[i], Keywords.PACKAGE)) 8698 continue; 8699 int relevance = computeBaseRelevance(); 8700 relevance += computeRelevanceForResolution(); 8701 relevance += computeRelevanceForInterestingProposal(); 8702 relevance += computeRelevanceForCaseMatching(keyword, choices[i]); 8703 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords 8704 if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; 8705 8706 if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) { 8707 relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); 8708 relevance += computeRelevanceForQualification(false); 8709 } 8710 if (CharOperation.equals(choices[i], Keywords.NEW)) { 8711 relevance += computeRelevanceForConstructor(); 8712 } 8713 this.noProposal = false; 8714 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 8715 InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 8716 proposal.setName(choices[i]); 8717 proposal.setCompletion(choices[i]); 8718 proposal.setReplaceRange((this.startPosition < 0) ? 0 : this.startPosition - this.offset, this.endPosition - this.offset); 8719 proposal.setTokenRange((this.tokenStart < 0) ? 0 : this.tokenStart - this.offset, this.tokenEnd - this.offset); 8720 proposal.setRelevance(relevance); 8721 this.requestor.accept(proposal); 8722 if(DEBUG) { 8723 this.printDebug(proposal); 8724 } 8725 } 8726 } 8727 } findKeywordsForMember(char[] token, int modifiers, ASTNode astNode)8728 private void findKeywordsForMember(char[] token, int modifiers, ASTNode astNode) { 8729 char[][] keywords = new char[Keywords.COUNT][]; 8730 int count = 0; 8731 8732 // visibility 8733 if((modifiers & ClassFileConstants.AccPrivate) == 0 8734 && (modifiers & ClassFileConstants.AccProtected) == 0 8735 && (modifiers & ClassFileConstants.AccPublic) == 0) { 8736 keywords[count++] = Keywords.PROTECTED; 8737 keywords[count++] = Keywords.PUBLIC; 8738 if((modifiers & ClassFileConstants.AccAbstract) == 0) { 8739 keywords[count++] = Keywords.PRIVATE; 8740 } 8741 } 8742 8743 if (astNode instanceof CompletionOnFieldType && 8744 this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) { 8745 FieldBinding astNodeBinding = ((CompletionOnFieldType) astNode).binding; 8746 ReferenceBinding declaringClass = astNodeBinding != null ? astNodeBinding.declaringClass : null; 8747 if (declaringClass != null && declaringClass.isInterface() && !declaringClass.isAnnotationType()) 8748 keywords[count++] = Keywords.DEFAULT; 8749 } 8750 if((modifiers & ClassFileConstants.AccAbstract) == 0) { 8751 // abtract 8752 if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) { 8753 keywords[count++] = Keywords.ABSTRACT; 8754 } 8755 8756 // final 8757 if((modifiers & ClassFileConstants.AccFinal) == 0) { 8758 keywords[count++] = Keywords.FINAL; 8759 } 8760 8761 // static 8762 if((modifiers & ClassFileConstants.AccStatic) == 0) { 8763 keywords[count++] = Keywords.STATIC; 8764 } 8765 8766 boolean canBeField = true; 8767 boolean canBeMethod = true; 8768 boolean canBeType = true; 8769 if((modifiers & ClassFileConstants.AccNative) != 0 8770 || (modifiers & ClassFileConstants.AccStrictfp) != 0 8771 || (modifiers & ClassFileConstants.AccSynchronized) != 0) { 8772 canBeField = false; 8773 canBeType = false; 8774 } 8775 8776 if((modifiers & ClassFileConstants.AccTransient) != 0 8777 || (modifiers & ClassFileConstants.AccVolatile) != 0) { 8778 canBeMethod = false; 8779 canBeType = false; 8780 } 8781 8782 if(canBeField) { 8783 // transient 8784 if((modifiers & ClassFileConstants.AccTransient) == 0) { 8785 keywords[count++] = Keywords.TRANSIENT; 8786 } 8787 8788 // volatile 8789 if((modifiers & ClassFileConstants.AccVolatile) == 0) { 8790 keywords[count++] = Keywords.VOLATILE; 8791 } 8792 } 8793 8794 if(canBeMethod) { 8795 // native 8796 if((modifiers & ClassFileConstants.AccNative) == 0) { 8797 keywords[count++] = Keywords.NATIVE; 8798 } 8799 8800 // strictfp 8801 if((modifiers & ClassFileConstants.AccStrictfp) == 0) { 8802 keywords[count++] = Keywords.STRICTFP; 8803 } 8804 8805 // synchronized 8806 if((modifiers & ClassFileConstants.AccSynchronized) == 0) { 8807 keywords[count++] = Keywords.SYNCHRONIZED; 8808 } 8809 } 8810 8811 if(canBeType) { 8812 keywords[count++] = Keywords.CLASS; 8813 keywords[count++] = Keywords.INTERFACE; 8814 8815 if((modifiers & ClassFileConstants.AccFinal) == 0) { 8816 keywords[count++] = Keywords.ENUM; 8817 } 8818 } 8819 } else { 8820 // class 8821 keywords[count++] = Keywords.CLASS; 8822 keywords[count++] = Keywords.INTERFACE; 8823 } 8824 System.arraycopy(keywords, 0, keywords = new char[count][], 0, count); 8825 8826 findKeywords(token, keywords, false, false); 8827 } findLabels(char[] label, char[][] choices)8828 private void findLabels(char[] label, char[][] choices) { 8829 if(choices == null || choices.length == 0) return; 8830 8831 int length = label.length; 8832 for (int i = 0; i < choices.length; i++) { 8833 if (length <= choices[i].length 8834 && CharOperation.prefixEquals(label, choices[i], false /* ignore case */ 8835 )){ 8836 int relevance = computeBaseRelevance(); 8837 relevance += computeRelevanceForResolution(); 8838 relevance += computeRelevanceForInterestingProposal(); 8839 relevance += computeRelevanceForCaseMatching(label, choices[i]); 8840 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors 8841 8842 this.noProposal = false; 8843 if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) { 8844 InternalCompletionProposal proposal = createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition); 8845 proposal.setName(choices[i]); 8846 proposal.setCompletion(choices[i]); 8847 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8848 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8849 proposal.setRelevance(relevance); 8850 this.requestor.accept(proposal); 8851 if(DEBUG) { 8852 this.printDebug(proposal); 8853 } 8854 } 8855 } 8856 } 8857 } 8858 8859 // Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding) findLocalMethodDeclarations( char[] methodName, MethodBinding[] methods, Scope scope, ObjectVector methodsFound, boolean exactMatch, ReferenceBinding receiverType)8860 private void findLocalMethodDeclarations( 8861 char[] methodName, 8862 MethodBinding[] methods, 8863 Scope scope, 8864 ObjectVector methodsFound, 8865 // boolean noVoidReturnType, how do you know? 8866 boolean exactMatch, 8867 ReferenceBinding receiverType) { 8868 8869 ObjectVector newMethodsFound = new ObjectVector(); 8870 // Inherited methods which are hidden by subclasses are filtered out 8871 // No visibility checks can be performed without the scope & invocationSite 8872 int methodLength = methodName.length; 8873 next : for (int f = methods.length; --f >= 0;) { 8874 8875 MethodBinding method = methods[f]; 8876 if (method.isSynthetic()) continue next; 8877 8878 if (method.isDefaultAbstract()) continue next; 8879 8880 if (method.isConstructor()) continue next; 8881 8882 if (method.isFinal()) { 8883 newMethodsFound.add(method); 8884 continue next; 8885 } 8886 8887 if (this.options.checkDeprecation && 8888 method.isViewedAsDeprecated() && 8889 !scope.isDefinedInSameUnit(method.declaringClass)) 8890 continue next; 8891 8892 // if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next; 8893 if(method.isStatic()) continue next; 8894 8895 if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next; 8896 8897 if (exactMatch) { 8898 if (!CharOperation.equals(methodName, method.selector, false /* ignore case */ 8899 )) 8900 continue next; 8901 8902 } else { 8903 8904 if (methodLength > method.selector.length) 8905 continue next; 8906 8907 if (isFailedMatch(methodName, method.selector)) 8908 continue next; 8909 } 8910 8911 for (int i = methodsFound.size; --i >= 0;) { 8912 MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i); 8913 if (method == otherMethod) 8914 continue next; 8915 8916 if (CharOperation.equals(method.selector, otherMethod.selector, true) 8917 && this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 8918 continue next; 8919 } 8920 } 8921 8922 newMethodsFound.add(method); 8923 8924 int length = method.parameters.length; 8925 char[][] parameterPackageNames = new char[length][]; 8926 char[][] parameterFullTypeNames = new char[length][]; 8927 8928 for (int i = 0; i < length; i++) { 8929 TypeBinding type = method.parameters[i]; 8930 parameterPackageNames[i] = type.qualifiedPackageName(); 8931 parameterFullTypeNames[i] = type.qualifiedSourceName(); 8932 } 8933 8934 char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames); 8935 8936 if(method.typeVariables != null && method.typeVariables.length > 0) { 8937 char[][] excludedNames = findEnclosingTypeNames(scope); 8938 char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames); 8939 if(substituedParameterNames != null) { 8940 method = new ParameterizedMethodBinding( 8941 method.declaringClass, 8942 method, 8943 substituedParameterNames, 8944 scope.environment()); 8945 } 8946 } 8947 8948 StringBuffer completion = new StringBuffer(10); 8949 if (!exactMatch) { 8950 createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion); 8951 } 8952 8953 int relevance = computeBaseRelevance(); 8954 relevance += computeRelevanceForResolution(); 8955 relevance += computeRelevanceForInterestingProposal(); 8956 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 8957 relevance += R_METHOD_OVERIDE; 8958 if(method.isAbstract()) relevance += R_ABSTRACT_METHOD; 8959 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 8960 8961 this.noProposal = false; 8962 if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) { 8963 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition); 8964 proposal.setBinding(method); 8965 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 8966 proposal.setDeclarationKey(method.declaringClass.computeUniqueKey()); 8967 proposal.setSignature(getSignature(method)); 8968 MethodBinding original = method.original(); 8969 if(original != method) { 8970 proposal.setOriginalSignature(getSignature(original)); 8971 } 8972 proposal.setKey(method.computeUniqueKey()); 8973 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 8974 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 8975 proposal.setParameterPackageNames(parameterPackageNames); 8976 proposal.setParameterTypeNames(parameterFullTypeNames); 8977 proposal.setPackageName(method.returnType.qualifiedPackageName()); 8978 proposal.setTypeName(method.returnType.qualifiedSourceName()); 8979 proposal.setCompletion(completion.toString().toCharArray()); 8980 proposal.setName(method.selector); 8981 proposal.setFlags(method.modifiers); 8982 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 8983 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 8984 proposal.setRelevance(relevance); 8985 if(parameterNames != null) proposal.setParameterNames(parameterNames); 8986 this.requestor.accept(proposal); 8987 if(DEBUG) { 8988 this.printDebug(proposal); 8989 } 8990 } 8991 } 8992 methodsFound.addAll(newMethodsFound); 8993 } 8994 8995 // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean) findLocalMethods( char[] methodName, TypeBinding[] typeArgTypes, TypeBinding[] argTypes, MethodBinding[] methods, Scope scope, ObjectVector methodsFound, boolean onlyStaticMethods, boolean exactMatch, ReferenceBinding receiverType, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean superCall, boolean canBePrefixed, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)8996 private void findLocalMethods( 8997 char[] methodName, 8998 TypeBinding[] typeArgTypes, 8999 TypeBinding[] argTypes, 9000 MethodBinding[] methods, 9001 Scope scope, 9002 ObjectVector methodsFound, 9003 boolean onlyStaticMethods, 9004 boolean exactMatch, 9005 ReferenceBinding receiverType, 9006 InvocationSite invocationSite, 9007 Scope invocationScope, 9008 boolean implicitCall, 9009 boolean superCall, 9010 boolean canBePrefixed, 9011 Binding[] missingElements, 9012 int[] missingElementsStarts, 9013 int[] missingElementsEnds, 9014 boolean missingElementsHaveProblems, 9015 char[] castedReceiver, 9016 int receiverStart, 9017 int receiverEnd) { 9018 9019 boolean completionOnReferenceExpressionName = invocationSite instanceof ReferenceExpression; 9020 ObjectVector newMethodsFound = new ObjectVector(); 9021 // Inherited methods which are hidden by subclasses are filtered out 9022 // No visibility checks can be performed without the scope & invocationSite 9023 9024 int methodLength = methodName.length; 9025 int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length; 9026 int minArgLength = argTypes == null ? 0 : argTypes.length; 9027 9028 next : for (int f = methods.length; --f >= 0;) { 9029 MethodBinding method = methods[f]; 9030 9031 if (method.isSynthetic()) continue next; 9032 9033 if (method.isDefaultAbstract()) continue next; 9034 9035 if (method.isConstructor()) continue next; 9036 9037 if (this.options.checkDeprecation && 9038 method.isViewedAsDeprecated() && 9039 !scope.isDefinedInSameUnit(method.declaringClass)) 9040 continue next; 9041 9042 //TODO (david) perhaps the relevance of a void method must be lesser than other methods 9043 //if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next; 9044 9045 if (onlyStaticMethods && !method.isStatic()) continue next; 9046 9047 if (this.options.checkVisibility 9048 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 9049 9050 if(superCall && method.isAbstract()) { 9051 methodsFound.add(new Object[]{method, receiverType}); 9052 continue next; 9053 } 9054 9055 if (exactMatch) { 9056 if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) { 9057 continue next; 9058 } 9059 } else { 9060 if (methodLength > method.selector.length) continue next; 9061 if (isFailedMatch(methodName, method.selector)) { 9062 continue next; 9063 } 9064 } 9065 9066 if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length) 9067 continue next; 9068 9069 if (minTypeArgLength != 0) { 9070 method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes); 9071 } 9072 9073 if (minArgLength > method.parameters.length) 9074 continue next; 9075 9076 for (int a = minArgLength; --a >= 0;){ 9077 if (argTypes[a] != null) { // can be null if it could not be resolved properly 9078 if (!argTypes[a].isCompatibleWith(method.parameters[a])) { 9079 continue next; 9080 } 9081 } 9082 } 9083 9084 boolean prefixRequired = false; 9085 9086 for (int i = methodsFound.size; --i >= 0;) { 9087 Object[] other = (Object[]) methodsFound.elementAt(i); 9088 MethodBinding otherMethod = (MethodBinding) other[0]; 9089 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 9090 if (method == otherMethod && TypeBinding.equalsEquals(receiverType, otherReceiverType)) 9091 continue next; 9092 9093 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 9094 if (TypeBinding.equalsEquals(receiverType, otherReceiverType)) { 9095 if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 9096 if (!superCall || !otherMethod.declaringClass.isInterface()) { 9097 continue next; 9098 } 9099 } 9100 } else { 9101 if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 9102 if(receiverType.isAnonymousType()) continue next; 9103 9104 if(!superCall) { 9105 if(!canBePrefixed) continue next; 9106 9107 prefixRequired = true; 9108 } 9109 } 9110 } 9111 } 9112 } 9113 9114 newMethodsFound.add(new Object[]{method, receiverType}); 9115 9116 ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass); 9117 if (TypeBinding.notEquals(method.declaringClass, superTypeWithSameErasure)) { 9118 MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector); 9119 for (int i = 0; i < otherMethods.length; i++) { 9120 if(otherMethods[i].original() == method.original()) { 9121 method = otherMethods[i]; 9122 } 9123 } 9124 } 9125 9126 int length = method.parameters.length; 9127 char[][] parameterPackageNames = new char[length][]; 9128 char[][] parameterTypeNames = new char[length][]; 9129 9130 for (int i = 0; i < length; i++) { 9131 TypeBinding type = method.original().parameters[i]; 9132 parameterPackageNames[i] = type.qualifiedPackageName(); 9133 parameterTypeNames[i] = type.qualifiedSourceName(); 9134 } 9135 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 9136 9137 char[] completion = CharOperation.NO_CHAR; 9138 9139 int previousStartPosition = this.startPosition; 9140 int previousTokenStart = this.tokenStart; 9141 9142 // Special case for completion in javadoc 9143 if (this.assistNodeInJavadoc > 0) { 9144 Expression receiver = null; 9145 if (invocationSite instanceof CompletionOnJavadocMessageSend) { 9146 CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite; 9147 receiver = msg.receiver; 9148 } else if (invocationSite instanceof CompletionOnJavadocFieldReference) { 9149 CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite; 9150 receiver = fieldRef.receiver; 9151 } 9152 if (receiver != null) { 9153 StringBuffer javadocCompletion = new StringBuffer(); 9154 if (receiver.isThis()) { 9155 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 9156 javadocCompletion.append('#'); 9157 } 9158 } else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) { 9159 if (receiver instanceof JavadocSingleTypeReference) { 9160 JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver; 9161 javadocCompletion.append(typeRef.token); 9162 javadocCompletion.append('#'); 9163 } else if (receiver instanceof JavadocQualifiedTypeReference) { 9164 JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver; 9165 completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#'); 9166 for (int t=0,nt =typeRef.tokens.length; t<nt; t++) { 9167 if (t>0) javadocCompletion.append('.'); 9168 javadocCompletion.append(typeRef.tokens[t]); 9169 } 9170 javadocCompletion.append('#'); 9171 } 9172 } 9173 javadocCompletion.append(method.selector); 9174 // Append parameters types 9175 javadocCompletion.append('('); 9176 if (method.parameters != null) { 9177 boolean isVarargs = method.isVarargs(); 9178 for (int p=0, ln=method.parameters.length; p<ln; p++) { 9179 if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$ 9180 TypeBinding argTypeBinding = method.parameters[p]; 9181 if (isVarargs && p == ln - 1) { 9182 createVargsType(argTypeBinding.erasure(), scope, javadocCompletion); 9183 } else { 9184 createType(argTypeBinding.erasure(), scope,javadocCompletion); 9185 } 9186 } 9187 } 9188 javadocCompletion.append(')'); 9189 completion = javadocCompletion.toString().toCharArray(); 9190 } 9191 } else { 9192 // nothing to insert - do not want to replace the existing selector & arguments 9193 if (!exactMatch) { 9194 if (completionOnReferenceExpressionName) 9195 completion = method.selector; 9196 else if (this.source != null 9197 && this.source.length > this.endPosition 9198 && this.source[this.endPosition] == '(') 9199 completion = method.selector; 9200 else 9201 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 9202 9203 if (castedReceiver != null) { 9204 completion = CharOperation.concat(castedReceiver, completion); 9205 } 9206 } else { 9207 if(prefixRequired && (this.source != null)) { 9208 completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition); 9209 } else { 9210 this.startPosition = this.endPosition; 9211 } 9212 this.tokenStart = this.tokenEnd; 9213 } 9214 9215 if(prefixRequired || this.options.forceImplicitQualification){ 9216 char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic()); 9217 completion = CharOperation.concat(prefix,completion,'.'); 9218 } 9219 } 9220 9221 int relevance = computeBaseRelevance(); 9222 relevance += computeRelevanceForResolution(); 9223 relevance += computeRelevanceForInterestingProposal(); 9224 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 9225 relevance += computeRelevanceForExpectingType(method.returnType); 9226 relevance += computeRelevanceForEnumConstant(method.returnType); 9227 relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic()); 9228 relevance += computeRelevanceForQualification(prefixRequired); 9229 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 9230 if (onlyStaticMethods && this.insideQualifiedReference) { 9231 relevance += computeRelevanceForInheritance(receiverType, method.declaringClass); 9232 } 9233 if (missingElements != null) { 9234 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 9235 } 9236 relevance += computeRelevanceForSuper(method, scope, invocationSite); 9237 this.noProposal = false; 9238 9239 if (castedReceiver == null) { 9240 // Standard proposal 9241 if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) { 9242 InternalCompletionProposal proposal = createProposal(completionOnReferenceExpressionName ? CompletionProposal.METHOD_NAME_REFERENCE : CompletionProposal.METHOD_REF, this.actualCompletionPosition); 9243 proposal.setBinding(method); 9244 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9245 proposal.setSignature(getSignature(method)); 9246 MethodBinding original = method.original(); 9247 if(original != method) { 9248 proposal.setOriginalSignature(getSignature(original)); 9249 } 9250 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9251 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9252 proposal.setParameterPackageNames(parameterPackageNames); 9253 proposal.setParameterTypeNames(parameterTypeNames); 9254 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9255 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9256 proposal.setName(method.selector); 9257 if (missingElements != null) { 9258 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 9259 for (int i = 0; i < missingElements.length; i++) { 9260 subProposals[i] = 9261 createRequiredTypeProposal( 9262 missingElements[i], 9263 missingElementsStarts[i], 9264 missingElementsEnds[i], 9265 relevance); 9266 } 9267 proposal.setRequiredProposals(subProposals); 9268 } 9269 proposal.setCompletion(completion); 9270 proposal.setFlags(method.modifiers); 9271 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9272 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9273 proposal.setRelevance(relevance); 9274 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9275 this.requestor.accept(proposal); 9276 if(DEBUG) { 9277 this.printDebug(proposal); 9278 } 9279 } 9280 9281 // Javadoc proposal 9282 if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) { 9283 char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK); 9284 InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition); 9285 proposal.setBinding(method); 9286 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9287 proposal.setSignature(getSignature(method)); 9288 MethodBinding original = method.original(); 9289 if(original != method) { 9290 proposal.setOriginalSignature(getSignature(original)); 9291 } 9292 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9293 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9294 proposal.setParameterPackageNames(parameterPackageNames); 9295 proposal.setParameterTypeNames(parameterTypeNames); 9296 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9297 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9298 proposal.setName(method.selector); 9299 proposal.setCompletion(javadocCompletion); 9300 proposal.setFlags(method.modifiers); 9301 int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition; 9302 proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset); 9303 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9304 proposal.setRelevance(relevance+R_INLINE_TAG); 9305 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9306 this.requestor.accept(proposal); 9307 if(DEBUG) { 9308 this.printDebug(proposal); 9309 } 9310 } 9311 } else { 9312 if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) { 9313 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition); 9314 proposal.setBinding(method); 9315 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9316 proposal.setSignature(getSignature(method)); 9317 MethodBinding original = method.original(); 9318 if(original != method) { 9319 proposal.setOriginalSignature(getSignature(original)); 9320 } 9321 proposal.setReceiverSignature(getSignature(receiverType)); 9322 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9323 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9324 proposal.setParameterPackageNames(parameterPackageNames); 9325 proposal.setParameterTypeNames(parameterTypeNames); 9326 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9327 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9328 proposal.setName(method.selector); 9329 if (missingElements != null) { 9330 CompletionProposal[] subProposals = new CompletionProposal[missingElements.length]; 9331 for (int i = 0; i < missingElements.length; i++) { 9332 subProposals[i] = 9333 createRequiredTypeProposal( 9334 missingElements[i], 9335 missingElementsStarts[i], 9336 missingElementsEnds[i], 9337 relevance); 9338 } 9339 proposal.setRequiredProposals(subProposals); 9340 } 9341 proposal.setCompletion(completion); 9342 proposal.setFlags(method.modifiers); 9343 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9344 proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset); 9345 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9346 proposal.setRelevance(relevance); 9347 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9348 this.requestor.accept(proposal); 9349 if(DEBUG) { 9350 this.printDebug(proposal); 9351 } 9352 } 9353 } 9354 this.startPosition = previousStartPosition; 9355 this.tokenStart = previousTokenStart; 9356 } 9357 9358 methodsFound.addAll(newMethodsFound); 9359 } findLocalMethodsFromFavorites( char[] methodName, MethodBinding[] methods, Scope scope, ObjectVector methodsFound, ObjectVector methodsFoundFromFavorites, ReferenceBinding receiverType, InvocationSite invocationSite, Scope invocationScope)9360 private void findLocalMethodsFromFavorites( 9361 char[] methodName, 9362 MethodBinding[] methods, 9363 Scope scope, 9364 ObjectVector methodsFound, 9365 ObjectVector methodsFoundFromFavorites, 9366 ReferenceBinding receiverType, 9367 InvocationSite invocationSite, 9368 Scope invocationScope) { 9369 9370 char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.'); 9371 9372 int methodLength = methodName.length; 9373 9374 next : for (int f = methods.length; --f >= 0;) { 9375 MethodBinding method = methods[f]; 9376 9377 if (method.isSynthetic()) continue next; 9378 9379 if (method.isDefaultAbstract()) continue next; 9380 9381 if (method.isConstructor()) continue next; 9382 9383 if (this.options.checkDeprecation && 9384 method.isViewedAsDeprecated() && 9385 !scope.isDefinedInSameUnit(method.declaringClass)) 9386 continue next; 9387 9388 if (!method.isStatic()) continue next; 9389 9390 if (this.options.checkVisibility 9391 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 9392 9393 if (methodLength > method.selector.length) continue next; 9394 9395 if (isFailedMatch(methodName, method.selector)) { 9396 continue next; 9397 } 9398 9399 for (int i = methodsFoundFromFavorites.size; --i >= 0;) { 9400 Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i); 9401 MethodBinding otherMethod = (MethodBinding) other[0]; 9402 9403 if (method == otherMethod) continue next; 9404 9405 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 9406 if (TypeBinding.equalsEquals(otherMethod.declaringClass, method.declaringClass) && 9407 this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 9408 continue next; 9409 } 9410 } 9411 } 9412 9413 for (int i = methodsFound.size; --i >= 0;) { 9414 Object[] other = (Object[]) methodsFound.elementAt(i); 9415 MethodBinding otherMethod = (MethodBinding) other[0]; 9416 9417 if (method == otherMethod) continue next; 9418 9419 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 9420 if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 9421 continue next; 9422 } 9423 } 9424 } 9425 9426 boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) && 9427 this.options.suggestStaticImport; 9428 9429 boolean isAlreadyImported = false; 9430 if (!proposeStaticImport) { 9431 if(!this.importCachesInitialized) { 9432 initializeImportCaches(); 9433 } 9434 for (int j = 0; j < this.importCacheCount; j++) { 9435 char[][] importName = this.importsCache[j]; 9436 if(CharOperation.equals(receiverType.sourceName, importName[0])) { 9437 if (!CharOperation.equals(typeName, importName[1])) { 9438 continue next; 9439 } else { 9440 isAlreadyImported = true; 9441 } 9442 } 9443 } 9444 } 9445 9446 methodsFoundFromFavorites.add(new Object[]{method, receiverType}); 9447 9448 ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass); 9449 if (TypeBinding.notEquals(method.declaringClass, superTypeWithSameErasure)) { 9450 MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector); 9451 for (int i = 0; i < otherMethods.length; i++) { 9452 if(otherMethods[i].original() == method.original()) { 9453 method = otherMethods[i]; 9454 } 9455 } 9456 } 9457 9458 int length = method.parameters.length; 9459 char[][] parameterPackageNames = new char[length][]; 9460 char[][] parameterTypeNames = new char[length][]; 9461 9462 for (int i = 0; i < length; i++) { 9463 TypeBinding type = method.original().parameters[i]; 9464 parameterPackageNames[i] = type.qualifiedPackageName(); 9465 parameterTypeNames[i] = type.qualifiedSourceName(); 9466 } 9467 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 9468 9469 char[] completion = CharOperation.NO_CHAR; 9470 9471 int previousStartPosition = this.startPosition; 9472 int previousTokenStart = this.tokenStart; 9473 9474 if (this.source != null 9475 && this.source.length > this.endPosition 9476 && this.source[this.endPosition] == '(') { 9477 completion = method.selector; 9478 } else { 9479 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 9480 } 9481 9482 int relevance = computeBaseRelevance(); 9483 relevance += computeRelevanceForResolution(); 9484 relevance += computeRelevanceForInterestingProposal(); 9485 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 9486 relevance += computeRelevanceForExpectingType(method.returnType); 9487 relevance += computeRelevanceForEnumConstant(method.returnType); 9488 relevance += computeRelevanceForStatic(true, method.isStatic()); 9489 relevance += computeRelevanceForQualification(true); 9490 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 9491 9492 CompilationUnitDeclaration cu = this.unitScope.referenceContext; 9493 int importStart = cu.types[0].declarationSourceStart; 9494 int importEnd = importStart; 9495 9496 this.noProposal = false; 9497 9498 if (!proposeStaticImport) { 9499 if (isAlreadyImported) { 9500 if (!isIgnored(CompletionProposal.METHOD_REF)) { 9501 completion = CharOperation.concat(receiverType.sourceName, completion, '.'); 9502 9503 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 9504 proposal.setBinding(method); 9505 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9506 proposal.setSignature(getSignature(method)); 9507 MethodBinding original = method.original(); 9508 if(original != method) { 9509 proposal.setOriginalSignature(getSignature(original)); 9510 } 9511 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9512 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9513 proposal.setParameterPackageNames(parameterPackageNames); 9514 proposal.setParameterTypeNames(parameterTypeNames); 9515 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9516 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9517 proposal.setName(method.selector); 9518 proposal.setCompletion(completion); 9519 proposal.setFlags(method.modifiers); 9520 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9521 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9522 proposal.setRelevance(relevance); 9523 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9524 9525 this.requestor.accept(proposal); 9526 if(DEBUG) { 9527 this.printDebug(proposal); 9528 } 9529 } 9530 } else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) { 9531 completion = CharOperation.concat(receiverType.sourceName, completion, '.'); 9532 9533 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 9534 proposal.setBinding(method); 9535 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9536 proposal.setSignature(getSignature(method)); 9537 MethodBinding original = method.original(); 9538 if(original != method) { 9539 proposal.setOriginalSignature(getSignature(original)); 9540 } 9541 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9542 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9543 proposal.setParameterPackageNames(parameterPackageNames); 9544 proposal.setParameterTypeNames(parameterTypeNames); 9545 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9546 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9547 proposal.setName(method.selector); 9548 proposal.setCompletion(completion); 9549 proposal.setFlags(method.modifiers); 9550 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9551 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9552 proposal.setRelevance(relevance); 9553 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9554 9555 char[] typeImportCompletion = createImportCharArray(typeName, false, false); 9556 9557 InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition); 9558 typeImportProposal.nameLookup = this.nameEnvironment.nameLookup; 9559 typeImportProposal.completionEngine = this; 9560 char[] packageName = receiverType.qualifiedPackageName(); 9561 typeImportProposal.setDeclarationSignature(packageName); 9562 typeImportProposal.setSignature(getSignature(receiverType)); 9563 typeImportProposal.setPackageName(packageName); 9564 typeImportProposal.setTypeName(receiverType.qualifiedSourceName()); 9565 typeImportProposal.setCompletion(typeImportCompletion); 9566 typeImportProposal.setFlags(receiverType.modifiers); 9567 typeImportProposal.setAdditionalFlags(CompletionFlags.Default); 9568 typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 9569 typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset); 9570 typeImportProposal.setRelevance(relevance); 9571 9572 proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal}); 9573 9574 this.requestor.accept(proposal); 9575 if(DEBUG) { 9576 this.printDebug(proposal); 9577 } 9578 } 9579 } else { 9580 if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) { 9581 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 9582 proposal.setBinding(method); 9583 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9584 proposal.setSignature(getSignature(method)); 9585 MethodBinding original = method.original(); 9586 if(original != method) { 9587 proposal.setOriginalSignature(getSignature(original)); 9588 } 9589 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9590 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9591 proposal.setParameterPackageNames(parameterPackageNames); 9592 proposal.setParameterTypeNames(parameterTypeNames); 9593 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9594 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9595 proposal.setName(method.selector); 9596 proposal.setCompletion(completion); 9597 proposal.setFlags(method.modifiers); 9598 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9599 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9600 proposal.setRelevance(relevance); 9601 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9602 9603 char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false); 9604 9605 InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition); 9606 methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass)); 9607 methodImportProposal.setSignature(getSignature(method)); 9608 if(original != method) { 9609 proposal.setOriginalSignature(getSignature(original)); 9610 } 9611 methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9612 methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9613 methodImportProposal.setParameterPackageNames(parameterPackageNames); 9614 methodImportProposal.setParameterTypeNames(parameterTypeNames); 9615 methodImportProposal.setPackageName(method.returnType.qualifiedPackageName()); 9616 methodImportProposal.setTypeName(method.returnType.qualifiedSourceName()); 9617 methodImportProposal.setName(method.selector); 9618 methodImportProposal.setCompletion(methodImportCompletion); 9619 methodImportProposal.setFlags(method.modifiers); 9620 methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport); 9621 methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset); 9622 methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset); 9623 methodImportProposal.setRelevance(relevance); 9624 if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames); 9625 9626 proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal}); 9627 9628 this.requestor.accept(proposal); 9629 if(DEBUG) { 9630 this.printDebug(proposal); 9631 } 9632 } 9633 } 9634 9635 this.startPosition = previousStartPosition; 9636 this.tokenStart = previousTokenStart; 9637 } 9638 } 9639 9640 /** 9641 * Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean) 9642 * Note that the method doesn't do a comparison of the method names and expects the client to handle the same. 9643 * 9644 * @methodName method as entered by the user, the one to completed 9645 * @param methods a resultant array of MethodBinding, whose names should match methodName. The calling client must ensure that this check is handled. 9646 */ findLocalMethodsFromStaticImports( char[] methodName, MethodBinding[] methods, Scope scope, boolean exactMatch, ObjectVector methodsFound, ReferenceBinding receiverType, InvocationSite invocationSite)9647 private void findLocalMethodsFromStaticImports( 9648 char[] methodName, 9649 MethodBinding[] methods, 9650 Scope scope, 9651 boolean exactMatch, 9652 ObjectVector methodsFound, 9653 ReferenceBinding receiverType, 9654 InvocationSite invocationSite) { 9655 9656 ObjectVector newMethodsFound = new ObjectVector(); 9657 9658 next : for (int f = methods.length; --f >= 0;) { 9659 MethodBinding method = methods[f]; 9660 9661 if (method.isSynthetic()) continue next; 9662 9663 if (method.isDefaultAbstract()) continue next; 9664 9665 if (method.isConstructor()) continue next; 9666 9667 if (!method.isStatic()) continue next; 9668 9669 if (this.options.checkDeprecation && 9670 method.isViewedAsDeprecated() && 9671 !scope.isDefinedInSameUnit(method.declaringClass)) 9672 continue next; 9673 9674 if (this.options.checkVisibility 9675 && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next; 9676 9677 for (int i = methodsFound.size; --i >= 0;) { 9678 Object[] other = (Object[]) methodsFound.elementAt(i); 9679 MethodBinding otherMethod = (MethodBinding) other[0]; 9680 ReferenceBinding otherReceiverType = (ReferenceBinding) other[1]; 9681 if (method == otherMethod && TypeBinding.equalsEquals(receiverType, otherReceiverType)) 9682 continue next; 9683 9684 if (CharOperation.equals(method.selector, otherMethod.selector, true)) { 9685 if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) { 9686 continue next; 9687 } 9688 } 9689 } 9690 9691 newMethodsFound.add(new Object[]{method, receiverType}); 9692 9693 int length = method.parameters.length; 9694 char[][] parameterPackageNames = new char[length][]; 9695 char[][] parameterTypeNames = new char[length][]; 9696 9697 for (int i = 0; i < length; i++) { 9698 TypeBinding type = method.original().parameters[i]; 9699 parameterPackageNames[i] = type.qualifiedPackageName(); 9700 parameterTypeNames[i] = type.qualifiedSourceName(); 9701 } 9702 char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames); 9703 9704 char[] completion = CharOperation.NO_CHAR; 9705 9706 int previousStartPosition = this.startPosition; 9707 int previousTokenStart = this.tokenStart; 9708 9709 if (!exactMatch) { 9710 if (this.source != null 9711 && this.source.length > this.endPosition 9712 && this.source[this.endPosition] == '(') { 9713 completion = method.selector; 9714 } else { 9715 completion = CharOperation.concat(method.selector, new char[] { '(', ')' }); 9716 } 9717 } else { 9718 this.startPosition = this.endPosition; 9719 this.tokenStart = this.tokenEnd; 9720 } 9721 9722 int relevance = computeBaseRelevance(); 9723 relevance += computeRelevanceForResolution(); 9724 relevance += computeRelevanceForInterestingProposal(); 9725 relevance += computeRelevanceForCaseMatching(methodName, method.selector); 9726 relevance += computeRelevanceForExpectingType(method.returnType); 9727 relevance += computeRelevanceForEnumConstant(method.returnType); 9728 relevance += computeRelevanceForStatic(true, method.isStatic()); 9729 relevance += computeRelevanceForQualification(false); 9730 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 9731 9732 this.noProposal = false; 9733 if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 9734 InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition); 9735 proposal.setBinding(method); 9736 proposal.setDeclarationSignature(getSignature(method.declaringClass)); 9737 proposal.setSignature(getSignature(method)); 9738 MethodBinding original = method.original(); 9739 if(original != method) { 9740 proposal.setOriginalSignature(getSignature(original)); 9741 } 9742 proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName()); 9743 proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName()); 9744 proposal.setParameterPackageNames(parameterPackageNames); 9745 proposal.setParameterTypeNames(parameterTypeNames); 9746 proposal.setPackageName(method.returnType.qualifiedPackageName()); 9747 proposal.setTypeName(method.returnType.qualifiedSourceName()); 9748 proposal.setName(method.selector); 9749 proposal.setCompletion(completion); 9750 proposal.setFlags(method.modifiers); 9751 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 9752 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 9753 proposal.setRelevance(relevance); 9754 if(parameterNames != null) proposal.setParameterNames(parameterNames); 9755 this.requestor.accept(proposal); 9756 if(DEBUG) { 9757 this.printDebug(proposal); 9758 } 9759 } 9760 this.startPosition = previousStartPosition; 9761 this.tokenStart = previousTokenStart; 9762 } 9763 9764 methodsFound.addAll(newMethodsFound); 9765 } 9766 findLocalMethodsFromStaticImports( char[] token, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean exactMatch, ObjectVector methodsFound, boolean proposeMethod)9767 private void findLocalMethodsFromStaticImports( 9768 char[] token, 9769 Scope scope, 9770 InvocationSite invocationSite, 9771 Scope invocationScope, 9772 boolean exactMatch, 9773 ObjectVector methodsFound, 9774 boolean proposeMethod) { 9775 findFieldsAndMethodsFromStaticImports( 9776 token, 9777 scope, 9778 invocationSite, 9779 invocationScope, 9780 exactMatch, 9781 false, 9782 new ObjectVector(), 9783 new ObjectVector(), 9784 methodsFound, 9785 false, 9786 proposeMethod); 9787 } findMembers( char[] token, ReferenceBinding receiverType, Scope scope, InvocationSite invocationSite, boolean isInsideAnnotationAttribute, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)9788 protected void findMembers( 9789 char[] token, 9790 ReferenceBinding receiverType, 9791 Scope scope, 9792 InvocationSite invocationSite, 9793 boolean isInsideAnnotationAttribute, 9794 Binding[] missingElements, 9795 int[] missingElementsStarts, 9796 int[] missingElementsEnds, 9797 boolean missingElementsHaveProblems) { 9798 9799 if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 9800 findMemberTypes( 9801 token, 9802 receiverType, 9803 scope, 9804 scope.enclosingSourceType(), 9805 false, 9806 true, 9807 new ObjectVector(), 9808 missingElements, 9809 missingElementsStarts, 9810 missingElementsEnds, 9811 missingElementsHaveProblems); 9812 } 9813 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 9814 findClassField( 9815 token, 9816 receiverType, 9817 scope, 9818 missingElements, 9819 missingElementsStarts, 9820 missingElementsEnds, 9821 missingElementsHaveProblems); 9822 } 9823 9824 MethodScope methodScope = null; 9825 if (!isInsideAnnotationAttribute && 9826 !this.requestor.isIgnored(CompletionProposal.KEYWORD) && 9827 ((scope instanceof MethodScope && !((MethodScope)scope).isStatic) 9828 || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) { 9829 if (token.length >= 0) { 9830 boolean isInterface = false; 9831 if (receiverType != null) { 9832 isInterface = receiverType.isInterface(); 9833 } 9834 if (!isInterface) { 9835 findKeywords(token, new char[][] { Keywords.THIS, Keywords.SUPER }, true, false); 9836 } else { 9837 boolean isEqual = false; 9838 char[] enclosingSourceName = null; 9839 if(scope.enclosingSourceType() != null) 9840 enclosingSourceName = scope.enclosingSourceType().sourceName; 9841 char[] receiverSourceName = null; 9842 if (receiverType != null) { 9843 receiverSourceName = receiverType.sourceName; 9844 } 9845 if( enclosingSourceName !=null & receiverSourceName !=null) 9846 isEqual = Arrays.equals(enclosingSourceName, receiverSourceName); 9847 if(isEqual) { 9848 findKeywords(token, new char[][] { Keywords.THIS }, true, false); 9849 } else { 9850 // Check if the enclosing source implements this interface then show super 9851 if (scope.enclosingSourceType() != null) { 9852 SourceTypeBinding src = scope.enclosingSourceType(); 9853 ReferenceBinding[] superInterfaces = src.superInterfaces(); 9854 boolean implemented = false; 9855 for (ReferenceBinding referenceBinding : superInterfaces) { 9856 if (Arrays.equals(referenceBinding.sourceName, receiverSourceName)) { 9857 implemented = true; 9858 break; 9859 } 9860 } 9861 if (implemented) { 9862 findKeywords(token, new char[][] { Keywords.SUPER }, true, false); 9863 } 9864 } 9865 } 9866 } 9867 } 9868 } 9869 9870 if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) { 9871 findFields( 9872 token, 9873 receiverType, 9874 scope, 9875 new ObjectVector(), 9876 new ObjectVector(), 9877 true, 9878 invocationSite, 9879 scope, 9880 false, 9881 false, 9882 missingElements, 9883 missingElementsStarts, 9884 missingElementsEnds, 9885 missingElementsHaveProblems, 9886 null, 9887 -1, 9888 -1); 9889 } 9890 9891 if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) { 9892 findMethods( 9893 token, 9894 null, 9895 null, 9896 receiverType, 9897 scope, 9898 new ObjectVector(), 9899 true, 9900 false, 9901 invocationSite, 9902 scope, 9903 false, 9904 false, 9905 false, 9906 missingElements, 9907 missingElementsStarts, 9908 missingElementsEnds, 9909 missingElementsHaveProblems, 9910 null, 9911 -1, 9912 -1); 9913 } 9914 } 9915 findMembersFromMissingType( final char[] token, final long pos, TypeBinding resolveType, final Scope scope, final InvocationSite invocationSite, final boolean isInsideAnnotationAttribute)9916 private void findMembersFromMissingType( 9917 final char[] token, 9918 final long pos, 9919 TypeBinding resolveType, 9920 final Scope scope, 9921 final InvocationSite invocationSite, 9922 final boolean isInsideAnnotationAttribute) { 9923 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 9924 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 9925 new MissingTypesGuesser.GuessedTypeRequestor() { 9926 @Override 9927 public void accept( 9928 TypeBinding guessedType, 9929 Binding[] missingElements, 9930 int[] missingElementsStarts, 9931 int[] missingElementsEnds, 9932 boolean hasProblems) { 9933 if (guessedType instanceof ReferenceBinding) { 9934 findMembers( 9935 CompletionEngine.this.completionToken, 9936 (ReferenceBinding)guessedType, 9937 scope, 9938 invocationSite, 9939 isInsideAnnotationAttribute, 9940 missingElements, 9941 missingElementsStarts, 9942 missingElementsEnds, 9943 hasProblems); 9944 } 9945 } 9946 }; 9947 SingleTypeReference typeRef = new SingleTypeReference(token, pos); 9948 typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound); 9949 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 9950 } 9951 findMemberTypes( char[] typeName, ReferenceBinding receiverType, Scope scope, SourceTypeBinding typeInvocation, boolean staticOnly, boolean staticFieldsAndMethodOnly, boolean fromStaticImport, boolean checkQualification, boolean proposeAllMemberTypes, SourceTypeBinding typeToIgnore, ObjectVector typesFound, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)9952 private void findMemberTypes( 9953 char[] typeName, 9954 ReferenceBinding receiverType, 9955 Scope scope, 9956 SourceTypeBinding typeInvocation, 9957 boolean staticOnly, 9958 boolean staticFieldsAndMethodOnly, 9959 boolean fromStaticImport, 9960 boolean checkQualification, 9961 boolean proposeAllMemberTypes, 9962 SourceTypeBinding typeToIgnore, 9963 ObjectVector typesFound, 9964 Binding[] missingElements, 9965 int[] missingElementsStarts, 9966 int[] missingElementsEnds, 9967 boolean missingElementsHaveProblems) { 9968 9969 ReferenceBinding currentType = receiverType; 9970 if (typeName == null) 9971 return; 9972 9973 if (this.insideQualifiedReference 9974 || typeName.length == 0) { // do not search up the hierarchy 9975 9976 findMemberTypes( 9977 typeName, 9978 currentType.memberTypes(), 9979 typesFound, 9980 receiverType, 9981 typeInvocation, 9982 staticOnly, 9983 staticFieldsAndMethodOnly, 9984 fromStaticImport, 9985 checkQualification, 9986 scope, 9987 missingElements, 9988 missingElementsStarts, 9989 missingElementsEnds, 9990 missingElementsHaveProblems); 9991 return; 9992 } 9993 9994 ReferenceBinding[] interfacesToVisit = null; 9995 int nextPosition = 0; 9996 9997 do { 9998 ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); 9999 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 10000 if (interfacesToVisit == null) { 10001 interfacesToVisit = itsInterfaces; 10002 nextPosition = interfacesToVisit.length; 10003 } else { 10004 int itsLength = itsInterfaces.length; 10005 if (nextPosition + itsLength >= interfacesToVisit.length) 10006 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 10007 nextInterface : for (int a = 0; a < itsLength; a++) { 10008 ReferenceBinding next = itsInterfaces[a]; 10009 for (int b = 0; b < nextPosition; b++) 10010 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 10011 interfacesToVisit[nextPosition++] = next; 10012 } 10013 } 10014 } 10015 10016 findMemberTypes( 10017 typeName, 10018 currentType.memberTypes(), 10019 typesFound, 10020 receiverType, 10021 typeInvocation, 10022 staticOnly, 10023 staticFieldsAndMethodOnly, 10024 fromStaticImport, 10025 checkQualification, 10026 scope, 10027 missingElements, 10028 missingElementsStarts, 10029 missingElementsEnds, 10030 missingElementsHaveProblems); 10031 10032 currentType = currentType.superclass(); 10033 } while (currentType != null); 10034 10035 if(proposeAllMemberTypes) { 10036 ReferenceBinding[] memberTypes = receiverType.memberTypes(); 10037 for (int i = 0; i < memberTypes.length; i++) { 10038 if(TypeBinding.notEquals(memberTypes[i], typeToIgnore)) { 10039 findSubMemberTypes( 10040 typeName, 10041 memberTypes[i], 10042 scope, 10043 typeInvocation, 10044 staticOnly, 10045 staticFieldsAndMethodOnly, 10046 fromStaticImport, 10047 typesFound); 10048 } 10049 } 10050 } 10051 10052 if (interfacesToVisit != null) { 10053 for (int i = 0; i < nextPosition; i++) { 10054 ReferenceBinding anInterface = interfacesToVisit[i]; 10055 findMemberTypes( 10056 typeName, 10057 anInterface.memberTypes(), 10058 typesFound, 10059 receiverType, 10060 typeInvocation, 10061 staticOnly, 10062 staticFieldsAndMethodOnly, 10063 fromStaticImport, 10064 checkQualification, 10065 scope, 10066 missingElements, 10067 missingElementsStarts, 10068 missingElementsEnds, 10069 missingElementsHaveProblems); 10070 10071 ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); 10072 if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) { 10073 int itsLength = itsInterfaces.length; 10074 if (nextPosition + itsLength >= interfacesToVisit.length) 10075 System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition); 10076 nextInterface : for (int a = 0; a < itsLength; a++) { 10077 ReferenceBinding next = itsInterfaces[a]; 10078 for (int b = 0; b < nextPosition; b++) 10079 if (TypeBinding.equalsEquals(next, interfacesToVisit[b])) continue nextInterface; 10080 interfacesToVisit[nextPosition++] = next; 10081 } 10082 } 10083 } 10084 } 10085 } 10086 findMemberTypes( char[] typeName, ReferenceBinding receiverType, Scope scope, SourceTypeBinding typeInvocation, boolean staticOnly, boolean staticFieldsAndMethodOnly, ObjectVector typesFound, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)10087 protected void findMemberTypes( 10088 char[] typeName, 10089 ReferenceBinding receiverType, 10090 Scope scope, 10091 SourceTypeBinding typeInvocation, 10092 boolean staticOnly, 10093 boolean staticFieldsAndMethodOnly, 10094 ObjectVector typesFound, 10095 Binding[] missingElements, 10096 int[] missingElementsStarts, 10097 int[] missingElementsEnds, 10098 boolean missingElementsHaveProblems) { 10099 findMemberTypes( 10100 typeName, 10101 receiverType, 10102 scope, 10103 typeInvocation, 10104 staticOnly, 10105 staticFieldsAndMethodOnly, 10106 false, 10107 false, 10108 false, 10109 null, 10110 typesFound, 10111 missingElements, 10112 missingElementsStarts, 10113 missingElementsEnds, 10114 missingElementsHaveProblems); 10115 } 10116 // Helper method for findMemberTypes(char[], ReferenceBinding, Scope) findMemberTypes( char[] typeName, ReferenceBinding[] memberTypes, ObjectVector typesFound, ReferenceBinding receiverType, SourceTypeBinding invocationType, boolean staticOnly, boolean staticFieldsAndMethodOnly, boolean fromStaticImport, boolean checkQualification, Scope scope, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)10117 private void findMemberTypes( 10118 char[] typeName, 10119 ReferenceBinding[] memberTypes, 10120 ObjectVector typesFound, 10121 ReferenceBinding receiverType, 10122 SourceTypeBinding invocationType, 10123 boolean staticOnly, 10124 boolean staticFieldsAndMethodOnly, 10125 boolean fromStaticImport, 10126 boolean checkQualification, 10127 Scope scope, 10128 Binding[] missingElements, 10129 int[] missingElementsStarts, 10130 int[] missingElementsEnds, 10131 boolean missingElementsHaveProblems) { 10132 10133 // Inherited member types which are hidden by subclasses are filtered out 10134 // No visibility checks can be performed without the scope & invocationSite 10135 int typeLength = typeName.length; 10136 next : for (int m = memberTypes.length; --m >= 0;) { 10137 ReferenceBinding memberType = memberTypes[m]; 10138 // if (!wantClasses && memberType.isClass()) continue next; 10139 // if (!wantInterfaces && memberType.isInterface()) continue next; 10140 10141 if (staticOnly && !memberType.isStatic()) continue next; 10142 10143 if (isForbidden(memberType)) continue next; 10144 10145 if (typeLength > memberType.sourceName.length) 10146 continue next; 10147 10148 if (isFailedMatch(typeName, memberType.sourceName)) 10149 continue next; 10150 10151 if (this.options.checkDeprecation && 10152 memberType.isViewedAsDeprecated() && 10153 !scope.isDefinedInSameUnit(memberType)) 10154 continue next; 10155 10156 if (this.options.checkVisibility) { 10157 if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) { 10158 continue next; 10159 } else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) { 10160 continue next; 10161 } 10162 } 10163 10164 if (this.insideQualifiedReference && 10165 receiverType.isParameterizedType() && 10166 memberType.isStatic()) { 10167 continue next; 10168 } 10169 10170 for (int i = typesFound.size; --i >= 0;) { 10171 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i); 10172 10173 if (TypeBinding.equalsEquals(memberType, otherType)) 10174 continue next; 10175 10176 if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true) 10177 && otherType.isNestedType()) { 10178 10179 if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType())) 10180 continue next; 10181 10182 if (otherType.enclosingType().isInterface()) 10183 if (memberType.enclosingType() 10184 .implementsInterface(otherType.enclosingType(), true)) 10185 continue next; 10186 10187 if (memberType.enclosingType().isInterface()) 10188 if (otherType.enclosingType() 10189 .implementsInterface(memberType.enclosingType(), true)) 10190 continue next; 10191 } 10192 } 10193 10194 typesFound.add(memberType); 10195 10196 if (this.assistNodeIsExtendedType && memberType.isFinal()) continue next; 10197 if (this.assistNodeIsInterfaceExcludingAnnotation && memberType.isAnnotationType()) continue next; 10198 if(!this.insideQualifiedReference) { 10199 if(this.assistNodeIsClass || this.assistNodeIsException) { 10200 if(!memberType.isClass()) continue next; 10201 } else if(this.assistNodeIsInterface) { 10202 if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next; 10203 } else if (this.assistNodeIsAnnotation) { 10204 if(!memberType.isAnnotationType()) continue next; 10205 } 10206 } 10207 10208 char[] completionName = memberType.sourceName(); 10209 10210 boolean isQualified = false; 10211 if(checkQualification && !fromStaticImport) { 10212 char[] memberPackageName = memberType.qualifiedPackageName(); 10213 char[] memberTypeName = memberType.sourceName(); 10214 char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName(); 10215 if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) { 10216 if (memberPackageName == null || memberPackageName.length == 0) 10217 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 10218 break next; // ignore types from the default package from outside it 10219 isQualified = true; 10220 completionName = 10221 CharOperation.concat( 10222 memberPackageName, 10223 CharOperation.concat( 10224 memberEnclosingTypeNames, 10225 memberTypeName, 10226 '.'), 10227 '.'); 10228 } 10229 } 10230 10231 int relevance = computeBaseRelevance(); 10232 relevance += computeRelevanceForResolution(); 10233 relevance += computeRelevanceForInterestingProposal(memberType); 10234 relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName); 10235 relevance += computeRelevanceForExpectingType(memberType); 10236 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 10237 if(!this.insideQualifiedReference) { 10238 relevance += computeRelevanceForQualification(isQualified); 10239 } 10240 if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED; // This criterion doesn't concern types and is added to be balanced with field and method relevance. 10241 10242 if (memberType.isAnnotationType()) { 10243 relevance += computeRelevanceForAnnotation(); 10244 relevance += computeRelevanceForAnnotationTarget(memberType); 10245 } else if (memberType.isClass()) { 10246 relevance += computeRelevanceForClass(); 10247 relevance += computeRelevanceForException(memberType.sourceName); 10248 } else if(memberType.isEnum()) { 10249 relevance += computeRelevanceForEnum(); 10250 } else if(memberType.isInterface()) { 10251 relevance += computeRelevanceForInterface(); 10252 } 10253 10254 if (missingElements != null) { 10255 relevance += computeRelevanceForMissingElements(missingElementsHaveProblems); 10256 } 10257 10258 boolean allowingLongComputationProposals = isAllowingLongComputationProposals(); 10259 10260 this.noProposal = false; 10261 if (!this.assistNodeIsConstructor || 10262 !allowingLongComputationProposals || 10263 hasStaticMemberTypes(memberType, invocationType, this.unitScope) || 10264 (memberType instanceof SourceTypeBinding && hasMemberTypesInEnclosingScope((SourceTypeBinding)memberType, scope)) || 10265 hasArrayTypeAsExpectedSuperTypes()) { 10266 createTypeProposal( 10267 memberType, 10268 memberType.qualifiedSourceName(), 10269 IAccessRule.K_ACCESSIBLE, 10270 completionName, 10271 relevance, 10272 missingElements, 10273 missingElementsStarts, 10274 missingElementsEnds, 10275 missingElementsHaveProblems); 10276 } 10277 10278 if (this.assistNodeIsConstructor && allowingLongComputationProposals) { 10279 findConstructorsOrAnonymousTypes( 10280 memberType, 10281 scope, 10282 FakeInvocationSite, 10283 isQualified, 10284 relevance); 10285 } 10286 } 10287 } findMemberTypesFromMissingType( char[] typeName, final long pos, final Scope scope)10288 private void findMemberTypesFromMissingType( 10289 char[] typeName, 10290 final long pos, 10291 final Scope scope) { 10292 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 10293 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 10294 new MissingTypesGuesser.GuessedTypeRequestor() { 10295 @Override 10296 public void accept( 10297 TypeBinding guessedType, 10298 Binding[] missingElements, 10299 int[] missingElementsStarts, 10300 int[] missingElementsEnds, 10301 boolean hasProblems) { 10302 if (guessedType instanceof ReferenceBinding) { 10303 findMemberTypes( 10304 CompletionEngine.this.completionToken, 10305 (ReferenceBinding)guessedType, 10306 scope, 10307 scope.enclosingSourceType(), 10308 false, 10309 false, 10310 new ObjectVector(), 10311 missingElements, 10312 missingElementsStarts, 10313 missingElementsEnds, 10314 hasProblems); 10315 } 10316 } 10317 }; 10318 SingleTypeReference typeRef = new SingleTypeReference(typeName, pos); 10319 typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound); 10320 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 10321 } 10322 findMemberTypesFromMissingType( TypeReference typeRef, final long pos, final Scope scope)10323 private void findMemberTypesFromMissingType( 10324 TypeReference typeRef, 10325 final long pos, 10326 final Scope scope) { 10327 MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this); 10328 MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor = 10329 new MissingTypesGuesser.GuessedTypeRequestor() { 10330 @Override 10331 public void accept( 10332 TypeBinding guessedType, 10333 Binding[] missingElements, 10334 int[] missingElementsStarts, 10335 int[] missingElementsEnds, 10336 boolean hasProblems) { 10337 if (guessedType instanceof ReferenceBinding) { 10338 findMemberTypes( 10339 CompletionEngine.this.completionToken, 10340 (ReferenceBinding)guessedType, 10341 scope, 10342 scope.enclosingSourceType(), 10343 false, 10344 false, 10345 new ObjectVector(), 10346 missingElements, 10347 missingElementsStarts, 10348 missingElementsEnds, 10349 hasProblems); 10350 } 10351 } 10352 }; 10353 missingTypesConverter.guess(typeRef, scope, substitutionRequestor); 10354 } 10355 findMethodDeclarations( char[] selector, ReferenceBinding receiverType, Scope scope, ObjectVector methodsFound, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems)10356 private void findMethodDeclarations( 10357 char[] selector, 10358 ReferenceBinding receiverType, 10359 Scope scope, 10360 ObjectVector methodsFound, 10361 Binding[] missingElements, 10362 int[] missingElementsStarts, 10363 int[] missingElementsEnds, 10364 boolean missingElementsHaveProblems) { 10365 10366 if (selector == null) { 10367 return; 10368 } 10369 10370 MethodBinding[] receiverTypeMethods = receiverType.availableMethods(); 10371 if (receiverTypeMethods != null){ 10372 for (int i = 0; i < receiverTypeMethods.length; i++) { 10373 if(!receiverTypeMethods[i].isDefaultAbstract()) { 10374 methodsFound.add(receiverTypeMethods[i]); 10375 } 10376 } 10377 } 10378 10379 ReferenceBinding currentType = receiverType; 10380 10381 findInterfacesMethodDeclarations( 10382 selector, 10383 receiverType, 10384 currentType.superInterfaces(), 10385 scope, 10386 methodsFound, 10387 missingElements, 10388 missingElementsStarts, 10389 missingElementsEnds, 10390 missingElementsHaveProblems); 10391 10392 if (receiverType.isInterface()) { 10393 currentType = scope.getJavaLangObject(); 10394 } else { 10395 currentType = receiverType.superclass(); 10396 } 10397 10398 boolean hasPotentialDefaultAbstractMethods = true; 10399 boolean java8Plus = this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8; 10400 while (currentType != null) { 10401 10402 MethodBinding[] methods = currentType.availableMethods(); 10403 if (methods != null) { 10404 findLocalMethodDeclarations( 10405 selector, 10406 methods, 10407 scope, 10408 methodsFound, 10409 false, 10410 receiverType); 10411 } 10412 10413 if (hasPotentialDefaultAbstractMethods && (java8Plus || 10414 (currentType.isAbstract() || 10415 currentType.isTypeVariable() || 10416 currentType.isIntersectionType() || 10417 currentType.isEnum()))){ 10418 10419 ReferenceBinding[] superInterfaces = currentType.superInterfaces(); 10420 10421 findInterfacesMethodDeclarations( 10422 selector, 10423 receiverType, 10424 superInterfaces, 10425 scope, 10426 methodsFound, 10427 missingElements, 10428 missingElementsStarts, 10429 missingElementsEnds, 10430 missingElementsHaveProblems); 10431 } else { 10432 hasPotentialDefaultAbstractMethods = false; 10433 } 10434 currentType = currentType.superclass(); 10435 } 10436 } 10437 findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames)10438 private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){ 10439 TypeBinding erasure = method.declaringClass.erasure(); 10440 if(!(erasure instanceof ReferenceBinding)) return null; 10441 10442 char[][] parameterNames = null; 10443 10444 int length = parameterTypeNames.length; 10445 10446 if (length == 0){ 10447 return CharOperation.NO_CHAR_CHAR; 10448 } 10449 // look into the corresponding unit if it is available 10450 if (erasure instanceof SourceTypeBinding){ 10451 SourceTypeBinding sourceType = (SourceTypeBinding) erasure; 10452 10453 if (sourceType.scope != null){ 10454 TypeDeclaration parsedType; 10455 10456 if ((parsedType = sourceType.scope.referenceContext) != null){ 10457 AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original()); 10458 10459 if (methodDecl != null){ 10460 Argument[] arguments = methodDecl.arguments; 10461 parameterNames = new char[length][]; 10462 10463 for(int i = 0 ; i < length ; i++){ 10464 parameterNames[i] = arguments[i].name; 10465 } 10466 } 10467 } 10468 } 10469 } 10470 // look into the model 10471 if(parameterNames == null){ 10472 10473 ReferenceBinding bindingType = (ReferenceBinding)erasure; 10474 10475 char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.'); 10476 Object type = this.typeCache.get(compoundName); 10477 10478 ISourceType sourceType = null; 10479 if(type != null) { 10480 if(type instanceof ISourceType) { 10481 sourceType = (ISourceType) type; 10482 } 10483 } else { 10484 NameEnvironmentAnswer answer = this.nameEnvironment.findTypeInModules(bindingType.compoundName, this.unitScope.module()); 10485 if(answer != null && answer.isSourceType()) { 10486 sourceType = answer.getSourceTypes()[0]; 10487 this.typeCache.put(compoundName, sourceType); 10488 } 10489 } 10490 10491 if(sourceType != null) { 10492 IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle(); 10493 10494 String[] parameterTypeSignatures = new String[length]; 10495 for (int i = 0; i < length; i++) { 10496 parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false); 10497 } 10498 IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures); 10499 IMethod[] foundMethods = typeHandle.findMethods(searchedMethod); 10500 10501 if(foundMethods != null) { 10502 int len = foundMethods.length; 10503 if(len == 1) { 10504 try { 10505 SourceMethod sourceMethod = (SourceMethod) foundMethods[0]; 10506 parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames(); 10507 } catch (JavaModelException e) { 10508 // method doesn't exist: ignore 10509 } 10510 } 10511 } 10512 } 10513 } 10514 return parameterNames; 10515 } 10516 findMethods( char[] selector, TypeBinding[] typeArgTypes, TypeBinding[] argTypes, ReferenceBinding receiverType, Scope scope, ObjectVector methodsFound, boolean onlyStaticMethods, boolean exactMatch, InvocationSite invocationSite, Scope invocationScope, boolean implicitCall, boolean superCall, boolean canBePrefixed, Binding[] missingElements, int[] missingElementsStarts, int[] missingElementsEnds, boolean missingElementsHaveProblems, char[] castedReceiver, int receiverStart, int receiverEnd)10517 private void findMethods( 10518 char[] selector, 10519 TypeBinding[] typeArgTypes, 10520 TypeBinding[] argTypes, 10521 ReferenceBinding receiverType, 10522 Scope scope, 10523 ObjectVector methodsFound, 10524 boolean onlyStaticMethods, 10525 boolean exactMatch, 10526 InvocationSite invocationSite, 10527 Scope invocationScope, 10528 boolean implicitCall, 10529 boolean superCall, 10530 boolean canBePrefixed, 10531 Binding[] missingElements, 10532 int[] missingElementsStarts, 10533 int[] missingElementsEnds, 10534 boolean missingElementsHaveProblems, 10535 char[] castedReceiver, 10536 int receiverStart, 10537 int receiverEnd) { 10538 10539 boolean notInJavadoc = this.assistNodeInJavadoc == 0; 10540 if (selector == null && notInJavadoc) { 10541 return; 10542 } 10543 10544 if (this.assistNodeIsInsideCase) 10545 return; // no methods should be proposed inside case expression 10546 10547 ReferenceBinding currentType = receiverType; 10548 if (notInJavadoc) { 10549 if (receiverType.isInterface()) { 10550 findInterfacesMethods( 10551 selector, 10552 typeArgTypes, 10553 argTypes, 10554 receiverType, 10555 new ReferenceBinding[]{currentType}, 10556 scope, 10557 methodsFound, 10558 onlyStaticMethods, 10559 exactMatch, 10560 invocationSite, 10561 invocationScope, 10562 implicitCall, 10563 superCall, 10564 canBePrefixed, 10565 missingElements, 10566 missingElementsStarts, 10567 missingElementsEnds, 10568 missingElementsHaveProblems, 10569 castedReceiver, 10570 receiverStart, 10571 receiverEnd); 10572 10573 currentType = scope.getJavaLangObject(); 10574 } 10575 } 10576 boolean hasPotentialDefaultAbstractMethods = true; 10577 boolean java8Plus = this.compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8; 10578 while (currentType != null) { 10579 10580 MethodBinding[] methods = currentType.availableMethods(); 10581 if (methods != null) { 10582 findLocalMethods( 10583 selector, 10584 typeArgTypes, 10585 argTypes, 10586 methods, 10587 scope, 10588 methodsFound, 10589 onlyStaticMethods, 10590 exactMatch, 10591 receiverType, 10592 invocationSite, 10593 invocationScope, 10594 implicitCall, 10595 superCall, 10596 canBePrefixed, 10597 missingElements, 10598 missingElementsStarts, 10599 missingElementsEnds, 10600 missingElementsHaveProblems, 10601 castedReceiver, 10602 receiverStart, 10603 receiverEnd); 10604 } 10605 10606 /* Searching of superinterfaces for candidate proposal methods can be skipped if current type is concrete, but only for source levels below 1.8. 10607 For 1.8 even a concrete type's superinterfaces should be searched as they could have default methods which are not implemented by the concrete 10608 type. 10609 */ 10610 if (hasPotentialDefaultAbstractMethods && 10611 (java8Plus || (currentType.isAbstract() || currentType.isTypeVariable() || currentType.isIntersectionType() || currentType.isEnum()))) { 10612 10613 ReferenceBinding[] superInterfaces = currentType.superInterfaces(); 10614 if (superInterfaces != null && currentType.isIntersectionType()) { 10615 for (int i = 0; i < superInterfaces.length; i++) { 10616 superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceStart(), invocationSite.sourceEnd()); 10617 } 10618 } 10619 10620 findInterfacesMethods( 10621 selector, 10622 typeArgTypes, 10623 argTypes, 10624 receiverType, 10625 superInterfaces, 10626 scope, 10627 methodsFound, 10628 onlyStaticMethods, 10629 exactMatch, 10630 invocationSite, 10631 invocationScope, 10632 implicitCall, 10633 superCall, 10634 canBePrefixed, 10635 missingElements, 10636 missingElementsStarts, 10637 missingElementsEnds, 10638 missingElementsHaveProblems, 10639 castedReceiver, 10640 receiverStart, 10641 receiverEnd); 10642 } else { 10643 if (!java8Plus) 10644 hasPotentialDefaultAbstractMethods = false; 10645 } 10646 currentType = currentType.superclass(); 10647 } 10648 } 10649 findNestedTypes( char[] typeName, SourceTypeBinding currentType, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound)10650 private void findNestedTypes( 10651 char[] typeName, 10652 SourceTypeBinding currentType, 10653 Scope scope, 10654 boolean proposeAllMemberTypes, 10655 ObjectVector typesFound) { 10656 10657 if (typeName == null) 10658 return; 10659 10660 int typeLength = typeName.length; 10661 10662 SourceTypeBinding nextTypeToIgnore = null; 10663 while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found 10664 10665 switch (scope.kind) { 10666 10667 case Scope.METHOD_SCOPE : 10668 case Scope.BLOCK_SCOPE : 10669 BlockScope blockScope = (BlockScope) scope; 10670 10671 next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) { 10672 10673 if (blockScope.subscopes[i] instanceof ClassScope) { 10674 SourceTypeBinding localType = 10675 ((ClassScope) blockScope.subscopes[i]).referenceContext.binding; 10676 10677 if (!localType.isAnonymousType()) { 10678 if (isForbidden(localType)) 10679 continue next; 10680 10681 if (typeLength > localType.sourceName.length) 10682 continue next; 10683 if (isFailedMatch(typeName, localType.sourceName)) 10684 continue next; 10685 10686 for (int j = typesFound.size; --j >= 0;) { 10687 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 10688 10689 if (TypeBinding.equalsEquals(localType, otherType)) 10690 continue next; 10691 } 10692 10693 if (this.assistNodeIsExtendedType && localType.isFinal()) continue next; 10694 if (this.assistNodeIsInterfaceExcludingAnnotation && localType.isAnnotationType()) continue next; 10695 if(this.assistNodeIsClass) { 10696 if(!localType.isClass()) continue next; 10697 } else if(this.assistNodeIsInterface) { 10698 if(!localType.isInterface() && !localType.isAnnotationType()) continue next; 10699 } else if (this.assistNodeIsAnnotation) { 10700 if(!localType.isAnnotationType()) continue next; 10701 } 10702 10703 int relevance = computeBaseRelevance(); 10704 relevance += computeRelevanceForResolution(); 10705 relevance += computeRelevanceForInterestingProposal(localType); 10706 relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName); 10707 relevance += computeRelevanceForExpectingType(localType); 10708 relevance += computeRelevanceForException(localType.sourceName); 10709 relevance += computeRelevanceForClass(); 10710 relevance += computeRelevanceForQualification(false); 10711 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type 10712 relevance += computeRelevanceForAnnotationTarget(localType); 10713 10714 boolean allowingLongComputationProposals = isAllowingLongComputationProposals(); 10715 if (!this.assistNodeIsConstructor || !allowingLongComputationProposals || hasArrayTypeAsExpectedSuperTypes()) { 10716 this.noProposal = false; 10717 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 10718 createTypeProposal( 10719 localType, 10720 localType.sourceName, 10721 IAccessRule.K_ACCESSIBLE, 10722 localType.sourceName, 10723 relevance, 10724 null, 10725 null, 10726 null, 10727 false); 10728 } 10729 } 10730 10731 if (this.assistNodeIsConstructor && allowingLongComputationProposals) { 10732 findConstructorsOrAnonymousTypes( 10733 localType, 10734 blockScope, 10735 FakeInvocationSite, 10736 false, 10737 relevance); 10738 } 10739 } 10740 } 10741 } 10742 break; 10743 10744 case Scope.CLASS_SCOPE : 10745 SourceTypeBinding enclosingSourceType = scope.enclosingSourceType(); 10746 findMemberTypes( 10747 typeName, 10748 enclosingSourceType, 10749 scope, 10750 currentType, 10751 false, 10752 false, 10753 false, 10754 false, 10755 proposeAllMemberTypes, 10756 nextTypeToIgnore, 10757 typesFound, 10758 null, 10759 null, 10760 null, 10761 false); 10762 nextTypeToIgnore = enclosingSourceType; 10763 if (typeLength == 0) 10764 return; // do not search outside the class scope if no prefix was provided 10765 break; 10766 10767 case Scope.COMPILATION_UNIT_SCOPE : 10768 return; 10769 } 10770 scope = scope.parent; 10771 } 10772 } 10773 proposeModuleName(CompilationUnitDeclaration parsedUnit)10774 private void proposeModuleName(CompilationUnitDeclaration parsedUnit) { 10775 String projectName = this.javaProject.getElementName(); 10776 char[] moduleName = projectName.toCharArray(); 10777 if (moduleName.length > 0) {// do not propose invalid names 10778 if (!Character.isJavaIdentifierStart(moduleName[0])) return; 10779 for (char c : moduleName) { 10780 if (!Character.isJavaIdentifierPart(c) && c != '.') return; 10781 } 10782 } 10783 this.completionToken = CharOperation.concatWith(this.moduleDeclaration.tokens, '.'); 10784 setSourceRange(this.moduleDeclaration.sourceStart, this.moduleDeclaration.bodyStart); 10785 if (this.completionToken.length > 0 && !CharOperation.prefixEquals(this.completionToken, moduleName)) return; 10786 10787 InternalCompletionProposal proposal = createProposal(CompletionProposal.MODULE_DECLARATION, this.actualCompletionPosition); 10788 proposal.setName(moduleName); 10789 proposal.setDeclarationSignature(moduleName); 10790 proposal.setCompletion(moduleName); 10791 proposal.setReplaceRange((this.startPosition < 0) ? 0 : this.startPosition - this.offset, this.endPosition - this.offset); 10792 proposal.setTokenRange((this.tokenStart < 0) ? 0 : this.tokenStart - this.offset, this.tokenEnd - this.offset); 10793 proposal.setRelevance(R_MODULE_DECLARATION); 10794 this.requestor.accept(proposal); 10795 if(DEBUG) { 10796 this.printDebug(proposal); 10797 } 10798 } 10799 getAllJarModuleNames(IJavaProject javaProject2)10800 private HashSet<String> getAllJarModuleNames(IJavaProject javaProject2) { 10801 HashSet<String> modules = new HashSet<>(); 10802 try { 10803 for (IPackageFragmentRoot root : javaProject2.getAllPackageFragmentRoots()) { 10804 if (root instanceof JarPackageFragmentRoot) { 10805 IModuleDescription desc = root.getModuleDescription(); 10806 desc = desc == null ? ((JarPackageFragmentRoot) root).getAutomaticModuleDescription() : desc; 10807 String name = desc != null ? desc.getElementName() : null; 10808 if (name != null && name.length() > 0) 10809 modules.add(name); 10810 } 10811 } 10812 } catch (JavaModelException e) { 10813 // do nothing 10814 } 10815 return modules; 10816 } findTargettedModules(char[] prefix, HashSet<String> skipSet)10817 private void findTargettedModules(char[] prefix, HashSet<String> skipSet) { 10818 HashSet<String> probableModules = new HashSet<>(); 10819 ModuleSourcePathManager mManager = JavaModelManager.getModulePathManager(); 10820 JavaElementRequestor javaElementRequestor = new JavaElementRequestor(); 10821 try { 10822 mManager.seekModule(this.completionToken, true, javaElementRequestor); 10823 IModuleDescription[] modules = javaElementRequestor.getModules(); 10824 for (IModuleDescription module : modules) { 10825 String name = module.getElementName(); 10826 if (name == null || name.equals("")) //$NON-NLS-1$ 10827 continue; 10828 probableModules.add(name); 10829 } 10830 } catch (JavaModelException e) { 10831 // TODO ignore for now 10832 } 10833 probableModules.addAll(getAllJarModuleNames(this.javaProject)); 10834 if (prefix != CharOperation.ALL_PREFIX && prefix != null && prefix.length > 0) { 10835 probableModules.removeIf(e -> isFailedMatch(prefix, e.toCharArray())); 10836 } 10837 for (String s : probableModules) { 10838 if (!skipSet.contains(s)) 10839 this.acceptModule(s.toCharArray()); 10840 } 10841 } findTargettedModules(CompletionOnModuleReference moduleReference, HashSet<String> skipSet)10842 private void findTargettedModules(CompletionOnModuleReference moduleReference, HashSet<String> skipSet) { 10843 setCompletionToken(moduleReference.tokens, moduleReference.sourceStart, moduleReference.sourceEnd, moduleReference.sourcePositions); 10844 findTargettedModules(CharOperation.toLowerCase(this.completionToken), skipSet); 10845 } 10846 setCompletionToken(char[][] tokens, int sourceStart, int sourceEnd, long[] sourcePositions, boolean without)10847 private void setCompletionToken(char[][] tokens, int sourceStart, int sourceEnd, long[] sourcePositions, boolean without) { 10848 this.completionToken = without ? CharOperation.concatWith(tokens, '.') : CharOperation.concatWithAll(tokens, '.'); 10849 if (this.completionToken.length == 0) 10850 this.completionToken = CharOperation.ALL_PREFIX; 10851 setSourceRange(sourceStart, sourceEnd); 10852 long completionPosition = sourcePositions[sourcePositions.length - 1]; 10853 setTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 10854 } setCompletionToken(char[][] tokens, int sourceStart, int sourceEnd, long[] sourcePositions)10855 private void setCompletionToken(char[][] tokens, int sourceStart, int sourceEnd, long[] sourcePositions) { 10856 setCompletionToken(tokens, sourceStart, sourceEnd, sourcePositions, tokens.length > 0 && tokens[tokens.length - 1].length > 0); 10857 } findModules(CompletionOnModuleReference moduleReference, boolean targetted)10858 private void findModules(CompletionOnModuleReference moduleReference, boolean targetted) { 10859 setCompletionToken(moduleReference.tokens, moduleReference.sourceStart, moduleReference.sourceEnd, moduleReference.sourcePositions); 10860 findTargettedModules(moduleReference, new HashSet<>()); // empty skipSet passed 10861 this.nameEnvironment.findModules(CharOperation.toLowerCase(this.completionToken), this, targetted ? this.javaProject : null); 10862 } findPackages(CompletionOnPackageVisibilityReference reference)10863 private void findPackages(CompletionOnPackageVisibilityReference reference) { 10864 setCompletionToken(reference.tokens, reference.sourceStart, reference.sourceEnd, reference.sourcePositions, false); 10865 findPackagesInCurrentModule(); 10866 } 10867 findPackagesInCurrentModule()10868 private void findPackagesInCurrentModule() { 10869 try { 10870 IPackageFragmentRoot[] moduleRoots = SearchableEnvironment.getOwnedPackageFragmentRoots(this.javaProject); 10871 this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this, moduleRoots, false); 10872 } catch (JavaModelException e) { 10873 // silent 10874 } 10875 } findPackages(CompletionOnPackageReference packageStatement)10876 private void findPackages(CompletionOnPackageReference packageStatement) { 10877 this.completionToken = CharOperation.concatWithAll(packageStatement.tokens, '.'); 10878 if (this.completionToken.length == 0) 10879 return; 10880 setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd); 10881 long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1]; 10882 setTokenRange((int) (completionPosition >>> 32), (int) completionPosition); 10883 try { 10884 this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this, this.javaProject.getAllPackageFragmentRoots(), true); 10885 } catch (JavaModelException e) { 10886 // silent 10887 } 10888 } 10889 findParameterizedType(TypeReference ref, Scope scope)10890 private void findParameterizedType(TypeReference ref, Scope scope) { 10891 ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType; 10892 if(refBinding != null) { 10893 if (this.options.checkDeprecation && 10894 refBinding.isViewedAsDeprecated() && 10895 !scope.isDefinedInSameUnit(refBinding)) 10896 return; 10897 10898 int accessibility = IAccessRule.K_ACCESSIBLE; 10899 if(refBinding.hasRestrictedAccess()) { 10900 AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding); 10901 if(accessRestriction != null) { 10902 switch (accessRestriction.getProblemId()) { 10903 case IProblem.ForbiddenReference: 10904 if (this.options.checkForbiddenReference) { 10905 return; 10906 } 10907 accessibility = IAccessRule.K_NON_ACCESSIBLE; 10908 break; 10909 case IProblem.DiscouragedReference: 10910 if (this.options.checkDiscouragedReference) { 10911 return; 10912 } 10913 accessibility = IAccessRule.K_DISCOURAGED; 10914 break; 10915 } 10916 } 10917 } 10918 10919 int relevance = computeBaseRelevance(); 10920 relevance += computeRelevanceForResolution(); 10921 relevance += computeRelevanceForInterestingProposal(); 10922 relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName); 10923 relevance += computeRelevanceForExpectingType(refBinding); 10924 relevance += computeRelevanceForQualification(false); 10925 relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit 10926 10927 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 10928 createTypeProposal( 10929 refBinding, 10930 refBinding.qualifiedSourceName(), 10931 IAccessRule.K_ACCESSIBLE, 10932 CharOperation.NO_CHAR, 10933 relevance, 10934 null, 10935 null, 10936 null, 10937 false); 10938 } 10939 } 10940 } 10941 findSubMemberTypes( char[] typeName, ReferenceBinding receiverType, Scope scope, SourceTypeBinding typeInvocation, boolean staticOnly, boolean staticFieldsAndMethodOnly, boolean fromStaticImport, ObjectVector typesFound)10942 private void findSubMemberTypes( 10943 char[] typeName, 10944 ReferenceBinding receiverType, 10945 Scope scope, 10946 SourceTypeBinding typeInvocation, 10947 boolean staticOnly, 10948 boolean staticFieldsAndMethodOnly, 10949 boolean fromStaticImport, 10950 ObjectVector typesFound) { 10951 10952 ReferenceBinding currentType = receiverType; 10953 if (typeName == null) 10954 return; 10955 10956 if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype 10957 10958 findMemberTypes( 10959 typeName, 10960 currentType.memberTypes(), 10961 typesFound, 10962 receiverType, 10963 typeInvocation, 10964 staticOnly, 10965 staticFieldsAndMethodOnly, 10966 fromStaticImport, 10967 true, 10968 scope, 10969 null, 10970 null, 10971 null, 10972 false); 10973 10974 ReferenceBinding[] memberTypes = receiverType.memberTypes(); 10975 next : for (int i = 0; i < memberTypes.length; i++) { 10976 if (this.options.checkVisibility) { 10977 if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) { 10978 continue next; 10979 } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) { 10980 continue next; 10981 } 10982 } 10983 findSubMemberTypes( 10984 typeName, 10985 memberTypes[i], 10986 scope, 10987 typeInvocation, 10988 staticOnly, 10989 staticFieldsAndMethodOnly, 10990 fromStaticImport, 10991 typesFound); 10992 } 10993 } 10994 findTrueOrFalseKeywords(char[][] choices)10995 private void findTrueOrFalseKeywords(char[][] choices) { 10996 if(choices == null || choices.length == 0) return; 10997 10998 if(this.expectedTypesPtr != 0 || TypeBinding.notEquals(this.expectedTypes[0], TypeBinding.BOOLEAN)) return; 10999 11000 for (int i = 0; i < choices.length; i++) { 11001 if (CharOperation.equals(choices[i], Keywords.TRUE) || 11002 CharOperation.equals(choices[i], Keywords.FALSE) 11003 ){ 11004 int relevance = computeBaseRelevance(); 11005 relevance += computeRelevanceForResolution(); 11006 relevance += computeRelevanceForInterestingProposal(); 11007 relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]); 11008 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors 11009 relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN); 11010 relevance += computeRelevanceForQualification(false); 11011 relevance += R_TRUE_OR_FALSE; 11012 11013 this.noProposal = false; 11014 if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 11015 InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition); 11016 proposal.setName(choices[i]); 11017 proposal.setCompletion(choices[i]); 11018 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 11019 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 11020 proposal.setRelevance(relevance); 11021 this.requestor.accept(proposal); 11022 if(DEBUG) { 11023 this.printDebug(proposal); 11024 } 11025 } 11026 } 11027 } 11028 } 11029 findTypeParameters(char[] token, Scope scope)11030 private void findTypeParameters(char[] token, Scope scope) { 11031 if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return; 11032 11033 TypeParameter[] typeParameters = null; 11034 while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found 11035 typeParameters = null; 11036 switch (scope.kind) { 11037 case Scope.METHOD_SCOPE : 11038 MethodScope methodScope = (MethodScope) scope; 11039 if(methodScope.referenceContext instanceof MethodDeclaration) { 11040 MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext; 11041 typeParameters = methodDeclaration.typeParameters; 11042 } else if(methodScope.referenceContext instanceof ConstructorDeclaration) { 11043 ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext; 11044 typeParameters = methodDeclaration.typeParameters; 11045 } 11046 break; 11047 case Scope.CLASS_SCOPE : 11048 ClassScope classScope = (ClassScope) scope; 11049 typeParameters = classScope.referenceContext.typeParameters; 11050 break; 11051 case Scope.COMPILATION_UNIT_SCOPE : 11052 return; 11053 } 11054 if(typeParameters != null) { 11055 for (int i = 0; i < typeParameters.length; i++) { 11056 int typeLength = token.length; 11057 TypeParameter typeParameter = typeParameters[i]; 11058 11059 if(typeParameter.binding == null) continue; 11060 11061 if (typeLength > typeParameter.name.length) continue; 11062 11063 if (isFailedMatch(token, typeParameter.name)) continue; 11064 11065 int relevance = computeBaseRelevance(); 11066 relevance += computeRelevanceForResolution(); 11067 relevance += computeRelevanceForInterestingProposal(); 11068 relevance += computeRelevanceForCaseMatching(token, typeParameter.name); 11069 relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType); 11070 relevance += computeRelevanceForQualification(false); 11071 relevance += computeRelevanceForException(typeParameter.name); 11072 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter 11073 11074 this.noProposal = false; 11075 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 11076 createTypeParameterProposal(typeParameter, relevance); 11077 } 11078 } 11079 } 11080 scope = scope.parent; 11081 } 11082 } 11083 findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound)11084 private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) { 11085 11086 if (token == null) 11087 return; 11088 11089 boolean allowingLongComputationProposals = isAllowingLongComputationProposals(); 11090 11091 boolean proposeType = 11092 !this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 11093 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)); 11094 11095 boolean proposeAllMemberTypes = !this.assistNodeIsConstructor; 11096 11097 boolean proposeConstructor = 11098 allowingLongComputationProposals && 11099 this.assistNodeIsConstructor && 11100 (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) || 11101 !isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)); 11102 11103 11104 if ((proposeType || proposeConstructor) && scope.enclosingSourceType() != null) { 11105 11106 checkCancel(); 11107 11108 findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound); 11109 if(!this.assistNodeIsInterface && 11110 !this.assistNodeIsConstructor && 11111 !this.assistNodeIsAnnotation && 11112 this.assistNodeInJavadoc == 0) { 11113 11114 checkCancel(); 11115 11116 // don't propose type parameters if the completion is a constructor ('new |') 11117 findTypeParameters(token, scope); 11118 } 11119 } 11120 11121 boolean isEmptyPrefix = token.length == 0; 11122 11123 if ((proposeType || proposeConstructor) && this.unitScope != null) { 11124 11125 ReferenceBinding outerInvocationType = scope.enclosingSourceType(); 11126 if(outerInvocationType != null) { 11127 ReferenceBinding temp = outerInvocationType.enclosingType(); 11128 while(temp != null) { 11129 outerInvocationType = temp; 11130 temp = temp.enclosingType(); 11131 } 11132 } 11133 11134 int typeLength = token.length; 11135 SourceTypeBinding[] types = this.unitScope.topLevelTypes; 11136 11137 next : for (int i = 0, length = types.length; i < length; i++) { 11138 11139 checkCancel(); 11140 11141 SourceTypeBinding sourceType = types[i]; 11142 11143 if(isForbidden(sourceType)) continue next; 11144 11145 if(proposeAllMemberTypes && 11146 TypeBinding.notEquals(sourceType, outerInvocationType)) { 11147 findSubMemberTypes( 11148 token, 11149 sourceType, 11150 scope, 11151 scope.enclosingSourceType(), 11152 false, 11153 false, 11154 false, 11155 typesFound); 11156 } 11157 11158 if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next; 11159 if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next; 11160 11161 if (typeLength > sourceType.sourceName.length) continue next; 11162 11163 if (isFailedMatch(token, sourceType.sourceName)) continue next; 11164 11165 if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) { 11166 continue next; 11167 } 11168 11169 for (int j = typesFound.size; --j >= 0;) { 11170 ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j); 11171 11172 if (TypeBinding.equalsEquals(sourceType, otherType)) continue next; 11173 } 11174 11175 typesFound.add(sourceType); 11176 11177 if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue next; 11178 if (this.assistNodeIsExtendedType && sourceType.isRecord()) continue next; 11179 if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue next; 11180 if(this.assistNodeIsClass) { 11181 if(!sourceType.isClass()) continue next; 11182 } else if(this.assistNodeIsInterface) { 11183 if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next; 11184 } else if (this.assistNodeIsAnnotation) { 11185 if(!sourceType.isAnnotationType()) continue next; 11186 } else if (this.assistNodeIsException) { 11187 if (!sourceType.isClass()) continue next; 11188 if (isEmptyPrefix) { 11189 if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) { 11190 continue next; 11191 } 11192 } 11193 } 11194 11195 int relevance = computeBaseRelevance(); 11196 relevance += computeRelevanceForResolution(); 11197 relevance += computeRelevanceForInterestingProposal(sourceType); 11198 relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName); 11199 relevance += computeRelevanceForExpectingType(sourceType); 11200 relevance += computeRelevanceForQualification(false); 11201 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit 11202 11203 if (sourceType.isAnnotationType()) { 11204 relevance += computeRelevanceForAnnotation(); 11205 relevance += computeRelevanceForAnnotationTarget(sourceType); 11206 } else if (sourceType.isInterface()) { 11207 relevance += computeRelevanceForInterface(); 11208 } else if(sourceType.isClass()){ 11209 relevance += computeRelevanceForClass(); 11210 relevance += computeRelevanceForException(sourceType.sourceName); 11211 } 11212 11213 11214 this.noProposal = false; 11215 if(proposeType && 11216 (!this.assistNodeIsConstructor || 11217 !allowingLongComputationProposals || 11218 hasStaticMemberTypes(sourceType, null, this.unitScope) || 11219 hasMemberTypesInEnclosingScope(sourceType, scope)) || 11220 hasArrayTypeAsExpectedSuperTypes()) { 11221 char[] typeName = sourceType.sourceName(); 11222 createTypeProposal( 11223 sourceType, 11224 typeName, 11225 IAccessRule.K_ACCESSIBLE, 11226 typeName, 11227 relevance, 11228 null, 11229 null, 11230 null, 11231 false); 11232 } 11233 11234 if (proposeConstructor) { 11235 findConstructorsOrAnonymousTypes( 11236 sourceType, 11237 scope, 11238 FakeInvocationSite, 11239 false, 11240 relevance); 11241 } 11242 } 11243 } 11244 11245 if (proposeConstructor && !isEmptyPrefix) { 11246 11247 checkCancel(); 11248 11249 findTypesFromImports(token, scope, proposeType, typesFound); 11250 } else if(proposeType) { 11251 11252 checkCancel(); 11253 11254 findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound); 11255 } 11256 11257 if (proposeConstructor) { 11258 11259 checkCancel(); 11260 11261 findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor); 11262 } 11263 11264 if (isEmptyPrefix && !this.assistNodeIsAnnotation) { 11265 if (!proposeConstructor) { 11266 findTypesFromExpectedTypes(token, scope, typesFound, proposeType, proposeConstructor); 11267 } 11268 } else { 11269 if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) { 11270 if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) { 11271 if (proposeBaseTypes) { 11272 if (proposeVoidType) { 11273 findKeywords(token, BASE_TYPE_NAMES, false, false); 11274 } else { 11275 findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false); 11276 } 11277 } 11278 } 11279 } 11280 11281 if (proposeConstructor) { 11282 int l = typesFound.size(); 11283 for (int i = 0; i < l; i++) { 11284 ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i); 11285 char[] fullyQualifiedTypeName = 11286 CharOperation.concat( 11287 typeFound.qualifiedPackageName(), 11288 typeFound.qualifiedSourceName(), 11289 '.'); 11290 this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS); 11291 } 11292 11293 checkCancel(); 11294 11295 this.foundConstructorsCount = 0; 11296 this.nameEnvironment.findConstructorDeclarations( 11297 token, 11298 this.options.camelCaseMatch, 11299 this, 11300 this.monitor); 11301 acceptConstructors(scope); 11302 } else if (proposeType) { 11303 int l = typesFound.size(); 11304 for (int i = 0; i < l; i++) { 11305 ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i); 11306 char[] fullyQualifiedTypeName = 11307 CharOperation.concat( 11308 typeFound.qualifiedPackageName(), 11309 typeFound.qualifiedSourceName(), 11310 '.'); 11311 this.knownTypes.put(fullyQualifiedTypeName, KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS); 11312 } 11313 int searchFor = IJavaSearchConstants.TYPE; 11314 if(this.assistNodeIsClass || this.assistNodeIsException) { 11315 searchFor = IJavaSearchConstants.CLASS; 11316 } else if (this.assistNodeIsInterfaceExcludingAnnotation) { 11317 searchFor = IJavaSearchConstants.INTERFACE; 11318 } else if(this.assistNodeIsInterface) { 11319 searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION; 11320 } else if(this.assistNodeIsEnum) { 11321 searchFor = IJavaSearchConstants.ENUM; 11322 } else if(this.assistNodeIsAnnotation) { 11323 searchFor = IJavaSearchConstants.ANNOTATION_TYPE; 11324 } 11325 11326 checkCancel(); 11327 11328 this.foundTypesCount = 0; 11329 this.nameEnvironment.findTypes( 11330 token, 11331 proposeAllMemberTypes, 11332 this.options.camelCaseMatch, 11333 searchFor, 11334 this, 11335 this.monitor); 11336 acceptTypes(scope); 11337 } 11338 if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 11339 11340 checkCancel(); 11341 11342 this.nameEnvironment.findPackages(token, this); 11343 } 11344 } 11345 } 11346 findTypesAndSubpackages( char[] token, PackageBinding packageBinding, Scope scope)11347 private void findTypesAndSubpackages( 11348 char[] token, 11349 PackageBinding packageBinding, 11350 Scope scope) { 11351 11352 boolean allowingLongComputationProposals = isAllowingLongComputationProposals(); 11353 11354 boolean proposeType = 11355 !this.requestor.isIgnored(CompletionProposal.TYPE_REF) || 11356 ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)); 11357 11358 boolean proposeConstructor = 11359 allowingLongComputationProposals && 11360 this.assistNodeIsConstructor && 11361 (!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF) || 11362 !isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)); 11363 11364 char[] qualifiedName = 11365 CharOperation.concatWith(packageBinding.compoundName, token, '.'); 11366 11367 if (token == null || token.length == 0) { 11368 int length = qualifiedName.length; 11369 System.arraycopy( 11370 qualifiedName, 11371 0, 11372 qualifiedName = new char[length + 1], 11373 0, 11374 length); 11375 qualifiedName[length] = '.'; 11376 } 11377 11378 this.qualifiedCompletionToken = qualifiedName; 11379 11380 if ((proposeType || proposeConstructor) && this.unitScope != null) { 11381 int typeLength = qualifiedName.length; 11382 SourceTypeBinding[] types = this.unitScope.topLevelTypes; 11383 11384 for (int i = 0, length = types.length; i < length; i++) { 11385 11386 checkCancel(); 11387 11388 SourceTypeBinding sourceType = types[i]; 11389 11390 if (isForbidden(sourceType)) continue; 11391 if (this.assistNodeIsClass && sourceType.isInterface()) continue; 11392 if (this.assistNodeIsInterface && sourceType.isClass()) continue; 11393 11394 char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.'); 11395 11396 if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue; 11397 if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue; 11398 if (typeLength > qualifiedSourceTypeName.length) continue; 11399 if (!(packageBinding == sourceType.getPackage())) continue; 11400 11401 if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false) 11402 && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue; 11403 11404 if (this.options.checkDeprecation && 11405 sourceType.isViewedAsDeprecated() && 11406 !scope.isDefinedInSameUnit(sourceType)) 11407 continue; 11408 11409 if (this.assistNodeIsExtendedType && sourceType.isFinal()) continue; 11410 if (this.assistNodeIsInterfaceExcludingAnnotation && sourceType.isAnnotationType()) continue; 11411 int accessibility = IAccessRule.K_ACCESSIBLE; 11412 if(sourceType.hasRestrictedAccess()) { 11413 AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType); 11414 if(accessRestriction != null) { 11415 switch (accessRestriction.getProblemId()) { 11416 case IProblem.ForbiddenReference: 11417 if (this.options.checkForbiddenReference) { 11418 continue; 11419 } 11420 accessibility = IAccessRule.K_NON_ACCESSIBLE; 11421 break; 11422 case IProblem.DiscouragedReference: 11423 if (this.options.checkDiscouragedReference) { 11424 continue; 11425 } 11426 accessibility = IAccessRule.K_DISCOURAGED; 11427 break; 11428 } 11429 } 11430 } 11431 11432 this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), KNOWN_TYPE_WITH_KNOWN_CONSTRUCTORS); 11433 11434 int relevance = computeBaseRelevance(); 11435 relevance += computeRelevanceForResolution(); 11436 relevance += computeRelevanceForInterestingProposal(sourceType); 11437 relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName); 11438 relevance += computeRelevanceForExpectingType(sourceType); 11439 relevance += computeRelevanceForQualification(false); 11440 relevance += computeRelevanceForRestrictions(accessibility); 11441 11442 if (sourceType.isAnnotationType()) { 11443 relevance += computeRelevanceForAnnotation(); 11444 } else if (sourceType.isInterface()) { 11445 relevance += computeRelevanceForInterface(); 11446 } else if (sourceType.isClass()) { 11447 relevance += computeRelevanceForClass(); 11448 relevance += computeRelevanceForException(sourceType.sourceName); 11449 } 11450 11451 this.noProposal = false; 11452 if(proposeType && 11453 (!this.assistNodeIsConstructor || 11454 !allowingLongComputationProposals || 11455 hasStaticMemberTypes(sourceType, null, this.unitScope) || 11456 hasMemberTypesInEnclosingScope(sourceType, scope)) || 11457 hasArrayTypeAsExpectedSuperTypes()) { 11458 char[] typeName = sourceType.sourceName(); 11459 createTypeProposal( 11460 sourceType, 11461 typeName, 11462 IAccessRule.K_ACCESSIBLE, 11463 typeName, 11464 relevance, 11465 null, 11466 null, 11467 null, 11468 false); 11469 } 11470 11471 if (proposeConstructor) { 11472 findConstructorsOrAnonymousTypes( 11473 sourceType, 11474 scope, 11475 FakeInvocationSite, 11476 false, 11477 relevance); 11478 } 11479 } 11480 } 11481 11482 if (proposeConstructor) { 11483 11484 11485 checkCancel(); 11486 11487 this.foundConstructorsCount = 0; 11488 this.nameEnvironment.findConstructorDeclarations( 11489 qualifiedName, 11490 this.options.camelCaseMatch, 11491 this, 11492 this.monitor); 11493 acceptConstructors(scope); 11494 } if(proposeType) { 11495 int searchFor = IJavaSearchConstants.TYPE; 11496 if(this.assistNodeIsClass) { 11497 searchFor = IJavaSearchConstants.CLASS; 11498 } else if (this.assistNodeIsInterfaceExcludingAnnotation) { 11499 searchFor = IJavaSearchConstants.INTERFACE; 11500 } else if(this.assistNodeIsInterface) { 11501 searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION; 11502 } else if(this.assistNodeIsEnum) { 11503 searchFor = IJavaSearchConstants.ENUM; 11504 } else if(this.assistNodeIsAnnotation) { 11505 searchFor = IJavaSearchConstants.ANNOTATION_TYPE; 11506 } 11507 11508 checkCancel(); 11509 11510 this.foundTypesCount = 0; 11511 this.nameEnvironment.findTypes( 11512 qualifiedName, 11513 false, 11514 this.options.camelCaseMatch, 11515 searchFor, 11516 this, 11517 this.monitor); 11518 acceptTypes(scope); 11519 } 11520 11521 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 11522 this.nameEnvironment.findPackages(qualifiedName, this); 11523 } 11524 } 11525 findTypesFromExpectedTypes(char[] token, Scope scope, ObjectVector typesFound, boolean proposeType, boolean proposeConstructor)11526 private void findTypesFromExpectedTypes(char[] token, Scope scope, ObjectVector typesFound, boolean proposeType, boolean proposeConstructor) { 11527 if(this.expectedTypesPtr > -1) { 11528 boolean allowingLongComputationProposals = isAllowingLongComputationProposals(); 11529 11530 int typeLength = token == null ? 0 : token.length; 11531 11532 next : for (int i = 0; i <= this.expectedTypesPtr; i++) { 11533 11534 checkCancel(); 11535 11536 if(this.expectedTypes[i] instanceof ReferenceBinding) { 11537 ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i]; 11538 11539 if (typeLength > 0) { 11540 if (typeLength > refBinding.sourceName.length) continue next; 11541 11542 if (isFailedMatch(token, refBinding.sourceName)) continue next; 11543 } 11544 11545 11546 if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) { 11547 // don't propose type variable if the completion is a constructor ('new |') 11548 continue next; 11549 } 11550 if (this.options.checkDeprecation && 11551 refBinding.isViewedAsDeprecated() && 11552 !scope.isDefinedInSameUnit(refBinding)) 11553 continue next; 11554 11555 int accessibility = IAccessRule.K_ACCESSIBLE; 11556 if(refBinding.hasRestrictedAccess()) { 11557 AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding); 11558 if(accessRestriction != null) { 11559 switch (accessRestriction.getProblemId()) { 11560 case IProblem.ForbiddenReference: 11561 if (this.options.checkForbiddenReference) { 11562 continue next; 11563 } 11564 accessibility = IAccessRule.K_NON_ACCESSIBLE; 11565 break; 11566 case IProblem.DiscouragedReference: 11567 if (this.options.checkDiscouragedReference) { 11568 continue next; 11569 } 11570 accessibility = IAccessRule.K_DISCOURAGED; 11571 break; 11572 } 11573 } 11574 } 11575 if(isForbidden(refBinding)) continue next; 11576 11577 for (int j = 0; j < typesFound.size(); j++) { 11578 ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j); 11579 if (TypeBinding.equalsEquals(typeFound, refBinding.erasure())) { 11580 continue next; 11581 } 11582 } 11583 11584 typesFound.add(refBinding); 11585 11586 boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding); 11587 11588 // top level types of the current unit are already proposed. 11589 if(!inSameUnit || (inSameUnit && refBinding.isMemberType())) { 11590 char[] packageName = refBinding.qualifiedPackageName(); 11591 char[] typeName = refBinding.sourceName(); 11592 char[] completionName = typeName; 11593 11594 boolean isQualified = false; 11595 if (!this.insideQualifiedReference && !refBinding.isMemberType()) { 11596 if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) { 11597 if (packageName == null || packageName.length == 0) 11598 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 11599 continue next; // ignore types from the default package from outside it 11600 completionName = CharOperation.concat(packageName, typeName, '.'); 11601 isQualified = true; 11602 } 11603 } 11604 11605 if (this.assistNodeIsExtendedType && refBinding.isFinal()) continue next; 11606 if (this.assistNodeIsInterfaceExcludingAnnotation && refBinding.isAnnotationType()) continue next; 11607 if(this.assistNodeIsClass) { 11608 if(!refBinding.isClass()) continue next; 11609 } else if(this.assistNodeIsInterface) { 11610 if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next; 11611 } else if (this.assistNodeIsAnnotation) { 11612 if(!refBinding.isAnnotationType()) continue next; 11613 } 11614 11615 int relevance = computeBaseRelevance(); 11616 relevance += computeRelevanceForResolution(); 11617 relevance += computeRelevanceForInterestingProposal(refBinding); 11618 relevance += computeRelevanceForCaseMatching(token, typeName); 11619 relevance += computeRelevanceForExpectingType(refBinding); 11620 relevance += computeRelevanceForQualification(isQualified); 11621 relevance += computeRelevanceForRestrictions(accessibility); 11622 11623 if(refBinding.isClass()) { 11624 relevance += computeRelevanceForClass(); 11625 relevance += computeRelevanceForException(typeName); 11626 } else if(refBinding.isEnum()) { 11627 relevance += computeRelevanceForEnum(); 11628 } else if(refBinding.isInterface()) { 11629 relevance += computeRelevanceForInterface(); 11630 } 11631 11632 if (proposeType && 11633 (!this.assistNodeIsConstructor || 11634 !allowingLongComputationProposals || 11635 hasStaticMemberTypes(refBinding, scope.enclosingSourceType() ,this.unitScope)) || 11636 hasArrayTypeAsExpectedSuperTypes()) { 11637 this.noProposal = false; 11638 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 11639 InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 11640 proposal.setDeclarationSignature(packageName); 11641 proposal.setSignature(getSignature(refBinding)); 11642 proposal.setPackageName(packageName); 11643 proposal.setTypeName(typeName); 11644 proposal.setCompletion(completionName); 11645 proposal.setFlags(refBinding.modifiers); 11646 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 11647 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 11648 proposal.setRelevance(relevance); 11649 proposal.setAccessibility(accessibility); 11650 this.requestor.accept(proposal); 11651 if(DEBUG) { 11652 this.printDebug(proposal); 11653 } 11654 } 11655 } 11656 11657 if (proposeConstructor) { 11658 findConstructorsOrAnonymousTypes( 11659 refBinding, 11660 scope, 11661 FakeInvocationSite, 11662 isQualified, 11663 relevance); 11664 } 11665 } 11666 } 11667 } 11668 } 11669 } 11670 findTypesFromImports(char[] token, Scope scope, boolean proposeType, ObjectVector typesFound)11671 private void findTypesFromImports(char[] token, Scope scope, boolean proposeType, ObjectVector typesFound) { 11672 ImportBinding[] importBindings = scope.compilationUnitScope().imports; 11673 next : for (int i = 0; i < importBindings.length; i++) { 11674 ImportBinding importBinding = importBindings[i]; 11675 if(importBinding.isValidBinding()) { 11676 Binding binding = importBinding.resolvedImport; 11677 if(binding != null && binding.isValidBinding()) { 11678 if(importBinding.onDemand) { 11679 if (importBinding.isStatic()) { 11680 if((binding.kind() & Binding.TYPE) != 0) { 11681 this.findMemberTypes( 11682 token, 11683 (ReferenceBinding) binding, 11684 scope, 11685 scope.enclosingSourceType(), 11686 true, 11687 false, 11688 true, 11689 true, 11690 false, 11691 null, 11692 typesFound, 11693 null, 11694 null, 11695 null, 11696 false); 11697 } 11698 } 11699 } else { 11700 if ((binding.kind() & Binding.TYPE) != 0) { 11701 ReferenceBinding typeBinding = (ReferenceBinding) binding; 11702 int typeLength = token.length; 11703 11704 if (!typeBinding.isStatic()) continue next; 11705 11706 if (typeLength > typeBinding.sourceName.length) continue next; 11707 11708 if (isFailedMatch(token, typeBinding.sourceName)) continue next; 11709 11710 int accessibility = IAccessRule.K_ACCESSIBLE; 11711 if(typeBinding.hasRestrictedAccess()) { 11712 AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(typeBinding); 11713 if(accessRestriction != null) { 11714 switch (accessRestriction.getProblemId()) { 11715 case IProblem.ForbiddenReference: 11716 if (this.options.checkForbiddenReference) { 11717 continue next; 11718 } 11719 accessibility = IAccessRule.K_NON_ACCESSIBLE; 11720 break; 11721 case IProblem.DiscouragedReference: 11722 if (this.options.checkDiscouragedReference) { 11723 continue next; 11724 } 11725 accessibility = IAccessRule.K_DISCOURAGED; 11726 break; 11727 } 11728 } 11729 } 11730 11731 if (typesFound.contains(typeBinding)) continue next; 11732 11733 typesFound.add(typeBinding); 11734 11735 if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue; 11736 if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue; 11737 if(this.assistNodeIsClass) { 11738 if(!typeBinding.isClass()) continue; 11739 } else if(this.assistNodeIsInterface) { 11740 if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue; 11741 } else if (this.assistNodeIsAnnotation) { 11742 if(!typeBinding.isAnnotationType()) continue; 11743 } 11744 11745 int relevance = computeBaseRelevance(); 11746 relevance += computeRelevanceForResolution(); 11747 relevance += computeRelevanceForInterestingProposal(typeBinding); 11748 relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName); 11749 relevance += computeRelevanceForExpectingType(typeBinding); 11750 relevance += computeRelevanceForQualification(false); 11751 relevance += computeRelevanceForRestrictions(accessibility); 11752 11753 if (typeBinding.isAnnotationType()) { 11754 relevance += computeRelevanceForAnnotation(); 11755 relevance += computeRelevanceForAnnotationTarget(typeBinding); 11756 } else if (typeBinding.isInterface()) { 11757 relevance += computeRelevanceForInterface(); 11758 } else if(typeBinding.isClass()){ 11759 relevance += computeRelevanceForClass(); 11760 relevance += computeRelevanceForException(typeBinding.sourceName); 11761 } 11762 11763 if (proposeType && 11764 (hasStaticMemberTypes(typeBinding, scope.enclosingSourceType(), this.unitScope) || hasArrayTypeAsExpectedSuperTypes())) { 11765 this.noProposal = false; 11766 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 11767 InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 11768 proposal.setDeclarationSignature(typeBinding.qualifiedPackageName()); 11769 proposal.setSignature(getSignature(typeBinding)); 11770 proposal.setPackageName(typeBinding.qualifiedPackageName()); 11771 proposal.setTypeName(typeBinding.qualifiedSourceName()); 11772 proposal.setCompletion(typeBinding.sourceName()); 11773 proposal.setFlags(typeBinding.modifiers); 11774 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 11775 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 11776 proposal.setRelevance(relevance); 11777 this.requestor.accept(proposal); 11778 if(DEBUG) { 11779 this.printDebug(proposal); 11780 } 11781 } 11782 } 11783 11784 findConstructorsOrAnonymousTypes( 11785 typeBinding, 11786 scope, 11787 FakeInvocationSite, 11788 false, 11789 relevance); 11790 } 11791 } 11792 } 11793 } 11794 } 11795 } 11796 findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound)11797 private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) { 11798 ImportBinding[] importBindings = scope.compilationUnitScope().imports; 11799 if (importBindings == null) return; 11800 for (int i = 0; i < importBindings.length; i++) { 11801 ImportBinding importBinding = importBindings[i]; 11802 if(importBinding.isValidBinding() && importBinding.isStatic()) { 11803 Binding binding = importBinding.resolvedImport; 11804 if(binding != null && binding.isValidBinding()) { 11805 if(importBinding.onDemand) { 11806 if((binding.kind() & Binding.TYPE) != 0) { 11807 this.findMemberTypes( 11808 token, 11809 (ReferenceBinding) binding, 11810 scope, 11811 scope.enclosingSourceType(), 11812 true, 11813 false, 11814 true, 11815 true, 11816 proposeAllMemberTypes, 11817 null, 11818 typesFound, 11819 null, 11820 null, 11821 null, 11822 false); 11823 } 11824 } else { 11825 if ((binding.kind() & Binding.TYPE) != 0) { 11826 ReferenceBinding typeBinding = (ReferenceBinding) binding; 11827 int typeLength = token.length; 11828 11829 if (!typeBinding.isStatic()) continue; 11830 11831 if (typeLength > typeBinding.sourceName.length) continue; 11832 11833 if (isFailedMatch(token, typeBinding.sourceName)) continue; 11834 11835 if (typesFound.contains(typeBinding)) continue; 11836 11837 typesFound.add(typeBinding); 11838 11839 if (this.assistNodeIsExtendedType && typeBinding.isFinal()) continue; 11840 if (this.assistNodeIsInterfaceExcludingAnnotation && typeBinding.isAnnotationType()) continue; 11841 if(this.assistNodeIsClass || this.assistNodeIsException) { 11842 if(!typeBinding.isClass()) continue; 11843 } else if(this.assistNodeIsInterface) { 11844 if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue; 11845 } else if (this.assistNodeIsAnnotation) { 11846 if(!typeBinding.isAnnotationType()) continue; 11847 } 11848 11849 int relevance = computeBaseRelevance(); 11850 relevance += computeRelevanceForResolution(); 11851 relevance += computeRelevanceForInterestingProposal(typeBinding); 11852 relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName); 11853 relevance += computeRelevanceForExpectingType(typeBinding); 11854 relevance += computeRelevanceForQualification(false); 11855 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); 11856 11857 if (typeBinding.isClass()) { 11858 relevance += computeRelevanceForClass(); 11859 relevance += computeRelevanceForException(typeBinding.sourceName); 11860 } else if(typeBinding.isEnum()) { 11861 relevance += computeRelevanceForEnum(); 11862 } else if(typeBinding.isInterface()) { 11863 relevance += computeRelevanceForInterface(); 11864 } 11865 11866 this.noProposal = false; 11867 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 11868 InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 11869 proposal.setDeclarationSignature(typeBinding.qualifiedPackageName()); 11870 proposal.setSignature(getSignature(typeBinding)); 11871 proposal.setPackageName(typeBinding.qualifiedPackageName()); 11872 proposal.setTypeName(typeBinding.qualifiedSourceName()); 11873 proposal.setCompletion(typeBinding.sourceName()); 11874 proposal.setFlags(typeBinding.modifiers); 11875 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 11876 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 11877 proposal.setRelevance(relevance); 11878 this.requestor.accept(proposal); 11879 if(DEBUG) { 11880 this.printDebug(proposal); 11881 } 11882 } 11883 } 11884 } 11885 } 11886 } 11887 } 11888 } 11889 findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames)11890 private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) { 11891 char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames); 11892 if (foundNames != null && foundNames.length > 1) { 11893 int discouragedNamesLength = discouragedNames.length; 11894 int foundNamesLength = foundNames.length; 11895 int newLength = discouragedNamesLength + foundNamesLength; 11896 System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength); 11897 System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength); 11898 } 11899 findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames); 11900 } 11901 findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames)11902 private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) { 11903 final ArrayList proposedNames = new ArrayList(); 11904 11905 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 11906 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 11907 @Override 11908 public void acceptName(char[] name) { 11909 CompletionEngine.this.acceptUnresolvedName(name); 11910 proposedNames.add(name); 11911 } 11912 }; 11913 11914 ReferenceContext referenceContext = scope.referenceContext(); 11915 if (referenceContext instanceof AbstractMethodDeclaration) { 11916 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 11917 11918 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 11919 nameFinder.findAfter( 11920 this.completionToken, 11921 md.scope, 11922 md.scope.classScope(), 11923 from, 11924 md.bodyEnd, 11925 discouragedNames, 11926 nameRequestor); 11927 } else if (referenceContext instanceof LambdaExpression) { 11928 LambdaExpression expression = (LambdaExpression) referenceContext; 11929 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 11930 nameFinder.findAfter( 11931 this.completionToken, 11932 expression.scope, 11933 expression.scope.classScope(), 11934 from, 11935 expression.body().sourceEnd, 11936 discouragedNames, 11937 nameRequestor); 11938 } else if (referenceContext instanceof TypeDeclaration) { 11939 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 11940 FieldDeclaration[] fields = typeDeclaration.fields; 11941 if (fields != null) { 11942 done : for (int i = 0; i < fields.length; i++) { 11943 if (fields[i] instanceof Initializer) { 11944 Initializer initializer = (Initializer) fields[i]; 11945 if (initializer.block.sourceStart <= from && 11946 from < initializer.bodyEnd) { 11947 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 11948 nameFinder.findAfter( 11949 this.completionToken, 11950 typeDeclaration.scope, 11951 typeDeclaration.scope, 11952 from, 11953 initializer.bodyEnd, 11954 discouragedNames, 11955 nameRequestor); 11956 break done; 11957 } 11958 } 11959 } 11960 } 11961 } 11962 11963 int proposedNamesCount = proposedNames.size(); 11964 if (proposedNamesCount > 0) { 11965 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 11966 } 11967 11968 return null; 11969 } 11970 findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames)11971 private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) { 11972 final ArrayList proposedNames = new ArrayList(); 11973 11974 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 11975 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 11976 @Override 11977 public void acceptName(char[] name) { 11978 CompletionEngine.this.acceptUnresolvedName(name); 11979 proposedNames.add(name); 11980 } 11981 }; 11982 11983 BlockScope upperScope = scope; 11984 while (upperScope.enclosingMethodScope() != null) { 11985 upperScope = upperScope.enclosingMethodScope(); 11986 } 11987 11988 ReferenceContext referenceContext = upperScope.referenceContext(); 11989 if (referenceContext instanceof AbstractMethodDeclaration) { 11990 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 11991 11992 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 11993 nameFinder.findBefore( 11994 this.completionToken, 11995 md.scope, 11996 md.scope.classScope(), 11997 md.bodyStart, 11998 recordTo, 11999 parseTo, 12000 discouragedNames, 12001 nameRequestor); 12002 } else if (referenceContext instanceof TypeDeclaration) { 12003 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 12004 12005 12006 done : { 12007 FieldDeclaration[] fields = typeDeclaration.fields; 12008 if (fields != null) { 12009 for (int i = 0; i < fields.length; i++) { 12010 if (fields[i] instanceof Initializer) { 12011 Initializer initializer = (Initializer) fields[i]; 12012 if (initializer.block.sourceStart <= recordTo && 12013 recordTo < initializer.bodyEnd) { 12014 12015 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 12016 nameFinder.findBefore( 12017 this.completionToken, 12018 typeDeclaration.scope, 12019 typeDeclaration.scope, 12020 initializer.block.sourceStart, 12021 recordTo, 12022 parseTo, 12023 discouragedNames, 12024 nameRequestor); 12025 break done; 12026 } 12027 } 12028 } 12029 } 12030 } 12031 } 12032 12033 int proposedNamesCount = proposedNames.size(); 12034 if (proposedNamesCount > 0) { 12035 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 12036 } 12037 12038 return null; 12039 } 12040 findImplementations(ProvidesStatement providesStmt, TypeReference reference )12041 private void findImplementations(ProvidesStatement providesStmt, TypeReference reference ) { 12042 char[][] tokens = reference.getTypeName(); 12043 char[] typeName = CharOperation.concatWithAll(tokens, '.'); 12044 12045 if (typeName.length == 0) { 12046 this.completionToken = CharOperation.ALL_PREFIX; 12047 } else if (reference instanceof CompletionOnProvidesImplementationsQualifiedTypeReference) { 12048 CompletionOnQualifiedTypeReference qReference = (CompletionOnQualifiedTypeReference) reference; 12049 if (qReference.completionIdentifier != null) { 12050 this.completionToken = CharOperation.concatAll(typeName, qReference.completionIdentifier, '.'); 12051 } 12052 } else { 12053 char[] lastToken = tokens[tokens.length - 1]; 12054 this.completionToken = lastToken != null && lastToken.length == 0 ? 12055 CharOperation.concat(typeName, new char[]{'.'}) :lastToken; 12056 } 12057 setSourceRange(reference.sourceStart, reference.sourceEnd); 12058 findImplementations(this.completionToken, this.unitScope, providesStmt, -1); 12059 } 12060 findImplementations(char[] token, Scope scope, ProvidesStatement providesStmt, int stmtIndex)12061 private void findImplementations(char[] token, Scope scope, ProvidesStatement providesStmt, int stmtIndex) { 12062 TypeReference theInterface = providesStmt.serviceInterface; 12063 if (token == null) return; 12064 char[][] theInterfaceType = null; 12065 if (theInterface.resolvedType != null && theInterface.resolvedType.isValidBinding()) { 12066 char[] readableName = theInterface.resolvedType.readableName(); 12067 if (readableName != null) 12068 theInterfaceType = CharOperation.splitOn('.', readableName); 12069 } 12070 theInterfaceType = theInterfaceType == null ? theInterface.getTypeName() : theInterfaceType; 12071 if (theInterfaceType == null) return; 12072 SearchPattern pattern = null; 12073 NameEnvironmentAnswer answer = this.nameEnvironment.findTypeInModules(theInterfaceType, scope.module()); 12074 if (answer != null ) { 12075 if (answer.isSourceType()) { 12076 IType typeHandle = ((SourceTypeElementInfo) answer.getSourceTypes()[0]).getHandle(); 12077 try { 12078 ArrayList<IType> allTypes = new ArrayList<IType>(); 12079 ITypeHierarchy newTypeHierarchy = typeHandle.newTypeHierarchy(this.javaProject, null); 12080 IType[] implementingClasses = newTypeHierarchy.getImplementingClasses(typeHandle); 12081 for (IType iClass : implementingClasses) { 12082 getAllTypesInHierarchy(newTypeHierarchy,iClass,allTypes); 12083 } 12084 for (IType iType : allTypes) { 12085 String pkg = iType.getPackageFragment().getElementName(); 12086 String name = iType.getElementName(); 12087 if ( CharOperation.ALL_PREFIX != this.completionToken) { 12088 if(!CharOperation.prefixEquals(this.completionToken, name.toCharArray(), false)) 12089 if(!CharOperation.prefixEquals(this.completionToken, pkg.toCharArray(), false)) 12090 continue; 12091 } 12092 this.acceptType(pkg.toCharArray(), name.toCharArray(), CharOperation.NO_CHAR_CHAR, iType.getFlags(), null); 12093 acceptTypes(scope); 12094 } 12095 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 12096 checkCancel(); 12097 findPackagesInCurrentModule(); 12098 } 12099 return; 12100 12101 } catch (JavaModelException e) { 12102 // 12103 } 12104 } else if (answer.isBinaryType()) { 12105 String typeName = new String(CharOperation.replaceOnCopy(answer.getBinaryType().getName(), '/', '.')); 12106 pattern = SearchPattern.createPattern(typeName, 12107 IJavaSearchConstants.CLASS_AND_INTERFACE, 12108 IJavaSearchConstants.IMPLEMENTORS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE); 12109 } 12110 } 12111 if (pattern == null) return; 12112 IJavaSearchScope searchScope = BasicSearchEngine.createJavaSearchScope(new IJavaElement[] {this.javaProject}); 12113 class ImplSearchRequestor extends SearchRequestor { 12114 String prefix; 12115 LinkedHashSet<String> filter; 12116 public List<IType> types = new ArrayList<>(); 12117 public ImplSearchRequestor(char[] prefixToken, LinkedHashSet<String> filter) { 12118 this.prefix = (prefixToken == CharOperation.ALL_PREFIX) ? null : new String(prefixToken); 12119 this.filter = filter; 12120 } 12121 @Override 12122 public void acceptSearchMatch(SearchMatch match) throws CoreException { 12123 // checkCancel(); 12124 IJavaElement element = ((IJavaElement) match.getElement()); 12125 if (element.getElementType() == IJavaElement.TYPE) { 12126 IType type = (IType) element; 12127 if (this.prefix != null) { 12128 String fullTypeName = type.getPackageFragment().getElementName(); 12129 if (fullTypeName != null) { 12130 fullTypeName = fullTypeName.concat(".").concat(type.getElementName()); //$NON-NLS-1$ 12131 } else { 12132 fullTypeName = type.getElementName(); 12133 } 12134 if (this.filter.contains(fullTypeName)) return; 12135 if (!(fullTypeName.startsWith(this.prefix) || type.getElementName().startsWith(this.prefix))) 12136 return; 12137 } 12138 this.types.add(type); 12139 } 12140 } 12141 } 12142 try { 12143 LinkedHashSet<String> existingImpl = new LinkedHashSet<>(); 12144 char[][] theInterfaceName = theInterface.getTypeName(); 12145 // filter out existing implementations of the same interfaces 12146 for (int i = 0, l = this.moduleDeclaration.servicesCount; i < l; ++i) { 12147 if (i == stmtIndex) continue; 12148 ProvidesStatement prevProvides = this.moduleDeclaration.services[i]; 12149 if (!CharOperation.equals(theInterfaceName, prevProvides.serviceInterface.getTypeName())) continue; 12150 TypeReference[] prevImpls = prevProvides.implementations; 12151 for (TypeReference prevImpl : prevImpls) { 12152 char[][] typeName = prevImpl.getTypeName(); 12153 if (typeName == CharOperation.NO_CHAR_CHAR) continue; 12154 existingImpl.add(CharOperation.toString(typeName)); 12155 } 12156 } 12157 // use search infrastructure - faster than using model 12158 ImplSearchRequestor searchRequestor = new ImplSearchRequestor(this.completionToken, existingImpl); 12159 new SearchEngine(this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/)).search( 12160 pattern, 12161 new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, 12162 searchScope, 12163 searchRequestor, 12164 null 12165 ); 12166 for (IType type : searchRequestor.types) { 12167 String pkg = type.getPackageFragment().getElementName(); 12168 String name = type.getElementName(); 12169 this.acceptType(pkg.toCharArray(), name.toCharArray(), CharOperation.NO_CHAR_CHAR, type.getFlags(), null); 12170 acceptTypes(scope); 12171 } 12172 } catch (CoreException e) { 12173 // TODO Auto-generated catch block 12174 e.printStackTrace(); 12175 } 12176 if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) { 12177 checkCancel(); 12178 findPackagesInCurrentModule(); 12179 } 12180 } 12181 getAllTypesInHierarchy(ITypeHierarchy newTypeHierarchy, IType iClass, ArrayList<IType> allTypes)12182 private void getAllTypesInHierarchy(ITypeHierarchy newTypeHierarchy, IType iClass, ArrayList<IType> allTypes) { 12183 allTypes.add(iClass); 12184 IType[] subclasses = newTypeHierarchy.getSubclasses(iClass); 12185 for (IType iType2 : subclasses) { 12186 getAllTypesInHierarchy(newTypeHierarchy,iType2,allTypes); 12187 12188 } 12189 12190 } 12191 findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames)12192 private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) { 12193 final TypeReference type = variable.type; 12194 if(type != null && 12195 type.resolvedType != null && 12196 type.resolvedType.problemId() == ProblemReasons.NoError){ 12197 12198 final ArrayList proposedNames = new ArrayList(); 12199 12200 UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor = 12201 new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() { 12202 @Override 12203 public void acceptName(char[] name) { 12204 int relevance = computeBaseRelevance(); 12205 relevance += computeRelevanceForInterestingProposal(); 12206 relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name); 12207 relevance += R_NAME_FIRST_PREFIX; 12208 relevance += R_NAME_FIRST_SUFFIX; 12209 relevance += R_NAME_LESS_NEW_CHARACTERS; 12210 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name 12211 12212 // accept result 12213 CompletionEngine.this.noProposal = false; 12214 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 12215 InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition); 12216 proposal.setSignature(getSignature(type.resolvedType)); 12217 proposal.setPackageName(type.resolvedType.qualifiedPackageName()); 12218 proposal.setTypeName(type.resolvedType.qualifiedSourceName()); 12219 proposal.setName(name); 12220 proposal.setCompletion(name); 12221 //proposal.setFlags(Flags.AccDefault); 12222 proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset); 12223 proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset); 12224 proposal.setRelevance(relevance); 12225 CompletionEngine.this.requestor.accept(proposal); 12226 if(DEBUG) { 12227 CompletionEngine.this.printDebug(proposal); 12228 } 12229 } 12230 proposedNames.add(name); 12231 } 12232 }; 12233 12234 ReferenceContext referenceContext = scope.referenceContext(); 12235 if (referenceContext instanceof AbstractMethodDeclaration) { 12236 AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext; 12237 12238 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 12239 nameFinder.find( 12240 this.completionToken, 12241 md, 12242 variable.declarationSourceEnd + 1, 12243 discouragedNames, 12244 nameRequestor); 12245 } else if (referenceContext instanceof TypeDeclaration) { 12246 TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext; 12247 FieldDeclaration[] fields = typeDeclaration.fields; 12248 if (fields != null) { 12249 done : for (int i = 0; i < fields.length; i++) { 12250 if (fields[i] instanceof Initializer) { 12251 Initializer initializer = (Initializer) fields[i]; 12252 if (initializer.bodyStart <= variable.sourceStart && 12253 variable.sourceStart < initializer.bodyEnd) { 12254 UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this); 12255 nameFinder.find( 12256 this.completionToken, 12257 initializer, 12258 typeDeclaration.scope, 12259 variable.declarationSourceEnd + 1, 12260 discouragedNames, 12261 nameRequestor); 12262 break done; 12263 } 12264 } 12265 } 12266 } 12267 } 12268 12269 int proposedNamesCount = proposedNames.size(); 12270 if (proposedNamesCount > 0) { 12271 return (char[][])proposedNames.toArray(new char[proposedNamesCount][]); 12272 } 12273 } 12274 12275 return null; 12276 } 12277 findVariableName( char[] token, char[] qualifiedPackageName, char[] qualifiedSourceName, char[] sourceName, final TypeBinding typeBinding, char[][] discouragedNames, final char[][] forbiddenNames, boolean forCollection, int dim, int kind)12278 private void findVariableName( 12279 char[] token, 12280 char[] qualifiedPackageName, 12281 char[] qualifiedSourceName, 12282 char[] sourceName, 12283 final TypeBinding typeBinding, 12284 char[][] discouragedNames, 12285 final char[][] forbiddenNames, 12286 boolean forCollection, 12287 int dim, 12288 int kind){ 12289 12290 if(sourceName == null || sourceName.length == 0) 12291 return; 12292 12293 // compute variable name for non base type 12294 final char[] displayName; 12295 if (!forCollection) { 12296 if (dim > 0){ 12297 int l = qualifiedSourceName.length; 12298 displayName = new char[l+(2*dim)]; 12299 System.arraycopy(qualifiedSourceName, 0, displayName, 0, l); 12300 for(int i = 0; i < dim; i++){ 12301 displayName[l+(i*2)] = '['; 12302 displayName[l+(i*2)+1] = ']'; 12303 } 12304 } else { 12305 displayName = qualifiedSourceName; 12306 } 12307 } else { 12308 displayName = typeBinding.qualifiedSourceName(); 12309 } 12310 12311 final char[] t = token; 12312 final char[] q = qualifiedPackageName; 12313 INamingRequestor namingRequestor = new INamingRequestor() { 12314 void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){ 12315 int l = forbiddenNames == null ? 0 : forbiddenNames.length; 12316 for (int i = 0; i < l; i++) { 12317 if (CharOperation.equals(forbiddenNames[i], name, false)) return; 12318 } 12319 12320 if (CharOperation.prefixEquals(t, name, false)) { 12321 int relevance = computeBaseRelevance(); 12322 relevance += computeRelevanceForInterestingProposal(); 12323 relevance += computeRelevanceForCaseMatching(t, name); 12324 relevance += prefixAndSuffixRelevance; 12325 if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS; 12326 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name 12327 12328 // accept result 12329 CompletionEngine.this.noProposal = false; 12330 if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) { 12331 InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition); 12332 proposal.setSignature(getSignature(typeBinding)); 12333 proposal.setPackageName(q); 12334 proposal.setTypeName(displayName); 12335 proposal.setName(name); 12336 proposal.setCompletion(name); 12337 //proposal.setFlags(Flags.AccDefault); 12338 proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset); 12339 proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset); 12340 proposal.setRelevance(relevance); 12341 CompletionEngine.this.requestor.accept(proposal); 12342 if(DEBUG) { 12343 CompletionEngine.this.printDebug(proposal); 12344 } 12345 } 12346 } 12347 } 12348 12349 @Override 12350 public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) { 12351 accept(name, 0, reusedCharacters); 12352 } 12353 12354 @Override 12355 public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) { 12356 accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX, reusedCharacters); 12357 } 12358 12359 @Override 12360 public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) { 12361 accept( 12362 name, 12363 (isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX), 12364 reusedCharacters); 12365 } 12366 @Override 12367 public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) { 12368 accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters); 12369 } 12370 }; 12371 12372 InternalNamingConventions.suggestVariableNames( 12373 kind, 12374 InternalNamingConventions.BK_SIMPLE_TYPE_NAME, 12375 qualifiedSourceName, 12376 this.javaProject, 12377 dim, 12378 token, 12379 discouragedNames, 12380 true, 12381 namingRequestor); 12382 } 12383 12384 // Helper method for private void findVariableNames(char[] name, TypeReference type ) findVariableName( char[] token, char[] qualifiedPackageName, char[] qualifiedSourceName, char[] sourceName, final TypeBinding typeBinding, char[][] discouragedNames, final char[][] forbiddenNames, int dim, int kind)12385 private void findVariableName( 12386 char[] token, 12387 char[] qualifiedPackageName, 12388 char[] qualifiedSourceName, 12389 char[] sourceName, 12390 final TypeBinding typeBinding, 12391 char[][] discouragedNames, 12392 final char[][] forbiddenNames, 12393 int dim, 12394 int kind){ 12395 findVariableName( 12396 token, 12397 qualifiedPackageName, 12398 qualifiedSourceName, 12399 sourceName, 12400 typeBinding, 12401 discouragedNames, 12402 forbiddenNames, 12403 false, 12404 dim, 12405 kind); 12406 } findVariableNameForCollection( char[] token, char[] qualifiedPackageName, char[] qualifiedSourceName, char[] sourceName, final TypeBinding typeBinding, char[][] discouragedNames, final char[][] forbiddenNames, int kind)12407 private void findVariableNameForCollection( 12408 char[] token, 12409 char[] qualifiedPackageName, 12410 char[] qualifiedSourceName, 12411 char[] sourceName, 12412 final TypeBinding typeBinding, 12413 char[][] discouragedNames, 12414 final char[][] forbiddenNames, 12415 int kind){ 12416 12417 findVariableName( 12418 token, 12419 qualifiedPackageName, 12420 qualifiedSourceName, 12421 sourceName, 12422 typeBinding, 12423 discouragedNames, 12424 forbiddenNames, 12425 false, 12426 1, 12427 kind); 12428 } findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind)12429 private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind){ 12430 if(type != null && 12431 type.resolvedType != null) { 12432 TypeBinding tb = type.resolvedType; 12433 12434 if (tb.problemId() == ProblemReasons.NoError && 12435 TypeBinding.notEquals(tb, Scope.getBaseType(VOID))) { 12436 findVariableName( 12437 name, 12438 tb.leafComponentType().qualifiedPackageName(), 12439 tb.leafComponentType().qualifiedSourceName(), 12440 tb.leafComponentType().sourceName(), 12441 tb, 12442 discouragedNames, 12443 forbiddenNames, 12444 type.dimensions(), 12445 kind); 12446 12447 if (tb.isParameterizedType() && 12448 tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) { 12449 ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb); 12450 TypeBinding[] arguments = ptb.arguments; 12451 if (arguments != null && arguments.length == 1) { 12452 TypeBinding argument = arguments[0]; 12453 findVariableNameForCollection( 12454 name, 12455 argument.leafComponentType().qualifiedPackageName(), 12456 argument.leafComponentType().qualifiedSourceName(), 12457 argument.leafComponentType().sourceName(), 12458 tb, 12459 discouragedNames, 12460 forbiddenNames, 12461 kind); 12462 } 12463 } 12464 } 12465 } 12466 12467 } findVariablesAndMethods( char[] token, Scope scope, InvocationSite invocationSite, Scope invocationScope, boolean insideTypeAnnotation, boolean insideAnnotationAttribute)12468 private void findVariablesAndMethods( 12469 char[] token, 12470 Scope scope, 12471 InvocationSite invocationSite, 12472 Scope invocationScope, 12473 boolean insideTypeAnnotation, 12474 boolean insideAnnotationAttribute) { 12475 12476 if (token == null) 12477 return; 12478 12479 // Should local variables hide fields from the receiver type or any of its enclosing types? 12480 // we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod 12481 12482 boolean staticsOnly = false; 12483 // need to know if we're in a static context (or inside a constructor) 12484 int tokenLength = token.length; 12485 12486 ObjectVector localsFound = new ObjectVector(); 12487 ObjectVector fieldsFound = new ObjectVector(); 12488 ObjectVector methodsFound = new ObjectVector(); 12489 12490 Scope currentScope = scope; 12491 12492 if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 12493 done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 12494 12495 switch (currentScope.kind) { 12496 12497 case Scope.METHOD_SCOPE : 12498 // handle the error case inside an explicit constructor call (see MethodScope>>findField) 12499 MethodScope methodScope = (MethodScope) currentScope; 12500 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 12501 12502 //$FALL-THROUGH$ 12503 case Scope.BLOCK_SCOPE : 12504 BlockScope blockScope = (BlockScope) currentScope; 12505 12506 next : for (int i = 0, length = blockScope.locals.length; i < length; i++) { 12507 LocalVariableBinding local = blockScope.locals[i]; 12508 12509 if (local == null) 12510 break next; 12511 12512 if (tokenLength > local.name.length) 12513 continue next; 12514 12515 if (isFailedMatch(token, local.name)) 12516 continue next; 12517 12518 if (local.isSecret()) 12519 continue next; 12520 12521 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328674 12522 if (local.declaration.initialization != null && !local.declaration.type.isTypeNameVar(null)) { 12523 // proposal being asked inside field's initialization. Don't propose this field. 12524 continue next; 12525 } 12526 12527 // don't propose non constant variables or strings (1.6 or below) in case expression 12528 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=195346 12529 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=343342 12530 if (this.assistNodeIsInsideCase) { 12531 if (local.isFinal()) { 12532 if (this.assistNodeIsString){ 12533 if (local.type == null || local.type.id != TypeIds.T_JavaLangString) 12534 continue next; 12535 } else if (!(local.type instanceof BaseTypeBinding)) 12536 continue next; 12537 } else { 12538 continue next; // non-constants not allowed in case. 12539 } 12540 } 12541 12542 int ptr = this.uninterestingBindingsPtr; 12543 // Cases where the binding is uninteresting eg. for completion occurring inside a local var 12544 // declaration, the local var binding is uninteresting and shouldn't be proposed. 12545 while (ptr >= 0) { 12546 if (this.uninterestingBindings[ptr] == local) { 12547 continue next; 12548 } 12549 ptr--; 12550 } 12551 12552 for (int f = 0; f < localsFound.size; f++) { 12553 LocalVariableBinding otherLocal = 12554 (LocalVariableBinding) localsFound.elementAt(f); 12555 if (CharOperation.equals(otherLocal.name, local.name, true)) 12556 continue next; 12557 } 12558 localsFound.add(local); 12559 12560 int relevance = computeBaseRelevance(); 12561 relevance += computeRelevanceForResolution(); 12562 relevance += computeRelevanceForInterestingProposal(local); 12563 relevance += computeRelevanceForCaseMatching(token, local.name); 12564 relevance += computeRelevanceForExpectingType(local.type); 12565 relevance += computeRelevanceForEnumConstant(local.type); 12566 relevance += computeRelevanceForQualification(false); 12567 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable 12568 relevance += computeRelevanceForFinal(this.assistNodeIsInsideCase, local.isFinal()); 12569 this.noProposal = false; 12570 if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) { 12571 InternalCompletionProposal proposal = createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition); 12572 proposal.setSignature( 12573 local.type == null 12574 ? createTypeSignature( 12575 CharOperation.NO_CHAR, 12576 local.declaration.type.toString().toCharArray()) 12577 : getSignature(local.type)); 12578 if(local.type == null) { 12579 //proposal.setPackageName(null); 12580 proposal.setTypeName(local.declaration.type.toString().toCharArray()); 12581 } else { 12582 proposal.setPackageName(local.type.qualifiedPackageName()); 12583 proposal.setTypeName(local.type.qualifiedSourceName()); 12584 } 12585 proposal.setName(local.name); 12586 proposal.setCompletion(local.name); 12587 proposal.setFlags(local.modifiers); 12588 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 12589 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 12590 proposal.setRelevance(relevance); 12591 this.requestor.accept(proposal); 12592 if(DEBUG) { 12593 this.printDebug(proposal); 12594 } 12595 } 12596 } 12597 break; 12598 12599 case Scope.COMPILATION_UNIT_SCOPE : 12600 break done1; 12601 } 12602 currentScope = currentScope.parent; 12603 } 12604 } 12605 12606 checkCancel(); 12607 12608 boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF); 12609 boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF); 12610 12611 staticsOnly = false; 12612 currentScope = scope; 12613 12614 if(proposeField || proposeMethod) { 12615 done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found 12616 12617 switch (currentScope.kind) { 12618 case Scope.METHOD_SCOPE : 12619 // handle the error case inside an explicit constructor call (see MethodScope>>findField) 12620 MethodScope methodScope = (MethodScope) currentScope; 12621 staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall; 12622 break; 12623 case Scope.CLASS_SCOPE : 12624 ClassScope classScope = (ClassScope) currentScope; 12625 SourceTypeBinding enclosingType = classScope.referenceContext.binding; 12626 /* if (tokenLength == 0) { // only search inside the type itself if no prefix was provided 12627 findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly); 12628 findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false); 12629 break done; 12630 } else { */ 12631 if(!insideTypeAnnotation) { 12632 if(proposeField) { 12633 findFields( 12634 token, 12635 enclosingType, 12636 classScope, 12637 fieldsFound, 12638 localsFound, 12639 staticsOnly, 12640 invocationSite, 12641 invocationScope, 12642 true, 12643 true, 12644 null, 12645 null, 12646 null, 12647 false, 12648 null, 12649 -1, 12650 -1); 12651 } 12652 if(proposeMethod && !insideAnnotationAttribute) { 12653 findMethods( 12654 token, 12655 null, 12656 null, 12657 enclosingType, 12658 classScope, 12659 methodsFound, 12660 staticsOnly, 12661 false, 12662 invocationSite, 12663 invocationScope, 12664 true, 12665 false, 12666 true, 12667 null, 12668 null, 12669 null, 12670 false, 12671 null, 12672 -1, 12673 -1); 12674 } 12675 } 12676 staticsOnly |= enclosingType.isStatic(); 12677 insideTypeAnnotation = false; 12678 // } 12679 break; 12680 12681 case Scope.COMPILATION_UNIT_SCOPE : 12682 break done2; 12683 } 12684 currentScope = currentScope.parent; 12685 } 12686 12687 checkCancel(); 12688 12689 findFieldsAndMethodsFromStaticImports( 12690 token, 12691 scope, 12692 invocationSite, 12693 invocationScope, 12694 false, 12695 insideAnnotationAttribute, 12696 localsFound, 12697 fieldsFound, 12698 methodsFound, 12699 proposeField, 12700 proposeMethod); 12701 12702 if (this.assistNodeInJavadoc == 0) { 12703 12704 checkCancel(); 12705 12706 // search in favorites import 12707 findFieldsAndMethodsFromFavorites( 12708 token, 12709 scope, 12710 invocationSite, 12711 invocationScope, 12712 localsFound, 12713 fieldsFound, 12714 methodsFound); 12715 } 12716 12717 checkCancel(); 12718 12719 findEnumConstantsFromExpectedTypes( 12720 token, 12721 invocationScope, 12722 fieldsFound); 12723 } 12724 } 12725 getCompletedTypeSignature(ReferenceBinding referenceBinding)12726 private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) { 12727 char[] result = null; 12728 StringBuffer sig = new StringBuffer(10); 12729 if (!referenceBinding.isMemberType()) { 12730 char[] typeSig = referenceBinding.genericTypeSignature(); 12731 sig.append(typeSig, 0, typeSig.length); 12732 } else if (!this.insideQualifiedReference) { 12733 if (referenceBinding.isStatic()) { 12734 char[] typeSig = referenceBinding.signature(); 12735 sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon 12736 12737 TypeVariableBinding[] typeVariables = referenceBinding.typeVariables(); 12738 if (typeVariables != Binding.NO_TYPE_VARIABLES) { 12739 sig.append(Signature.C_GENERIC_START); 12740 for (int i = 0, length = typeVariables.length; i < length; i++) { 12741 sig.append(typeVariables[i].genericTypeSignature()); 12742 } 12743 sig.append(Signature.C_GENERIC_END); 12744 } 12745 sig.append(Signature.C_SEMICOLON); 12746 } else { 12747 char[] typeSig = referenceBinding.genericTypeSignature(); 12748 sig.append(typeSig, 0, typeSig.length); 12749 } 12750 } else { 12751 ReferenceBinding enclosingType = referenceBinding.enclosingType(); 12752 if (enclosingType.isParameterizedType()) { 12753 char[] typeSig = referenceBinding.genericTypeSignature(); 12754 sig.append(typeSig, 0, typeSig.length-1); 12755 12756 TypeVariableBinding[] typeVariables = referenceBinding.typeVariables(); 12757 if (typeVariables != Binding.NO_TYPE_VARIABLES) { 12758 sig.append(Signature.C_GENERIC_START); 12759 for (int i = 0, length = typeVariables.length; i < length; i++) { 12760 sig.append(typeVariables[i].genericTypeSignature()); 12761 } 12762 sig.append(Signature.C_GENERIC_END); 12763 } 12764 } else { 12765 char[] typeSig = referenceBinding.signature(); 12766 sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon 12767 12768 if (referenceBinding.isStatic()) { 12769 TypeVariableBinding[] typeVariables = referenceBinding.typeVariables(); 12770 if (typeVariables != Binding.NO_TYPE_VARIABLES) { 12771 sig.append(Signature.C_GENERIC_START); 12772 for (int i = 0, length = typeVariables.length; i < length; i++) { 12773 sig.append(typeVariables[i].genericTypeSignature()); 12774 } 12775 sig.append(Signature.C_GENERIC_END); 12776 } 12777 } 12778 } 12779 sig.append(Signature.C_SEMICOLON); 12780 } 12781 int sigLength = sig.length(); 12782 result = new char[sigLength]; 12783 sig.getChars(0, sigLength, result, 0); 12784 result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT); 12785 return result; 12786 } 12787 getFavoriteReferenceBindings(Scope scope)12788 private ImportBinding[] getFavoriteReferenceBindings(Scope scope) { 12789 if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings; 12790 12791 String[] favoriteReferences = this.requestor.getFavoriteReferences(); 12792 12793 if (favoriteReferences == null || favoriteReferences.length == 0) return null; 12794 12795 ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length]; 12796 12797 int count = 0; 12798 next : for (int i = 0; i < favoriteReferences.length; i++) { 12799 String favoriteReference = favoriteReferences[i]; 12800 12801 int length; 12802 if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next; 12803 12804 boolean onDemand = favoriteReference.charAt(length - 1) == '*'; 12805 12806 char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray()); 12807 if (onDemand) { 12808 compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1); 12809 } 12810 12811 // remove duplicate and conflicting 12812 for (int j = 0; j < count; j++) { 12813 ImportReference f = resolvedImports[j].reference; 12814 12815 if (CharOperation.equals(f.tokens, compoundName)) continue next; 12816 12817 if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) { 12818 if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1])) 12819 continue next; 12820 } 12821 } 12822 12823 boolean isStatic = true; 12824 12825 ImportReference importReference = 12826 new ImportReference( 12827 compoundName, 12828 new long[compoundName.length], 12829 onDemand, 12830 isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault); 12831 12832 Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand); 12833 12834 if (!importBinding.isValidBinding()) { 12835 continue next; 12836 } 12837 12838 if (importBinding instanceof PackageBinding) { 12839 continue next; 12840 } 12841 12842 resolvedImports[count++] = 12843 new ImportBinding(compoundName, onDemand, importBinding, importReference); 12844 } 12845 12846 if (resolvedImports.length > count) 12847 System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count); 12848 12849 return this.favoriteReferenceBindings = resolvedImports; 12850 } 12851 getNoCacheNameEnvironment()12852 private INameEnvironment getNoCacheNameEnvironment() { 12853 if (this.noCacheNameEnvironment == null) { 12854 JavaModelManager.getJavaModelManager().cacheZipFiles(this); 12855 this.noCacheNameEnvironment = IndexBasedJavaSearchEnvironment.create(Collections.singletonList(this.javaProject), this.owner == null ? null : JavaModelManager.getJavaModelManager().getWorkingCopies(this.owner, true/*add primary WCs*/)); 12856 } 12857 return this.noCacheNameEnvironment; 12858 } 12859 12860 @Override getParser()12861 public AssistParser getParser() { 12862 12863 return this.parser; 12864 } hasArrayTypeAsExpectedSuperTypes()12865 protected boolean hasArrayTypeAsExpectedSuperTypes() { 12866 if ((this.expectedTypesFilter & ~SUBTYPE) != 0) return false; 12867 12868 if (!this.hasComputedExpectedArrayTypes) { 12869 if(this.expectedTypes != null) { 12870 done : for (int i = 0; i <= this.expectedTypesPtr; i++) { 12871 if(this.expectedTypes[i].isArrayType()) { 12872 this.hasExpectedArrayTypes = true; 12873 break done; 12874 } 12875 } 12876 } 12877 12878 this.hasComputedExpectedArrayTypes = true; 12879 } 12880 12881 return this.hasExpectedArrayTypes; 12882 } hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope)12883 protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) { 12884 if (this.targetedElement == TagBits.AnnotationForPackage) { 12885 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 12886 if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) { 12887 return false; 12888 } 12889 } else if (this.targetedElement == TagBits.AnnotationForModule) { 12890 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 12891 if(target != 0 && (target & TagBits.AnnotationForModule) == 0) { 12892 return false; 12893 } 12894 } else if ((this.targetedElement & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) != 0) { 12895 if (scope.parent != null && 12896 scope.parent.parent != null && 12897 scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType && 12898 scope.parent.parent instanceof CompilationUnitScope) { 12899 long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK; 12900 if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) { 12901 if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType | TagBits.AnnotationForTypeUse)) == 0) { 12902 return false; 12903 } 12904 } else { 12905 if (target != 0 && (target & (TagBits.AnnotationForType | TagBits.AnnotationForTypeUse)) == 0) { 12906 return false; 12907 } 12908 } 12909 } 12910 } 12911 return true; 12912 } 12913 /** 12914 * Returns completion string inserted inside a specified inline tag. 12915 * @param completionName 12916 * @return char[] Completion text inclunding specified inline tag 12917 */ inlineTagCompletion(char[] completionName, char[] inlineTag)12918 private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) { 12919 int tagLength= inlineTag.length; 12920 int completionLength = completionName.length; 12921 int inlineLength = 2+tagLength+1+completionLength+1; 12922 char[] inlineCompletion = new char[inlineLength]; 12923 inlineCompletion[0] = '{'; 12924 inlineCompletion[1] = '@'; 12925 System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength); 12926 inlineCompletion[tagLength+2] = ' '; 12927 System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength); 12928 // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026) 12929 //inlineCompletion[inlineLength-2] = ' '; 12930 inlineCompletion[inlineLength-1] = '}'; 12931 return inlineCompletion; 12932 } isAllowingLongComputationProposals()12933 private boolean isAllowingLongComputationProposals() { 12934 return this.monitor != null; 12935 } 12936 12937 /** 12938 * Checks whether name matches the token according to the current 12939 * code completion settings (substring match, camel case match etc.) 12940 * and sets whether the current match is a suffix proposal. 12941 * 12942 * @param token the token that is tested 12943 * @param name the name to match 12944 * @return <code>true</code> if the token does not match, 12945 * <code>false</code> otherwise 12946 */ isFailedMatch(char[] token, char[] name)12947 private boolean isFailedMatch(char[] token, char[] name) { 12948 if ((this.options.substringMatch && CharOperation.substringMatch(token, name)) 12949 || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, name)) 12950 || CharOperation.prefixEquals(token, name, false) 12951 || (this.options.subwordMatch && CharOperation.subWordMatch(token, name))) { 12952 return false; 12953 } 12954 12955 return true; 12956 } isForbidden(ReferenceBinding binding)12957 private boolean isForbidden(ReferenceBinding binding) { 12958 for (int i = 0; i <= this.forbbidenBindingsPtr; i++) { 12959 if(this.forbbidenBindings[i] == binding) { 12960 return true; 12961 } 12962 } 12963 if (!isValidPackageName(binding.qualifiedPackageName())) { 12964 return true; 12965 } 12966 return false; 12967 } 12968 isForbidden(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames)12969 private boolean isForbidden(char[] givenPkgName, char[] givenTypeName, char[][] enclosingTypeNames) { 12970 // CharOperation.concatWith() handles the cases where input args are null/empty 12971 char[] fullTypeName = CharOperation.concatWith(enclosingTypeNames, givenTypeName, '.'); 12972 for (int i = 0; i <= this.forbbidenBindingsPtr; i++) { 12973 if (this.forbbidenBindings[i] instanceof TypeBinding) { 12974 TypeBinding typeBinding = (TypeBinding) this.forbbidenBindings[i]; 12975 char[] currPkgName = typeBinding.qualifiedPackageName(); 12976 if (CharOperation.equals(givenPkgName, currPkgName)) { 12977 char[] currTypeName = typeBinding.qualifiedSourceName(); 12978 if (CharOperation.equals(fullTypeName, currTypeName)) { 12979 return true; 12980 } 12981 } 12982 } 12983 } 12984 12985 if (!isValidPackageName(givenPkgName)) { 12986 return true; 12987 } 12988 12989 return false; 12990 } 12991 isIgnored(int kind)12992 private boolean isIgnored(int kind) { 12993 return this.requestor.isIgnored(kind); 12994 } isIgnored(int kind, boolean missingTypes)12995 boolean isIgnored(int kind, boolean missingTypes) { 12996 return this.requestor.isIgnored(kind) || 12997 (missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF)); 12998 } 12999 isIgnored(int kind, int requiredProposalKind)13000 private boolean isIgnored(int kind, int requiredProposalKind) { 13001 return this.requestor.isIgnored(kind) || 13002 !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind); 13003 } 13004 isValidPackageName(char[] packageName)13005 private boolean isValidPackageName(char[] packageName) { 13006 if (this.validPackageNames.includes(packageName)) { 13007 return true; 13008 } 13009 13010 if (this.invalidPackageNames.includes(packageName)) { 13011 return false; 13012 } 13013 13014 char[][] names = CharOperation.splitOn('.', packageName); 13015 for (int i = 0, length = names.length; i < length; i++) { 13016 if (!Util.isValidFolderNameForPackage(new String(names[i]), this.sourceLevel, this.complianceLevel)) { 13017 this.invalidPackageNames.add(packageName); 13018 return false; 13019 } 13020 } 13021 13022 this.validPackageNames.add(packageName); 13023 return true; 13024 } 13025 isValidParent(ASTNode parent, ASTNode node, Scope scope)13026 private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){ 13027 13028 if(parent instanceof ParameterizedSingleTypeReference) { 13029 ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent; 13030 if (ref.resolvedType == null) { 13031 return false; 13032 } 13033 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 13034 int length = ref.typeArguments == null ? 0 : ref.typeArguments.length; 13035 int nodeIndex = -1; 13036 for(int i = length - 1 ; i > -1 ; i--) { 13037 if(node == ref.typeArguments[i]) { 13038 nodeIndex = i; 13039 break; 13040 } 13041 } 13042 if(nodeIndex > -1 && (typeVariables == null || typeVariables.length < nodeIndex + 1)) { 13043 TypeBinding[] typeBindings = new TypeBinding[nodeIndex + 1]; 13044 for(int i = 0; i < nodeIndex; i++) { 13045 typeBindings[i] = ref.typeArguments[i].resolvedType; 13046 } 13047 typeBindings[nodeIndex] = scope.getJavaLangObject(); 13048 if(typeVariables == null || typeVariables.length == 0) { 13049 scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings); 13050 } else { 13051 scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings); 13052 } 13053 return false; 13054 } 13055 } else if(parent instanceof ParameterizedQualifiedTypeReference) { 13056 ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent; 13057 TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables(); 13058 TypeReference[][] arguments = ref.typeArguments; 13059 int iLength = arguments == null ? 0 : arguments.length; 13060 for (int i = 0; i < iLength; i++) { 13061 int jLength = arguments[i] == null ? 0 : arguments[i].length; 13062 for (int j = 0; j < jLength; j++) { 13063 if(arguments[i][j] == node && (typeVariables == null || typeVariables.length <= j)) { 13064 TypeBinding[] typeBindings = new TypeBinding[j + 1]; 13065 for(int k = 0; k < j; k++) { 13066 typeBindings[k] = ref.typeArguments[i][k].resolvedType; 13067 } 13068 typeBindings[j] = scope.getJavaLangObject(); 13069 if(typeVariables == null || typeVariables.length == 0) { 13070 scope.problemReporter().nonGenericTypeCannotBeParameterized(0, ref, ref.resolvedType, typeBindings); 13071 } else { 13072 scope.problemReporter().incorrectArityForParameterizedType(ref, ref.resolvedType, typeBindings); 13073 } 13074 return false; 13075 } 13076 } 13077 } 13078 } 13079 return true; 13080 } mustQualifyType(ReferenceBinding type, char[] packageName, Scope scope)13081 private boolean mustQualifyType(ReferenceBinding type, char[] packageName, Scope scope) { 13082 if(!mustQualifyType( 13083 packageName, 13084 type.sourceName(), 13085 type.isMemberType() ? type.enclosingType().qualifiedSourceName() : null, 13086 type.modifiers)) { 13087 return false; 13088 } 13089 ReferenceBinding enclosingType = scope.enclosingSourceType(); 13090 while (enclosingType != null) { 13091 ReferenceBinding currentType = enclosingType; 13092 while (currentType != null) { 13093 ReferenceBinding[] memberTypes = currentType.memberTypes(); 13094 if(memberTypes != null) { 13095 for (int i = 0; i < memberTypes.length; i++) { 13096 if (CharOperation.equals(memberTypes[i].sourceName, type.sourceName()) && 13097 memberTypes[i].canBeSeenBy(scope)) { 13098 return TypeBinding.notEquals(memberTypes[i], type); 13099 } 13100 } 13101 } 13102 currentType = currentType.superclass(); 13103 } 13104 enclosingType = enclosingType.enclosingType(); 13105 } 13106 return true; 13107 } parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic)13108 private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){ 13109 StringBuffer prefix = new StringBuffer(); 13110 prefix.append("public class FakeType {\n "); //$NON-NLS-1$ 13111 if(isStatic) { 13112 prefix.append("static "); //$NON-NLS-1$ 13113 } 13114 prefix.append("{\n"); //$NON-NLS-1$ 13115 for (int i = 0; i < localVariableTypeNames.length; i++) { 13116 ASTNode.printModifiers(localVariableModifiers[i], prefix); 13117 prefix.append(' '); 13118 prefix.append(localVariableTypeNames[i]); 13119 prefix.append(' '); 13120 prefix.append(localVariableNames[i]); 13121 prefix.append(';'); 13122 } 13123 13124 char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$ 13125 this.offset = prefix.length(); 13126 13127 String encoding = this.compilerOptions.defaultEncoding; 13128 @SuppressWarnings("deprecation") 13129 BasicCompilationUnit fakeUnit = new BasicCompilationUnit( 13130 fakeSource, 13131 null, 13132 "FakeType.java", //$NON-NLS-1$ 13133 encoding); 13134 13135 this.actualCompletionPosition = prefix.length() + position - 1; 13136 13137 CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit); 13138 CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition); 13139 13140 parseBlockStatements(fakeAST, this.actualCompletionPosition); 13141 13142 return (Initializer)fakeAST.types[0].fields[0]; 13143 } printDebug(CategorizedProblem error)13144 protected void printDebug(CategorizedProblem error) { 13145 if(CompletionEngine.DEBUG) { 13146 System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$ 13147 System.out.print(error); 13148 System.out.println(")"); //$NON-NLS-1$ 13149 } 13150 } printDebug(CompletionProposal proposal)13151 protected void printDebug(CompletionProposal proposal){ 13152 StringBuffer buffer = new StringBuffer(); 13153 printDebug(proposal, 0, buffer); 13154 System.out.println(buffer.toString()); 13155 } 13156 printDebug(CompletionProposal proposal, int tab, StringBuffer buffer)13157 private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){ 13158 printDebugTab(tab, buffer); 13159 buffer.append("COMPLETION - "); //$NON-NLS-1$ 13160 switch(proposal.getKind()) { 13161 case CompletionProposal.ANONYMOUS_CLASS_DECLARATION : 13162 buffer.append("ANONYMOUS_CLASS_DECLARATION"); //$NON-NLS-1$ 13163 break; 13164 case CompletionProposal.FIELD_REF : 13165 buffer.append("FIELD_REF"); //$NON-NLS-1$ 13166 break; 13167 case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER : 13168 buffer.append("FIELD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$ 13169 break; 13170 case CompletionProposal.KEYWORD : 13171 buffer.append("KEYWORD"); //$NON-NLS-1$ 13172 break; 13173 case CompletionProposal.LABEL_REF : 13174 buffer.append("LABEL_REF"); //$NON-NLS-1$ 13175 break; 13176 case CompletionProposal.LOCAL_VARIABLE_REF : 13177 buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$ 13178 break; 13179 case CompletionProposal.METHOD_DECLARATION : 13180 buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$ 13181 break; 13182 case CompletionProposal.METHOD_REF : 13183 buffer.append("METHOD_REF"); //$NON-NLS-1$ 13184 break; 13185 case CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER : 13186 buffer.append("METHOD_REF_WITH_CASTED_RECEIVER"); //$NON-NLS-1$ 13187 break; 13188 case CompletionProposal.MODULE_DECLARATION : 13189 buffer.append("MODULE_DECLARATION"); //$NON-NLS-1$ 13190 break; 13191 case CompletionProposal.MODULE_REF : 13192 buffer.append("MODULE_REF"); //$NON-NLS-1$ 13193 break; 13194 case CompletionProposal.PACKAGE_REF : 13195 buffer.append("PACKAGE_REF"); //$NON-NLS-1$ 13196 break; 13197 case CompletionProposal.TYPE_REF : 13198 buffer.append("TYPE_REF"); //$NON-NLS-1$ 13199 break; 13200 case CompletionProposal.VARIABLE_DECLARATION : 13201 buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$ 13202 break; 13203 case CompletionProposal.POTENTIAL_METHOD_DECLARATION : 13204 buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$ 13205 break; 13206 case CompletionProposal.METHOD_NAME_REFERENCE : 13207 buffer.append("METHOD_NAME_REFERENCE"); //$NON-NLS-1$ 13208 break; 13209 case CompletionProposal.ANNOTATION_ATTRIBUTE_REF : 13210 buffer.append("ANNOTATION_ATTRIBUT_REF"); //$NON-NLS-1$ 13211 break; 13212 case CompletionProposal.FIELD_IMPORT : 13213 buffer.append("FIELD_IMPORT"); //$NON-NLS-1$ 13214 break; 13215 case CompletionProposal.METHOD_IMPORT : 13216 buffer.append("METHOD_IMPORT"); //$NON-NLS-1$ 13217 break; 13218 case CompletionProposal.TYPE_IMPORT : 13219 buffer.append("TYPE_IMPORT"); //$NON-NLS-1$ 13220 break; 13221 case CompletionProposal.CONSTRUCTOR_INVOCATION : 13222 buffer.append("CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$ 13223 break; 13224 case CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION : 13225 buffer.append("ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION"); //$NON-NLS-1$ 13226 break; 13227 default : 13228 buffer.append("PROPOSAL"); //$NON-NLS-1$ 13229 break; 13230 13231 } 13232 13233 buffer.append("{\n");//$NON-NLS-1$ 13234 printDebugTab(tab, buffer); 13235 buffer.append("\tCompletion[").append(proposal.getCompletion() == null ? "null".toCharArray() : proposal.getCompletion()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13236 printDebugTab(tab, buffer); 13237 buffer.append("\tDeclarationSignature[").append(proposal.getDeclarationSignature() == null ? "null".toCharArray() : proposal.getDeclarationSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13238 printDebugTab(tab, buffer); 13239 buffer.append("\tDeclarationKey[").append(proposal.getDeclarationKey() == null ? "null".toCharArray() : proposal.getDeclarationKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13240 printDebugTab(tab, buffer); 13241 buffer.append("\tSignature[").append(proposal.getSignature() == null ? "null".toCharArray() : proposal.getSignature()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13242 printDebugTab(tab, buffer); 13243 buffer.append("\tKey[").append(proposal.getKey() == null ? "null".toCharArray() : proposal.getKey()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13244 printDebugTab(tab, buffer); 13245 buffer.append("\tName[").append(proposal.getName() == null ? "null".toCharArray() : proposal.getName()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 13246 13247 printDebugTab(tab, buffer); 13248 buffer.append("\tFlags[");//$NON-NLS-1$ 13249 int flags = proposal.getFlags(); 13250 buffer.append(Flags.toString(flags)); 13251 if((flags & Flags.AccInterface) != 0) buffer.append("interface ");//$NON-NLS-1$ 13252 if((flags & Flags.AccEnum) != 0) buffer.append("enum ");//$NON-NLS-1$ 13253 buffer.append("]\n"); //$NON-NLS-1$ 13254 13255 CompletionProposal[] proposals = proposal.getRequiredProposals(); 13256 if(proposals != null) { 13257 printDebugTab(tab, buffer); 13258 buffer.append("\tRequiredProposals[");//$NON-NLS-1$ 13259 for (int i = 0; i < proposals.length; i++) { 13260 buffer.append("\n"); //$NON-NLS-1$ 13261 printDebug(proposals[i], tab + 2, buffer); 13262 } 13263 printDebugTab(tab, buffer); 13264 buffer.append("\n\t]\n"); //$NON-NLS-1$ 13265 } 13266 13267 printDebugTab(tab, buffer); 13268 buffer.append("\tCompletionLocation[").append(proposal.getCompletionLocation()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13269 int start = proposal.getReplaceStart(); 13270 int end = proposal.getReplaceEnd(); 13271 printDebugTab(tab, buffer); 13272 buffer.append("\tReplaceStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ 13273 buffer.append("-ReplaceEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13274 start = proposal.getTokenStart(); 13275 end = proposal.getTokenEnd(); 13276 printDebugTab(tab, buffer); 13277 buffer.append("\tTokenStart[").append(start).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ 13278 buffer.append("-TokenEnd[").append(end).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13279 if (this.source != null) { 13280 printDebugTab(tab, buffer); 13281 buffer.append("\tReplacedText[").append(this.source, start, end-start).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13282 } 13283 printDebugTab(tab, buffer); 13284 buffer.append("\tTokenStart[").append(proposal.getTokenStart()).append("]"); //$NON-NLS-1$ //$NON-NLS-2$ 13285 buffer.append("-TokenEnd[").append(proposal.getTokenEnd()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13286 printDebugTab(tab, buffer); 13287 buffer.append("\tRelevance[").append(proposal.getRelevance()).append("]\n"); //$NON-NLS-1$ //$NON-NLS-2$ 13288 13289 printDebugTab(tab, buffer); 13290 buffer.append("}\n");//$NON-NLS-1$ 13291 } 13292 printDebugTab(int tab, StringBuffer buffer)13293 private void printDebugTab(int tab, StringBuffer buffer) { 13294 for (int i = 0; i < tab; i++) { 13295 buffer.append('\t'); 13296 } 13297 } 13298 proposeConstructor(AcceptedConstructor deferredProposal, Scope scope)13299 private void proposeConstructor(AcceptedConstructor deferredProposal, Scope scope) { 13300 if (deferredProposal.proposeConstructor) { 13301 proposeConstructor( 13302 deferredProposal.simpleTypeName, 13303 deferredProposal.parameterCount, 13304 deferredProposal.signature, 13305 deferredProposal.parameterTypes, 13306 deferredProposal.parameterNames, 13307 deferredProposal.modifiers, 13308 deferredProposal.packageName, 13309 deferredProposal.typeModifiers, 13310 deferredProposal.accessibility, 13311 deferredProposal.simpleTypeName, 13312 deferredProposal.fullyQualifiedName, 13313 deferredProposal.mustBeQualified, 13314 scope, 13315 deferredProposal.extraFlags); 13316 } 13317 } 13318 proposeConstructor( char[] simpleTypeName, int parameterCount, char[] signature, char[][] parameterTypes, char[][] parameterNames, int modifiers, char[] packageName, int typeModifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope, int extraFlags)13319 private void proposeConstructor( 13320 char[] simpleTypeName, 13321 int parameterCount, 13322 char[] signature, 13323 char[][] parameterTypes, 13324 char[][] parameterNames, 13325 int modifiers, 13326 char[] packageName, 13327 int typeModifiers, 13328 int accessibility, 13329 char[] typeName, 13330 char[] fullyQualifiedName, 13331 boolean isQualified, 13332 Scope scope, 13333 int extraFlags) { 13334 char[] typeCompletion = fullyQualifiedName; 13335 if(isQualified) { 13336 if (packageName == null || packageName.length == 0) 13337 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 13338 return; // ignore types from the default package from outside it 13339 } else { 13340 typeCompletion = simpleTypeName; 13341 } 13342 13343 ReferenceBinding typeBinding = this.lookupEnvironment.getType(CharOperation.splitOn('.', fullyQualifiedName)); 13344 13345 int relevance = computeBaseRelevance(); 13346 relevance += computeRelevanceForResolution(); 13347 relevance += computeRelevanceForInterestingProposal(); 13348 relevance += computeRelevanceForRestrictions(accessibility); 13349 relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName); 13350 relevance += computeRelevanceForExpectingType(typeBinding); 13351 relevance += computeRelevanceForQualification(isQualified); 13352 relevance += computeRelevanceForConstructor(); 13353 13354 boolean isInterface = false; 13355 int kind = typeModifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation); 13356 switch (kind) { 13357 case ClassFileConstants.AccAnnotation: 13358 case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface: 13359 relevance += computeRelevanceForAnnotation(); 13360 relevance += computeRelevanceForInterface(); 13361 isInterface = true; 13362 break; 13363 case ClassFileConstants.AccEnum: 13364 relevance += computeRelevanceForEnum(); 13365 break; 13366 case ClassFileConstants.AccInterface: 13367 relevance += computeRelevanceForInterface(); 13368 isInterface = true; 13369 break; 13370 default: 13371 relevance += computeRelevanceForClass(); 13372 relevance += computeRelevanceForException(simpleTypeName); 13373 break; 13374 } 13375 13376 char[] completion; 13377 if (this.source != null 13378 && this.source.length > this.endPosition 13379 && this.source[this.endPosition] == '(') { 13380 completion = CharOperation.NO_CHAR; 13381 } else { 13382 completion = new char[] { '(', ')' }; 13383 } 13384 13385 InternalCompletionProposal typeProposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition); 13386 typeProposal.nameLookup = this.nameEnvironment.nameLookup; 13387 typeProposal.completionEngine = this; 13388 typeProposal.setDeclarationSignature(packageName); 13389 typeProposal.setSignature(createNonGenericTypeSignature(packageName, typeName)); 13390 typeProposal.setPackageName(packageName); 13391 typeProposal.setTypeName(typeName); 13392 typeProposal.setCompletion(typeCompletion); 13393 typeProposal.setFlags(typeModifiers); 13394 typeProposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 13395 typeProposal.setTokenRange(this.startPosition - this.offset, this.endPosition - this.offset); 13396 typeProposal.setRelevance(relevance); 13397 13398 switch (parameterCount) { 13399 case -1: // default constructor 13400 int flags = Flags.AccPublic; 13401 if (Flags.isDeprecated(typeModifiers)) { 13402 flags |= Flags.AccDeprecated; 13403 } 13404 13405 if (isInterface || (typeModifiers & ClassFileConstants.AccAbstract) != 0) { 13406 this.noProposal = false; 13407 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13408 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13409 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13410 proposal.setDeclarationKey(createBindingKey(packageName, typeName)); 13411 proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE); 13412 proposal.setDeclarationPackageName(packageName); 13413 proposal.setDeclarationTypeName(typeName); 13414 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13415 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13416 proposal.setParameterNames(CharOperation.NO_CHAR_CHAR); 13417 proposal.setName(simpleTypeName); 13418 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13419 proposal.setIsContructor(true); 13420 proposal.setCompletion(completion); 13421 proposal.setFlags(flags); 13422 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13423 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13424 proposal.setRelevance(relevance); 13425 this.requestor.accept(proposal); 13426 if(DEBUG) { 13427 this.printDebug(proposal); 13428 } 13429 } 13430 } else { 13431 this.noProposal = false; 13432 if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13433 InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13434 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13435 proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE); 13436 proposal.setDeclarationPackageName(packageName); 13437 proposal.setDeclarationTypeName(typeName); 13438 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13439 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13440 proposal.setParameterNames(CharOperation.NO_CHAR_CHAR); 13441 proposal.setName(simpleTypeName); 13442 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13443 proposal.setIsContructor(true); 13444 proposal.setCompletion(completion); 13445 proposal.setFlags(flags); 13446 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13447 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13448 proposal.setRelevance(relevance); 13449 this.requestor.accept(proposal); 13450 if(DEBUG) { 13451 this.printDebug(proposal); 13452 } 13453 } 13454 } 13455 break; 13456 case 0: // constructor with no parameter 13457 13458 if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) { 13459 this.noProposal = false; 13460 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13461 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13462 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13463 proposal.setDeclarationKey(createBindingKey(packageName, typeName)); 13464 proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE); 13465 proposal.setDeclarationPackageName(packageName); 13466 proposal.setDeclarationTypeName(typeName); 13467 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13468 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13469 proposal.setParameterNames(CharOperation.NO_CHAR_CHAR); 13470 proposal.setName(simpleTypeName); 13471 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13472 proposal.setIsContructor(true); 13473 proposal.setCompletion(completion); 13474 proposal.setFlags(modifiers); 13475 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13476 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13477 proposal.setRelevance(relevance); 13478 this.requestor.accept(proposal); 13479 if(DEBUG) { 13480 this.printDebug(proposal); 13481 } 13482 } 13483 } else { 13484 this.noProposal = false; 13485 if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13486 InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13487 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13488 proposal.setSignature(DEFAULT_CONSTRUCTOR_SIGNATURE); 13489 proposal.setDeclarationPackageName(packageName); 13490 proposal.setDeclarationTypeName(typeName); 13491 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13492 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13493 proposal.setParameterNames(CharOperation.NO_CHAR_CHAR); 13494 proposal.setName(simpleTypeName); 13495 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13496 proposal.setIsContructor(true); 13497 proposal.setCompletion(completion); 13498 proposal.setFlags(modifiers); 13499 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13500 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13501 proposal.setRelevance(relevance); 13502 this.requestor.accept(proposal); 13503 if(DEBUG) { 13504 this.printDebug(proposal); 13505 } 13506 } 13507 } 13508 break; 13509 default: // constructor with parameter 13510 if (signature == null) { 13511 // resolve type to found parameter types 13512 signature = getResolvedSignature(parameterTypes, fullyQualifiedName, parameterCount, scope); 13513 if (signature == null) return; 13514 } else { 13515 signature = CharOperation.replaceOnCopy(signature, '/', '.'); 13516 } 13517 13518 int parameterNamesLength = parameterNames == null ? 0 : parameterNames.length; 13519 if (parameterCount != parameterNamesLength) { 13520 parameterNames = null; 13521 } 13522 13523 if ((typeModifiers & ClassFileConstants.AccAbstract) != 0) { 13524 this.noProposal = false; 13525 if(!isIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13526 InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13527 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13528 proposal.setDeclarationKey(createBindingKey(packageName, typeName)); 13529 proposal.setSignature(signature); 13530 proposal.setDeclarationPackageName(packageName); 13531 proposal.setDeclarationTypeName(typeName); 13532 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13533 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13534 if (parameterNames != null) { 13535 proposal.setParameterNames(parameterNames); 13536 } else { 13537 proposal.setHasNoParameterNamesFromIndex(true); 13538 } 13539 proposal.setName(simpleTypeName); 13540 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13541 proposal.setIsContructor(true); 13542 proposal.setCompletion(completion); 13543 proposal.setFlags(modifiers); 13544 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13545 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13546 proposal.setRelevance(relevance); 13547 this.requestor.accept(proposal); 13548 if(DEBUG) { 13549 this.printDebug(proposal); 13550 } 13551 } 13552 } else { 13553 this.noProposal = false; 13554 if(!isIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, CompletionProposal.TYPE_REF)) { 13555 InternalCompletionProposal proposal = createProposal(CompletionProposal.CONSTRUCTOR_INVOCATION, this.actualCompletionPosition); 13556 proposal.setDeclarationSignature(createNonGenericTypeSignature(packageName, typeName)); 13557 proposal.setSignature(signature); 13558 proposal.setDeclarationPackageName(packageName); 13559 proposal.setDeclarationTypeName(typeName); 13560 proposal.setParameterPackageNames(CharOperation.NO_CHAR_CHAR); 13561 proposal.setParameterTypeNames(CharOperation.NO_CHAR_CHAR); 13562 if (parameterNames != null) { 13563 proposal.setParameterNames(parameterNames); 13564 } else { 13565 proposal.setHasNoParameterNamesFromIndex(true); 13566 } 13567 proposal.setName(simpleTypeName); 13568 proposal.setRequiredProposals(new CompletionProposal[]{typeProposal}); 13569 proposal.setIsContructor(true); 13570 proposal.setCompletion(completion); 13571 proposal.setFlags(modifiers); 13572 proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset); 13573 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13574 proposal.setRelevance(relevance); 13575 13576 this.requestor.accept(proposal); 13577 if(DEBUG) { 13578 this.printDebug(proposal); 13579 } 13580 } 13581 } 13582 break; 13583 } 13584 } 13585 proposeNewMethod(char[] token, ReferenceBinding reference)13586 private void proposeNewMethod(char[] token, ReferenceBinding reference) { 13587 if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) { 13588 int relevance = computeBaseRelevance(); 13589 relevance += computeRelevanceForResolution(); 13590 relevance += computeRelevanceForInterestingProposal(); 13591 relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method 13592 13593 InternalCompletionProposal proposal = createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition); 13594 proposal.setDeclarationSignature(getSignature(reference)); 13595 proposal.setSignature( 13596 createMethodSignature( 13597 CharOperation.NO_CHAR_CHAR, 13598 CharOperation.NO_CHAR_CHAR, 13599 CharOperation.NO_CHAR, 13600 VOID)); 13601 proposal.setDeclarationPackageName(reference.qualifiedPackageName()); 13602 proposal.setDeclarationTypeName(reference.qualifiedSourceName()); 13603 13604 //proposal.setPackageName(null); 13605 proposal.setTypeName(VOID); 13606 proposal.setName(token); 13607 //proposal.setParameterPackageNames(null); 13608 //proposal.setParameterTypeNames(null); 13609 //proposal.setPackageName(null); 13610 proposal.setCompletion(token); 13611 proposal.setFlags(Flags.AccPublic); 13612 proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset); 13613 proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset); 13614 proposal.setRelevance(relevance); 13615 this.requestor.accept(proposal); 13616 if(DEBUG) { 13617 this.printDebug(proposal); 13618 } 13619 } 13620 } 13621 proposeType( char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope)13622 private void proposeType( 13623 char[] packageName, 13624 char[] simpleTypeName, 13625 int modifiers, 13626 int accessibility, 13627 char[] typeName, 13628 char[] fullyQualifiedName, 13629 boolean isQualified, 13630 Scope scope) { 13631 char[] completionName = fullyQualifiedName; 13632 if(isQualified) { 13633 if (packageName == null || packageName.length == 0) 13634 if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR) 13635 return; // ignore types from the default package from outside it 13636 } else { 13637 completionName = simpleTypeName; 13638 } 13639 13640 TypeBinding guessedType = null; 13641 if ((modifiers & ClassFileConstants.AccAnnotation) != 0 && 13642 this.assistNodeIsAnnotation && 13643 (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) { 13644 char[][] cn = CharOperation.splitOn('.', fullyQualifiedName); 13645 13646 TypeReference ref; 13647 if (cn.length == 1) { 13648 ref = new SingleTypeReference(simpleTypeName, 0); 13649 } else { 13650 ref = new QualifiedTypeReference(cn,new long[cn.length]); 13651 } 13652 13653 switch (scope.kind) { 13654 case Scope.METHOD_SCOPE : 13655 case Scope.BLOCK_SCOPE : 13656 guessedType = ref.resolveType((BlockScope)scope); 13657 break; 13658 case Scope.CLASS_SCOPE : 13659 guessedType = ref.resolveType((ClassScope)scope); 13660 break; 13661 } 13662 13663 if (guessedType == null || !guessedType.isValidBinding()) return; 13664 13665 if (!hasPossibleAnnotationTarget(guessedType, scope)) return; 13666 } 13667 13668 int relevance = computeBaseRelevance(); 13669 relevance += computeRelevanceForResolution(); 13670 relevance += computeRelevanceForInterestingProposal(packageName, fullyQualifiedName); 13671 relevance += computeRelevanceForRestrictions(accessibility); 13672 relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName); 13673 relevance += computeRelevanceForExpectingType(packageName, simpleTypeName); 13674 relevance += computeRelevanceForQualification(isQualified); 13675 13676 int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation); 13677 switch (kind) { 13678 case ClassFileConstants.AccAnnotation: 13679 case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface: 13680 relevance += computeRelevanceForAnnotation(); 13681 if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType); 13682 relevance += computeRelevanceForInterface(); 13683 break; 13684 case ClassFileConstants.AccEnum: 13685 relevance += computeRelevanceForEnum(); 13686 break; 13687 case ClassFileConstants.AccInterface: 13688 relevance += computeRelevanceForInterface(); 13689 break; 13690 default: 13691 relevance += computeRelevanceForClass(); 13692 relevance += computeRelevanceForException(simpleTypeName); 13693 break; 13694 } 13695 13696 this.noProposal = false; 13697 if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) { 13698 createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance); 13699 } 13700 } 13701 reset()13702 protected void reset() { 13703 13704 super.reset(false); 13705 this.validPackageNames = new SimpleSetOfCharArray(10); 13706 this.invalidPackageNames = new SimpleSetOfCharArray(1); 13707 this.knownModules = new HashtableOfObject(10); 13708 this.knownPkgs = new HashtableOfObject(10); 13709 this.knownTypes = new HashtableOfObject(10); 13710 if (this.noCacheNameEnvironment != null) { 13711 this.noCacheNameEnvironment.cleanup(); 13712 this.noCacheNameEnvironment = null; 13713 JavaModelManager.getJavaModelManager().flushZipFiles(this); 13714 } 13715 } 13716 setSourceAndTokenRange(int start, int end)13717 private void setSourceAndTokenRange(int start, int end) { 13718 this.setSourceAndTokenRange(start, end, true); 13719 } 13720 setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment)13721 private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) { 13722 this.setSourceRange(start, end, emptyTokenAdjstment); 13723 this.setTokenRange(start, end, emptyTokenAdjstment); 13724 } 13725 setSourceRange(int start, int end)13726 private void setSourceRange(int start, int end) { 13727 this.setSourceRange(start, end, true); 13728 } 13729 setSourceRange(int start, int end, boolean emptyTokenAdjstment)13730 private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) { 13731 this.startPosition = start; 13732 if(emptyTokenAdjstment) { 13733 int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken; 13734 this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1; 13735 } else { 13736 this.endPosition = end + 1; 13737 } 13738 } 13739 setTokenRange(int start, int end)13740 private void setTokenRange(int start, int end) { 13741 this.setTokenRange(start, end, true); 13742 } setTokenRange(int start, int end, boolean emptyTokenAdjstment)13743 private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) { 13744 this.tokenStart = start; 13745 if(emptyTokenAdjstment) { 13746 int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken; 13747 this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1; 13748 } else { 13749 this.tokenEnd = end + 1; 13750 } 13751 } 13752 substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames)13753 private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) { 13754 char name = firstName; 13755 next : while (true) { 13756 for (int i = 0 ; i < excludedNames.length ; i++){ 13757 if(excludedNames[i].length == 1 && ScannerHelper.toLowerCase(excludedNames[i][0]) == ScannerHelper.toLowerCase(name)) { 13758 name++; 13759 if(name > endChar) 13760 name = startChar; 13761 if(name == firstName) 13762 return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames); 13763 continue next; 13764 } 13765 } 13766 13767 for (int i = 0; i < otherParameterNames.length; i++) { 13768 if(otherParameterNames[i].length == 1 && ScannerHelper.toLowerCase(otherParameterNames[i][0]) == ScannerHelper.toLowerCase(name)) { 13769 name++; 13770 if(name > endChar) 13771 name = startChar; 13772 if(name == firstName) 13773 return substituteMethodTypeParameterName(new char[]{firstName}, excludedNames, otherParameterNames); 13774 continue next; 13775 } 13776 } 13777 break next; 13778 } 13779 return new char[]{name}; 13780 } 13781 substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames)13782 private char[] substituteMethodTypeParameterName(char[] firstName, char[][] excludedNames, char[][] otherParameterNames) { 13783 char[] name = firstName; 13784 int count = 2; 13785 next : while(true) { 13786 for(int k = 0 ; k < excludedNames.length ; k++){ 13787 if(CharOperation.equals(name, excludedNames[k], false)) { 13788 name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray()); 13789 continue next; 13790 } 13791 } 13792 for (int i = 0; i < otherParameterNames.length; i++) { 13793 if(CharOperation.equals(name, otherParameterNames[i], false)) { 13794 name = CharOperation.concat(firstName, String.valueOf(count++).toCharArray()); 13795 continue next; 13796 } 13797 } 13798 break next; 13799 } 13800 return name; 13801 } 13802 substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames)13803 private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) { 13804 char[][] substituedParameterNames = new char[typeVariables.length][]; 13805 13806 for (int i = 0; i < substituedParameterNames.length; i++) { 13807 substituedParameterNames[i] = typeVariables[i].sourceName; 13808 } 13809 13810 boolean foundConflicts = false; 13811 13812 nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) { 13813 TypeVariableBinding typeVariableBinding = typeVariables[i]; 13814 char[] methodParameterName = typeVariableBinding.sourceName; 13815 13816 for (int j = 0; j < excludedNames.length; j++) { 13817 char[] typeParameterName = excludedNames[j]; 13818 if(CharOperation.equals(typeParameterName, methodParameterName, false)) { 13819 char[] substitution; 13820 if(methodParameterName.length == 1) { 13821 if(ScannerHelper.isUpperCase(methodParameterName[0])) { 13822 substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames); 13823 } else { 13824 substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames); 13825 } 13826 } else { 13827 substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames); 13828 } 13829 substituedParameterNames[i] = substitution; 13830 13831 foundConflicts = true; 13832 continue nextTypeParameter; 13833 } 13834 } 13835 } 13836 13837 if(foundConflicts) return substituedParameterNames; 13838 return null; 13839 } 13840 } 13841