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