View | Details | Raw Unified | Return to bug 247433 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java (+17 lines)
Lines 38-47 Link Here
38
	private boolean shortContext;
38
	private boolean shortContext;
39
	private boolean showMissingTypes;
39
	private boolean showMissingTypes;
40
	private boolean showModifiers;
40
	private boolean showModifiers;
41
	private boolean showAddionnalFlags;
41
42
42
	private boolean computeVisibleElements;
43
	private boolean computeVisibleElements;
43
	private boolean computeEnclosingElement;
44
	private boolean computeEnclosingElement;
44
	private String assignableType;
45
	private String assignableType;
46
	
47
	private boolean canceled;
45
48
46
	public boolean debug = false;
49
	public boolean debug = false;
47
50
Lines 89-94 Link Here
89
	public void acceptContext(CompletionContext cc) {
92
	public void acceptContext(CompletionContext cc) {
90
		this.context = cc;
93
		this.context = cc;
91
	}
94
	}
95
	public void aborting() {
96
		this.canceled = true;
97
	}
92
	public void accept(CompletionProposal proposal) {
98
	public void accept(CompletionProposal proposal) {
93
		int length = this.proposals.length;
99
		int length = this.proposals.length;
94
		if (++this.proposalsPtr== length) {
100
		if (++this.proposalsPtr== length) {
Lines 298-303 Link Here
298
		return strings;
304
		return strings;
299
	}
305
	}
300
306
307
	public boolean isCanceled() {
308
		return this.canceled;
309
	}
301
	protected StringBuffer printProposal(CompletionProposal proposal) {
310
	protected StringBuffer printProposal(CompletionProposal proposal) {
302
		StringBuffer buffer = new StringBuffer();
311
		StringBuffer buffer = new StringBuffer();
303
		return printProposal(proposal, 0, buffer);
312
		return printProposal(proposal, 0, buffer);
Lines 466-471 Link Here
466
				buffer.append(" deprecated"); //$NON-NLS-1$
475
				buffer.append(" deprecated"); //$NON-NLS-1$
467
			}
476
			}
468
		}
477
		}
478
		if(this.showAddionnalFlags) {
479
			int additionalFlags = proposal.getAdditionalFlags();
480
			buffer.append(", ");
481
			buffer.append(Flags.toString(additionalFlags));
482
		}
469
		buffer.append(", ");
483
		buffer.append(", ");
470
		buffer.append(proposal.getRelevance());
484
		buffer.append(proposal.getRelevance());
471
		buffer.append('}');
485
		buffer.append('}');
Lines 590-593 Link Here
590
	public void setComputeEnclosingElement(boolean computeEnclosingElement) {
604
	public void setComputeEnclosingElement(boolean computeEnclosingElement) {
591
		this.computeEnclosingElement = computeEnclosingElement;
605
		this.computeEnclosingElement = computeEnclosingElement;
592
	}
606
	}
607
	public void setShowAdditionnalFlags(boolean show) {
608
		this.showAddionnalFlags = show;
609
	}
593
}
610
}
(-)src/org/eclipse/jdt/core/tests/model/CompletionTests.java (+52 lines)
Lines 55-60 Link Here
55
	char[] varClassName = ((EvaluationContextWrapper)context).getVarClassName();
55
	char[] varClassName = ((EvaluationContextWrapper)context).getVarClassName();
56
	return Signature.createTypeSignature(varClassName, true);
56
	return Signature.createTypeSignature(varClassName, true);
57
}
57
}
58
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247433
59
public void testAbortCompletion1() throws JavaModelException {
60
	this.workingCopies = new ICompilationUnit[1];
61
	this.workingCopies[0] = getWorkingCopy(
62
		"/Completion/src/CompletionBasicType1.java",
63
		"public class CompletionBasicType1 {\n"+
64
		"	void foo() {\n"+
65
		"		Objec\n"+
66
		"	}\n"+
67
		"}\n");
68
69
	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
70
	requestor.setShowAdditionnalFlags(true);
71
	requestor.setThreshold(-1);
72
	
73
	String str = this.workingCopies[0].getSource();
74
	String completeBehind = "Objec";
75
	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
76
	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
77
	
78
	assertTrue("Completion abort", !requestor.isCanceled());
79
	assertResults(
80
		"Object[TYPE_REF]{Object, java.lang, Ljava.lang.Object;, null, , " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
81
		requestor.getResults());
82
}
83
84
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247433
85
public void testAbortCompletion2() throws JavaModelException {
86
	this.workingCopies = new ICompilationUnit[1];
87
	this.workingCopies[0] = getWorkingCopy(
88
		"/Completion/src/CompletionBasicType1.java",
89
		"public class CompletionBasicType1 {\n"+
90
		"	void foo() {\n"+
91
		"		Objec\n"+
92
		"	}\n"+
93
		"}\n");
94
95
	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
96
	requestor.setShowAdditionnalFlags(true);
97
	requestor.setThreshold(0); // force completion to abort
98
	
99
	String str = this.workingCopies[0].getSource();
100
	String completeBehind = "Objec";
101
	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
102
	this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
103
	
104
	assertTrue("Completion did not abort", requestor.isCanceled());
105
	assertResults(
106
		"",
107
		requestor.getResults());
108
}
109
58
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=164311
110
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=164311
59
public void testBug164311() throws JavaModelException {
111
public void testBug164311() throws JavaModelException {
60
	this.workingCopies = new ICompilationUnit[1];
112
	this.workingCopies = new ICompilationUnit[1];
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java (-3 / +3 lines)
Lines 1554-1562 Link Here
1554
		System.arraycopy(labels, 0, labels = new char[labelCount][], 0, labelCount);
1554
		System.arraycopy(labels, 0, labels = new char[labelCount][], 0, labelCount);
1555
1555
1556
		long position = this.identifierPositionStack[this.identifierPtr];
1556
		long position = this.identifierPositionStack[this.identifierPtr];
1557
		CompletionOnBrankStatementLabel statementLabel =
1557
		CompletionOnBranchStatementLabel statementLabel =
1558
			new CompletionOnBrankStatementLabel(
1558
			new CompletionOnBranchStatementLabel(
1559
					kind == K_INSIDE_BREAK_STATEMENT ? CompletionOnBrankStatementLabel.BREAK : CompletionOnBrankStatementLabel.CONTINUE,
1559
					kind == K_INSIDE_BREAK_STATEMENT ? CompletionOnBranchStatementLabel.BREAK : CompletionOnBranchStatementLabel.CONTINUE,
1560
					this.identifierStack[this.identifierPtr--],
1560
					this.identifierStack[this.identifierPtr--],
1561
					(int) (position >>> 32),
1561
					(int) (position >>> 32),
1562
					(int)position,
1562
					(int)position,
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBrankStatementLabel.java (-52 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.codeassist.complete;
12
13
import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
14
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
15
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
16
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
17
18
public class CompletionOnBrankStatementLabel extends BranchStatement {
19
	public static final int BREAK = 1;
20
	public static final int CONTINUE = 2;
21
22
	private int kind;
23
	public char[][] possibleLabels;
24
25
	public CompletionOnBrankStatementLabel(int kind, char[] l, int s, int e, char[][] possibleLabels) {
26
		super(l, s, e);
27
		this.kind = kind;
28
		this.possibleLabels = possibleLabels;
29
	}
30
31
	public FlowInfo analyseCode(BlockScope currentScope,
32
			FlowContext flowContext, FlowInfo flowInfo) {
33
		// Is never called
34
		return null;
35
	}
36
37
	public void resolve(BlockScope scope) {
38
		throw new CompletionNodeFound(this, scope);
39
	}
40
	public StringBuffer printStatement(int indent, StringBuffer output) {
41
		printIndent(indent, output);
42
		if(this.kind == CONTINUE) {
43
			output.append("continue "); //$NON-NLS-1$
44
		} else {
45
			output.append("break "); //$NON-NLS-1$
46
		}
47
		output.append("<CompleteOnLabel:"); //$NON-NLS-1$
48
		output.append(this.label);
49
		return output.append(">;"); //$NON-NLS-1$
50
	}
51
52
}
(-)model/org/eclipse/jdt/core/CompletionRequestor.java (+58 lines)
Lines 43-48 Link Here
43
 * <code>endReporting</code> calls are always made as well as
43
 * <code>endReporting</code> calls are always made as well as
44
 * <code>acceptContext</code> call.
44
 * <code>acceptContext</code> call.
45
 * </p>
45
 * </p>
46
 * 
47
 * Since 3.5 the completion can abort before reporting all the possible proposals. 
48
 * This event is notified by a call to {@link #aborting()}.
49
 * Proposals proposed after this notification are not guarantee to be optimum (see {@link #aborting()}).
50
 * In this case, the sequence of calls is:
51
 * <pre>
52
 * requestor.beginReporting();
53
 * requestor.acceptContext(context);
54
 * requestor.accept(proposal_1);
55
 * requestor.accept(proposal_2);
56
 * requestor.aborting();
57
 * requestor.accept(proposal_3);
58
 * requestor.endReporting();
59
 * </pre>
46
 * <p>
60
 * <p>
47
 * The class was introduced in 3.0 as a more evolvable replacement
61
 * The class was introduced in 3.0 as a more evolvable replacement
48
 * for the <code>ICompletionRequestor</code> interface.
62
 * for the <code>ICompletionRequestor</code> interface.
Lines 70-75 Link Here
70
	private int requiredProposalAllowSet[] = null;
84
	private int requiredProposalAllowSet[] = null;
71
85
72
	private boolean requireExtendedContext = false;
86
	private boolean requireExtendedContext = false;
87
	
88
	private long threshold = -1;
73
89
74
	/**
90
	/**
75
	 * Creates a new completion requestor.
91
	 * Creates a new completion requestor.
Lines 241-246 Link Here
241
	public String[] getFavoriteReferences() {
257
	public String[] getFavoriteReferences() {
242
		return this.favoriteReferences;
258
		return this.favoriteReferences;
243
	}
259
	}
260
	
261
	
262
	/**
263
	 * Returns the threshold in milliseconds beyond which the completion must abort as soon as possible.
264
	 * Returns <code>-1</code> when there is no time limit to finish the completion process.
265
	 * 
266
	 * When this threshold is reached a notification will be sent to the requestor by calling {@link #aborting()}
267
	 * 
268
	 * @since 3.5
269
	 */
270
	public long getThreshold() {
271
		return this.threshold;
272
	}
244
273
245
	/**
274
	/**
246
	 * Set the favorite references which will be used to compute some completion proposals.
275
	 * Set the favorite references which will be used to compute some completion proposals.
Lines 293-298 Link Here
293
	public void completionFailure(IProblem problem) {
322
	public void completionFailure(IProblem problem) {
294
		// default behavior is to ignore
323
		// default behavior is to ignore
295
	}
324
	}
325
	
326
	/**
327
	 * Notify that the completion will abort as soon as possible.
328
	 * <p>
329
	 * Proposals proposed after this notification are not guaranteed to be optimum:
330
	 * <ul>
331
	 * <li>Type references can be qualified even if it's not necessary.</li>
332
	 * </ul>
333
	 * The default implementation of this method does nothing.
334
	 * Clients may override.
335
	 * </p>
336
	 * 
337
	 * @since 3.5
338
	 */
339
	public void aborting() {
340
		// do nothing 
341
	}
296
342
297
	/**
343
	/**
298
	 * Proposes a completion. Has no effect if the kind of proposal
344
	 * Proposes a completion. Has no effect if the kind of proposal
Lines 355-358 Link Here
355
	public void setRequireExtendedContext(boolean require) {
401
	public void setRequireExtendedContext(boolean require) {
356
		this.requireExtendedContext = require;
402
		this.requireExtendedContext = require;
357
	}
403
	}
404
	
405
	/**
406
	 * Sets the threshold in milliseconds beyond which the completion must abort as soon as possible,
407
	 * or <code>-1</code> if there is no time limit to finish the completion process;
408
	 * 
409
	 * @param threshold the threshold in milliseconds
410
	 * 
411
	 * @since 3.5
412
	 */
413
	public void setThreshold(long threshold) {
414
		this.threshold = threshold;
415
	}
358
}
416
}
(-)model/org/eclipse/jdt/core/CompletionFlags.java (+31 lines)
Lines 31-36 Link Here
31
	 * Constant representing a static import
31
	 * Constant representing a static import
32
	 */
32
	 */
33
	public static final int StaticImport = 0x0001;
33
	public static final int StaticImport = 0x0001;
34
	
35
	/**
36
	 * Constant representing a non optimal proposal.
37
	 * eg. the proposal contains a qualified type reference which could be unqualified.
38
	 */
39
	public static final int NotOptimum = 0x0002;
34
40
35
	/**
41
	/**
36
	 * Not instantiable.
42
	 * Not instantiable.
Lines 48-51 Link Here
48
	public static boolean isStaticImport(int flags) {
54
	public static boolean isStaticImport(int flags) {
49
		return (flags & StaticImport) != 0;
55
		return (flags & StaticImport) != 0;
50
	}
56
	}
57
	
58
	/**
59
	 * Returns whether the given integer includes the {@link #NotOptimum} flag.
60
	 *
61
	 * @param flags the flags
62
	 * @return <code>true</code> if the {@link #NotOptimum} flag is included
63
	 */
64
	public static boolean isNotOptimum(int flags) {
65
		return (flags & NotOptimum) != 0;
66
	}
67
	
68
	public static String toString(int flags) {
69
		StringBuffer sb = new StringBuffer();
70
		
71
		if (isStaticImport(flags))
72
			sb.append("StaticImport "); //$NON-NLS-1$
73
		if (isNotOptimum(flags))
74
			sb.append("NotOptimum "); //$NON-NLS-1$
75
		
76
		int len = sb.length();
77
		if (len == 0)
78
			return ""; //$NON-NLS-1$
79
		sb.setLength(len - 1);
80
		return sb.toString();
81
	}
51
}
82
}
(-)codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java (-8344 / +8598 lines)
Lines 74-79 Link Here
74
	extends Engine
74
	extends Engine
75
	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
75
	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
76
76
77
	static class AbortCompletion extends RuntimeException {
78
		private static final long serialVersionUID = 1L;
79
	}
80
	
81
	private static class AcceptedType {
82
		public char[] packageName;
83
		public char[] simpleTypeName;
84
		public char[][] enclosingTypeNames;
85
		public int modifiers;
86
		public int accessibility;
87
		public boolean mustBeQualified = false;
88
89
		public char[] fullyQualifiedName = null;
90
		public char[] qualifiedTypeName = null;
91
		public AcceptedType(
92
			char[] packageName,
93
			char[] simpleTypeName,
94
			char[][] enclosingTypeNames,
95
			int modifiers,
96
			int accessibility) {
97
			this.packageName = packageName;
98
			this.simpleTypeName = simpleTypeName;
99
			this.enclosingTypeNames = enclosingTypeNames;
100
			this.modifiers = modifiers;
101
			this.accessibility = accessibility;
102
		}
103
104
		public String toString() {
105
			StringBuffer buffer = new StringBuffer();
106
			buffer.append('{');
107
			buffer.append(this.packageName);
108
			buffer.append(',');
109
			buffer.append(this.simpleTypeName);
110
			buffer.append(',');
111
			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
112
			buffer.append('}');
113
			return buffer.toString();
114
		}
115
	}
116
	
77
	public class CompletionProblemFactory extends DefaultProblemFactory {
117
	public class CompletionProblemFactory extends DefaultProblemFactory {
78
		private int lastErrorStart;
118
		private int lastErrorStart;
79
119
Lines 133-138 Link Here
133
				char[] originatingFileName,
173
				char[] originatingFileName,
134
				int problemId,
174
				int problemId,
135
				String[] problemArguments,
175
				String[] problemArguments,
176
				int elaborationId,
136
				String[] messageArguments,
177
				String[] messageArguments,
137
				int severity,
178
				int severity,
138
				int start,
179
				int start,
Lines 144-149 Link Here
144
						originatingFileName,
185
						originatingFileName,
145
						problemId,
186
						problemId,
146
						problemArguments,
187
						problemArguments,
188
						elaborationId,
147
						messageArguments,
189
						messageArguments,
148
						severity,
190
						severity,
149
						start,
191
						start,
Lines 156-162 Link Here
156
				char[] originatingFileName,
198
				char[] originatingFileName,
157
				int problemId,
199
				int problemId,
158
				String[] problemArguments,
200
				String[] problemArguments,
159
				int elaborationId,
160
				String[] messageArguments,
201
				String[] messageArguments,
161
				int severity,
202
				int severity,
162
				int start,
203
				int start,
Lines 168-174 Link Here
168
						originatingFileName,
209
						originatingFileName,
169
						problemId,
210
						problemId,
170
						problemArguments,
211
						problemArguments,
171
						elaborationId,
172
						messageArguments,
212
						messageArguments,
173
						severity,
213
						severity,
174
						start,
214
						start,
Lines 188-254 Link Here
188
		}
228
		}
189
	}
229
	}
190
230
191
	private static class AcceptedType {
231
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
192
		public AcceptedType(
232
		char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
193
			char[] packageName,
233
		for (int i = 0; i < parameterTypeSignature.length; i++) {
194
			char[] simpleTypeName,
234
			parameterTypeSignature[i] =
195
			char[][] enclosingTypeNames,
235
				Signature.createCharArrayTypeSignature(
196
			int modifiers,
236
						CharOperation.concat(
197
			int accessibility) {
237
								parameterPackageNames[i],
198
			this.packageName = packageName;
238
								CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
199
			this.simpleTypeName = simpleTypeName;
200
			this.enclosingTypeNames = enclosingTypeNames;
201
			this.modifiers = modifiers;
202
			this.accessibility = accessibility;
203
		}
239
		}
204
		public char[] packageName;
205
		public char[] simpleTypeName;
206
		public char[][] enclosingTypeNames;
207
		public int modifiers;
208
		public int accessibility;
209
240
210
		public boolean mustBeQualified = false;
241
		return Signature.createMethodSignature(
211
		public char[] fullyQualifiedName = null;
242
				parameterTypeSignature,
212
		public char[] qualifiedTypeName = null;
243
				returnTypeSignature);
244
	}
213
245
214
		public String toString() {
246
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
215
			StringBuffer buffer = new StringBuffer();
247
		char[] returnTypeSignature =
216
			buffer.append('{');
248
			returnTypeName == null || returnTypeName.length == 0
217
			buffer.append(this.packageName);
249
			? Signature.createCharArrayTypeSignature(VOID, true)
218
			buffer.append(',');
250
			: Signature.createCharArrayTypeSignature(
219
			buffer.append(this.simpleTypeName);
251
					CharOperation.concat(
220
			buffer.append(',');
252
							returnPackagename,
221
			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
253
							CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
222
			buffer.append('}');
254
223
			return buffer.toString();
255
		return createMethodSignature(
256
				parameterPackageNames,
257
				parameterTypeNames,
258
				returnTypeSignature);
259
	}
260
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
261
		return Signature.createCharArrayTypeSignature(
262
				CharOperation.concat(
263
						qualifiedPackageName,
264
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
265
	}
266
267
	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
268
		char[] name = new char[qualifiedTypeName.length];
269
		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
270
271
		int depth = 0;
272
		int length = name.length;
273
		for (int i = length -1; i >= 0; i--) {
274
			switch (name[i]) {
275
				case '.':
276
					if (depth == 0 && name[i - 1] != '>') {
277
						name[i] = '$';
278
					}
279
					break;
280
				case '<':
281
					depth--;
282
					break;
283
				case '>':
284
					depth++;
285
					break;
286
			}
224
		}
287
		}
288
		return Signature.createCharArrayTypeSignature(
289
				CharOperation.concat(
290
						qualifiedPackageName,
291
						name, '.'), true);
225
	}
292
	}
226
293
227
	public HashtableOfObject typeCache;
294
	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
295
		char[] result = null;
296
		StringBuffer sig = new StringBuffer(10);
297
298
		sig.append(typeBinding.signature());
228
299
300
		int sigLength = sig.length();
301
		result = new char[sigLength];
302
		sig.getChars(0, sigLength, result, 0);
303
		result = CharOperation.replaceOnCopy(result, '/', '.');
304
		return result;
305
	}
306
	public HashtableOfObject typeCache;
229
	public static boolean DEBUG = false;
307
	public static boolean DEBUG = false;
230
	public static boolean PERF = false;
231
308
309
	public static boolean PERF = false;
232
	// temporary constants to quickly disabled polish features if necessary
310
	// temporary constants to quickly disabled polish features if necessary
233
	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
311
	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
234
235
	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
312
	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
236
	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
313
	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
237
	private final static char[] SEMICOLON = new char[] { ';' };
314
	private final static char[] SEMICOLON = new char[] { ';' };
238
239
	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
315
	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
240
	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
316
	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
317
241
	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
318
	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
319
242
	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
320
	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
321
243
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
322
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
244
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
323
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
245
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
324
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
246
247
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
325
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
248
326
249
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
327
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
250
251
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
328
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
329
252
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
330
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
253
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
331
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
254
	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$
332
	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$
Lines 257-295 Link Here
257
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
335
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
258
	private final static char[] JAVA_LANG_NAME =
336
	private final static char[] JAVA_LANG_NAME =
259
		CharOperation.concatWith(JAVA_LANG, '.');
337
		CharOperation.concatWith(JAVA_LANG, '.');
260
261
	private final static int NONE = 0;
338
	private final static int NONE = 0;
339
262
	private final static int SUPERTYPE = 1;
340
	private final static int SUPERTYPE = 1;
263
	private final static int SUBTYPE = 2;
341
	private final static int SUBTYPE = 2;
264
265
	private final static int FIELD = 0;
342
	private final static int FIELD = 0;
266
	private final static int LOCAL = 1;
343
	private final static int LOCAL = 1;
267
	private final static int ARGUMENT = 2;
344
	private final static int ARGUMENT = 2;
268
269
	int expectedTypesPtr = -1;
345
	int expectedTypesPtr = -1;
270
	TypeBinding[] expectedTypes = new TypeBinding[1];
346
	TypeBinding[] expectedTypes = new TypeBinding[1];
271
	int expectedTypesFilter;
347
	int expectedTypesFilter;
272
	boolean hasJavaLangObjectAsExpectedType = false;
348
	boolean hasJavaLangObjectAsExpectedType = false;
349
273
	int uninterestingBindingsPtr = -1;
350
	int uninterestingBindingsPtr = -1;
351
274
	Binding[] uninterestingBindings = new Binding[1];
352
	Binding[] uninterestingBindings = new Binding[1];
275
	int forbbidenBindingsPtr = -1;
353
	int forbbidenBindingsPtr = -1;
276
	Binding[] forbbidenBindings = new Binding[1];
354
	Binding[] forbbidenBindings = new Binding[1];
277
	int forbbidenBindingsFilter;
355
	int forbbidenBindingsFilter;
278
279
	ImportBinding[] favoriteReferenceBindings;
356
	ImportBinding[] favoriteReferenceBindings;
280
281
	boolean assistNodeIsClass;
357
	boolean assistNodeIsClass;
282
	boolean assistNodeIsEnum;
358
	boolean assistNodeIsEnum;
283
	boolean assistNodeIsException;
359
	boolean assistNodeIsException;
284
	boolean assistNodeIsInterface;
360
	boolean assistNodeIsInterface;
361
285
	boolean assistNodeIsAnnotation;
362
	boolean assistNodeIsAnnotation;
363
286
	boolean assistNodeIsConstructor;
364
	boolean assistNodeIsConstructor;
287
	boolean assistNodeIsSuperType;
365
	boolean assistNodeIsSuperType;
288
	int  assistNodeInJavadoc = 0;
366
	int  assistNodeInJavadoc = 0;
289
	boolean assistNodeCanBeSingleMemberAnnotation = false;
367
	boolean assistNodeCanBeSingleMemberAnnotation = false;
290
291
	long targetedElement;
368
	long targetedElement;
292
293
	WorkingCopyOwner owner;
369
	WorkingCopyOwner owner;
294
	IJavaProject javaProject;
370
	IJavaProject javaProject;
295
	ITypeRoot typeRoot;
371
	ITypeRoot typeRoot;
Lines 307-319 Link Here
307
	CategorizedProblem problem = null;
383
	CategorizedProblem problem = null;
308
	char[] fileName = null;
384
	char[] fileName = null;
309
	int startPosition, actualCompletionPosition, endPosition, offset;
385
	int startPosition, actualCompletionPosition, endPosition, offset;
386
	
310
	int tokenStart, tokenEnd;
387
	int tokenStart, tokenEnd;
388
311
	int javadocTagPosition; // Position of previous tag while completing in javadoc
389
	int javadocTagPosition; // Position of previous tag while completing in javadoc
312
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
390
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
313
	HashtableOfObject knownTypes = new HashtableOfObject(10);
391
	HashtableOfObject knownTypes = new HashtableOfObject(10);
314
	Scanner nameScanner;
392
	Scanner nameScanner;
315
393
	
316
	/*
394
	long timeStart;
395
	boolean timeoutExceeded;
396
	
397
 	/*
317
		static final char[][] mainDeclarations =
398
		static final char[][] mainDeclarations =
318
			new char[][] {
399
			new char[][] {
319
				"package".toCharArray(),
400
				"package".toCharArray(),
Lines 349-371 Link Here
349
		TypeBinding.SHORT,
430
		TypeBinding.SHORT,
350
		TypeBinding.VOID
431
		TypeBinding.VOID
351
	};
432
	};
433
352
	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
434
	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
353
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
435
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
354
	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
436
	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
355
	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
437
	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
356
 	static {
357
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
358
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
359
 		}
360
		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
361
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
362
		}
363
 	}
364
365
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
438
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
439
366
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
440
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
441
367
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
442
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
443
368
	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
444
	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
445
369
	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$
446
	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$
370
447
371
	static InvocationSite FakeInvocationSite = new InvocationSite(){
448
	static InvocationSite FakeInvocationSite = new InvocationSite(){
Lines 375-384 Link Here
375
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
452
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
376
		public void setDepth(int depth){/* empty */}
453
		public void setDepth(int depth){/* empty */}
377
		public void setFieldIndex(int depth){/* empty */}
454
		public void setFieldIndex(int depth){/* empty */}
378
		public int sourceStart() { return 0; 	}
379
		public int sourceEnd() { return 0; 	}
455
		public int sourceEnd() { return 0; 	}
456
		public int sourceStart() { return 0; 	}
380
	};
457
	};
381
458
459
	static {
460
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
461
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
462
 		}
463
		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
464
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
465
		}
466
 	}
467
382
	private ObjectVector acceptedTypes;
468
	private ObjectVector acceptedTypes;
383
469
384
	/**
470
	/**
Lines 429-434 Link Here
429
				null/*taskPriorities*/,
515
				null/*taskPriorities*/,
430
				true/*taskCaseSensitive*/);
516
				true/*taskCaseSensitive*/);
431
		this.owner = owner;
517
		this.owner = owner;
518
		
519
		this.timeStart = System.currentTimeMillis();
520
		this.timeoutExceeded = false;
521
	}
522
523
	/**
524
	 * One result of the search consists of a new package.
525
	 *
526
	 * NOTE - All package names are presented in their readable form:
527
	 *    Package names are in the form "a.b.c".
528
	 *    The default package is represented by an empty array.
529
	 */
530
	public void acceptPackage(char[] packageName) {
531
532
		if (this.knownPkgs.containsKey(packageName)) return;
533
534
		this.knownPkgs.put(packageName, this);
535
536
		char[] completion;
537
		if(this.resolvingImports) {
538
			if(this.resolvingStaticImports) {
539
				completion = CharOperation.concat(packageName, new char[] { '.' });
540
			} else {
541
				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
542
			}
543
		} else {
544
			completion = packageName;
545
		}
546
547
		int relevance = computeBaseRelevance();
548
		relevance += computeRelevanceForResolution();
549
		relevance += computeRelevanceForInterestingProposal();
550
		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
551
		if(!this.resolvingImports) {
552
			relevance += computeRelevanceForQualification(true);
553
		}
554
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
555
556
		this.noProposal = false;
557
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
558
			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
559
			proposal.setDeclarationSignature(packageName);
560
			proposal.setPackageName(packageName);
561
			proposal.setCompletion(completion);
562
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
563
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
564
			proposal.setRelevance(relevance);
565
			this.requestor.accept(proposal);
566
			if(DEBUG) {
567
				this.printDebug(proposal);
568
			}
569
		}
432
	}
570
	}
433
571
434
	/**
572
	/**
Lines 445-450 Link Here
445
		char[][] enclosingTypeNames,
583
		char[][] enclosingTypeNames,
446
		int modifiers,
584
		int modifiers,
447
		AccessRestriction accessRestriction) {
585
		AccessRestriction accessRestriction) {
586
		
587
		checkTimeout();
448
588
449
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
589
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
450
590
Lines 489-555 Link Here
489
		if(length == 0) return;
629
		if(length == 0) return;
490
630
491
		HashtableOfObject onDemandFound = new HashtableOfObject();
631
		HashtableOfObject onDemandFound = new HashtableOfObject();
492
632
		
493
		next : for (int i = 0; i < length; i++) {
633
		try {
494
			AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
634
			next : for (int i = 0; i < length; i++) {
495
			char[] packageName = acceptedType.packageName;
635
				
496
			char[] simpleTypeName = acceptedType.simpleTypeName;
636
				checkTimeout();
497
			char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
637
				
498
			int modifiers = acceptedType.modifiers;
638
				AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
499
			int accessibility = acceptedType.accessibility;
639
				char[] packageName = acceptedType.packageName;
500
640
				char[] simpleTypeName = acceptedType.simpleTypeName;
501
			char[] typeName;
641
				char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
502
			char[] flatEnclosingTypeNames;
642
				int modifiers = acceptedType.modifiers;
503
			if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
643
				int accessibility = acceptedType.accessibility;
504
				flatEnclosingTypeNames = null;
644
	
505
				typeName = simpleTypeName;
645
				char[] typeName;
506
			} else {
646
				char[] flatEnclosingTypeNames;
507
				flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
647
				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
508
				typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
648
					flatEnclosingTypeNames = null;
509
			}
649
					typeName = simpleTypeName;
510
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
650
				} else {
511
651
					flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
512
			if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
652
					typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
513
514
			this.knownTypes.put(fullyQualifiedName, this);
515
516
			if (this.resolvingImports) {
517
				if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
518
					continue next; // import of default package is forbidden when compliance is 1.4 or higher
519
				}
653
				}
520
654
				char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
521
				char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
655
	
522
656
				if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
523
				if(this.resolvingStaticImports) {
657
	
524
					if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
658
				this.knownTypes.put(fullyQualifiedName, this);
525
						completionName = CharOperation.concat(completionName, new char[] { '.' });
659
	
526
					} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
660
				if (this.resolvingImports) {
527
						continue next;
661
					if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
662
						continue next; // import of default package is forbidden when compliance is 1.4 or higher
663
					}
664
	
665
					char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
666
	
667
					if(this.resolvingStaticImports) {
668
						if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
669
							completionName = CharOperation.concat(completionName, new char[] { '.' });
670
						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
671
							continue next;
672
						} else {
673
							completionName = CharOperation.concat(completionName, new char[] { ';' });
674
						}
528
					} else {
675
					} else {
529
						completionName = CharOperation.concat(completionName, new char[] { ';' });
676
						completionName = CharOperation.concat(completionName, new char[] { ';' });
530
					}
677
					}
678
	
679
					int relevance = computeBaseRelevance();
680
					relevance += computeRelevanceForResolution();
681
					relevance += computeRelevanceForInterestingProposal();
682
					relevance += computeRelevanceForRestrictions(accessibility);
683
					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
684
	
685
					this.noProposal = false;
686
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
687
						createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance, false);
688
					}
531
				} else {
689
				} else {
532
					completionName = CharOperation.concat(completionName, new char[] { ';' });
690
					if(!this.importCachesInitialized) {
533
				}
691
						initializeImportCaches();
534
692
					}
535
				int relevance = computeBaseRelevance();
693
	
536
				relevance += computeRelevanceForResolution();
694
					for (int j = 0; j < this.importCacheCount; j++) {
537
				relevance += computeRelevanceForInterestingProposal();
695
						char[][] importName = this.importsCache[j];
538
				relevance += computeRelevanceForRestrictions(accessibility);
696
						if(CharOperation.equals(typeName, importName[0])) {
539
				relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
697
							proposeType(
540
698
									packageName,
541
				this.noProposal = false;
699
									simpleTypeName,
542
				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
700
									modifiers,
543
					createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
701
									accessibility,
544
				}
702
									typeName,
545
			} else {
703
									fullyQualifiedName,
546
				if(!this.importCachesInitialized) {
704
									!CharOperation.equals(fullyQualifiedName, importName[1]),
547
					initializeImportCaches();
705
									false,
548
				}
706
									scope);
549
707
							continue next;
550
				for (int j = 0; j < this.importCacheCount; j++) {
708
						}
551
					char[][] importName = this.importsCache[j];
709
					}
552
					if(CharOperation.equals(typeName, importName[0])) {
710
	
711
	
712
					if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
553
						proposeType(
713
						proposeType(
554
								packageName,
714
								packageName,
555
								simpleTypeName,
715
								simpleTypeName,
Lines 557-606 Link Here
557
								accessibility,
717
								accessibility,
558
								typeName,
718
								typeName,
559
								fullyQualifiedName,
719
								fullyQualifiedName,
560
								!CharOperation.equals(fullyQualifiedName, importName[1]),
720
								false,
721
								false,
561
								scope);
722
								scope);
562
						continue next;
723
						continue next;
563
					}
724
					} else {
564
				}
725
						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
565
726
	
566
727
						AcceptedType foundType = null;
567
				if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
728
						if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
568
					proposeType(
729
							for (int j = 0; j < this.onDemandImportCacheCount; j++) {
569
							packageName,
730
								ImportBinding importBinding = this.onDemandImportsCache[j];
570
							simpleTypeName,
731
	
571
							modifiers,
732
								char[][] importName = importBinding.compoundName;
572
							accessibility,
733
								char[] importFlatName = CharOperation.concatWith(importName, '.');
573
							typeName,
734
	
574
							fullyQualifiedName,
735
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
575
							false,
736
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
576
							scope);
737
										fullyQualifiedEnclosingTypeOrPackageName =
577
					continue next;
738
											CharOperation.concat(
578
				} else {
739
													packageName,
579
					char[] fullyQualifiedEnclosingTypeOrPackageName = null;
740
													flatEnclosingTypeNames,
580
741
													'.');
581
					AcceptedType foundType = null;
742
									} else {
582
					if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
743
										fullyQualifiedEnclosingTypeOrPackageName =
583
						for (int j = 0; j < this.onDemandImportCacheCount; j++) {
744
											packageName;
584
							ImportBinding importBinding = this.onDemandImportsCache[j];
745
									}
585
586
							char[][] importName = importBinding.compoundName;
587
							char[] importFlatName = CharOperation.concatWith(importName, '.');
588
589
							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
590
								if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
591
									fullyQualifiedEnclosingTypeOrPackageName =
592
										CharOperation.concat(
593
												packageName,
594
												flatEnclosingTypeNames,
595
												'.');
596
								} else {
597
									fullyQualifiedEnclosingTypeOrPackageName =
598
										packageName;
599
								}
746
								}
600
							}
747
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
601
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
748
									if(importBinding.isStatic()) {
602
								if(importBinding.isStatic()) {
749
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
603
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
750
											acceptedType.qualifiedTypeName = typeName;
751
											acceptedType.fullyQualifiedName = fullyQualifiedName;
752
											onDemandFound.put(
753
													simpleTypeName,
754
													acceptedType);
755
											continue next;
756
										}
757
									} else {
604
										acceptedType.qualifiedTypeName = typeName;
758
										acceptedType.qualifiedTypeName = typeName;
605
										acceptedType.fullyQualifiedName = fullyQualifiedName;
759
										acceptedType.fullyQualifiedName = fullyQualifiedName;
606
										onDemandFound.put(
760
										onDemandFound.put(
Lines 608-689 Link Here
608
												acceptedType);
762
												acceptedType);
609
										continue next;
763
										continue next;
610
									}
764
									}
611
								} else {
612
									acceptedType.qualifiedTypeName = typeName;
613
									acceptedType.fullyQualifiedName = fullyQualifiedName;
614
									onDemandFound.put(
615
											simpleTypeName,
616
											acceptedType);
617
									continue next;
618
								}
765
								}
619
							}
766
							}
620
						}
767
						} else if(!foundType.mustBeQualified){
621
					} else if(!foundType.mustBeQualified){
768
							done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
622
						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
769
								ImportBinding importBinding = this.onDemandImportsCache[j];
623
							ImportBinding importBinding = this.onDemandImportsCache[j];
770
	
624
771
								char[][] importName = importBinding.compoundName;
625
							char[][] importName = importBinding.compoundName;
772
								char[] importFlatName = CharOperation.concatWith(importName, '.');
626
							char[] importFlatName = CharOperation.concatWith(importName, '.');
773
	
627
774
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
628
							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
775
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
629
								if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
776
										fullyQualifiedEnclosingTypeOrPackageName =
630
									fullyQualifiedEnclosingTypeOrPackageName =
777
											CharOperation.concat(
631
										CharOperation.concat(
778
													packageName,
632
												packageName,
779
													flatEnclosingTypeNames,
633
												flatEnclosingTypeNames,
780
													'.');
634
												'.');
781
									} else {
635
								} else {
782
										fullyQualifiedEnclosingTypeOrPackageName =
636
									fullyQualifiedEnclosingTypeOrPackageName =
783
											packageName;
637
										packageName;
784
									}
638
								}
785
								}
639
							}
786
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
640
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
787
									if(importBinding.isStatic()) {
641
								if(importBinding.isStatic()) {
788
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
642
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
789
											foundType.mustBeQualified = true;
790
											break done;
791
										}
792
									} else {
643
										foundType.mustBeQualified = true;
793
										foundType.mustBeQualified = true;
644
										break done;
794
										break done;
645
									}
795
									}
646
								} else {
647
									foundType.mustBeQualified = true;
648
									break done;
649
								}
796
								}
650
							}
797
							}
651
						}
798
						}
799
						proposeType(
800
								packageName,
801
								simpleTypeName,
802
								modifiers,
803
								accessibility,
804
								typeName,
805
								fullyQualifiedName,
806
								true,
807
								false,
808
								scope);
652
					}
809
					}
653
					proposeType(
654
							packageName,
655
							simpleTypeName,
656
							modifiers,
657
							accessibility,
658
							typeName,
659
							fullyQualifiedName,
660
							true,
661
							scope);
662
				}
810
				}
663
			}
811
			}
664
		}
812
		
665
		char[][] keys = onDemandFound.keyTable;
813
			char[][] keys = onDemandFound.keyTable;
666
		Object[] values = onDemandFound.valueTable;
814
			Object[] values = onDemandFound.valueTable;
667
		int max = keys.length;
815
			int max = keys.length;
668
		for (int i = 0; i < max; i++) {
816
			for (int i = 0; i < max; i++) {
669
			if(keys[i] != null) {
817
				if(keys[i] != null) {
670
				AcceptedType value = (AcceptedType) values[i];
818
					AcceptedType value = (AcceptedType) values[i];
671
				if(value != null) {
819
					if(value != null) {
672
					proposeType(
820
						proposeType(
673
							value.packageName,
821
								value.packageName,
674
							value.simpleTypeName,
822
								value.simpleTypeName,
675
							value.modifiers,
823
								value.modifiers,
676
							value.accessibility,
824
								value.accessibility,
677
							value.qualifiedTypeName,
825
								value.qualifiedTypeName,
678
							value.fullyQualifiedName,
826
								value.fullyQualifiedName,
679
							value.mustBeQualified,
827
								value.mustBeQualified,
680
							scope);
828
								false,
829
								scope);
830
					}
831
				}
832
			}
833
		} catch (AbortCompletion e) {
834
			char[][] keys = onDemandFound.keyTable;
835
			Object[] values = onDemandFound.valueTable;
836
			int max = keys.length;
837
			for (int i = 0; i < max; i++) {
838
				if(keys[i] != null) {
839
					AcceptedType value = (AcceptedType) values[i];
840
					if(value != null) {
841
						proposeType(
842
								value.packageName,
843
								value.simpleTypeName,
844
								value.modifiers,
845
								value.accessibility,
846
								value.qualifiedTypeName,
847
								value.fullyQualifiedName,
848
								true, // the qualification requirement is unknown then the proposal will be qualified to avoid potential compilation problem
849
								true, // qualification could be useless then the proposal is non optimal
850
								scope);
851
					}
681
				}
852
				}
682
			}
853
			}
854
			throw e;
855
		} finally {
856
			this.acceptedTypes = null; // reset
683
		}
857
		}
684
		this.acceptedTypes = null; // reset
858
		
859
		
685
	}
860
	}
686
861
	
687
	public void acceptUnresolvedName(char[] name) {
862
	public void acceptUnresolvedName(char[] name) {
688
		int relevance = computeBaseRelevance();
863
		int relevance = computeBaseRelevance();
689
		relevance += computeRelevanceForResolution(false);
864
		relevance += computeRelevanceForResolution(false);
Lines 709-714 Link Here
709
			}
884
			}
710
		}
885
		}
711
	}
886
	}
887
	private void addExpectedType(TypeBinding type, Scope scope){
888
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
889
890
		// do not add twice the same type
891
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
892
			if (this.expectedTypes[i] == type) return;
893
		}
894
895
		int length = this.expectedTypes.length;
896
		if (++this.expectedTypesPtr >= length)
897
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
898
		this.expectedTypes[this.expectedTypesPtr] = type;
899
900
		if(type == scope.getJavaLangObject()) {
901
			this.hasJavaLangObjectAsExpectedType = true;
902
		}
903
	}
904
905
	private void addForbiddenBindings(Binding binding){
906
		if (binding == null) return;
907
908
		int length = this.forbbidenBindings.length;
909
		if (++this.forbbidenBindingsPtr >= length)
910
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
911
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
912
	}
913
914
	private void addUninterestingBindings(Binding binding){
915
		if (binding == null) return;
916
917
		int length = this.uninterestingBindings.length;
918
		if (++this.uninterestingBindingsPtr >= length)
919
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
920
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
921
	}
712
922
713
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
923
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
714
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
924
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
Lines 741-933 Link Here
741
		return true;
951
		return true;
742
	}
952
	}
743
953
744
	private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope) {
954
	private void buildContext(
745
		char[] completionName = fullyQualifiedName;
955
			ASTNode astNode,
746
		if(isQualified) {
956
			ASTNode astNodeParent,
747
			if (packageName == null || packageName.length == 0)
957
			CompilationUnitDeclaration compilationUnitDeclaration,
748
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
958
			Binding qualifiedBinding,
749
					return; // ignore types from the default package from outside it
959
			Scope scope) {
750
		} else {
960
		InternalCompletionContext context = new InternalCompletionContext();
751
			completionName = simpleTypeName;
961
		if (this.requestor.isExtendedContextRequired()) {
962
			context.setExtendedData(
963
					this.typeRoot,
964
					compilationUnitDeclaration,
965
					this.lookupEnvironment,
966
					scope,
967
					astNode,
968
					this.owner,
969
					this.parser);
752
		}
970
		}
753
971
754
		TypeBinding guessedType = null;
972
		// build expected types context
755
		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
973
		if (this.expectedTypesPtr > -1) {
756
				this.assistNodeIsAnnotation &&
974
			int length = this.expectedTypesPtr + 1;
757
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
975
			char[][] expTypes = new char[length][];
758
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
976
			char[][] expKeys = new char[length][];
759
977
			for (int i = 0; i < length; i++) {
760
			TypeReference ref;
978
				expTypes[i] = getSignature(this.expectedTypes[i]);
761
			if (cn.length == 1) {
979
				expKeys[i] = this.expectedTypes[i].computeUniqueKey();
762
				ref = new SingleTypeReference(simpleTypeName, 0);
763
			} else {
764
				ref = new QualifiedTypeReference(cn,new long[cn.length]);
765
			}
766
767
			switch (scope.kind) {
768
				case Scope.METHOD_SCOPE :
769
				case Scope.BLOCK_SCOPE :
770
					guessedType = ref.resolveType((BlockScope)scope);
771
					break;
772
				case Scope.CLASS_SCOPE :
773
					guessedType = ref.resolveType((ClassScope)scope);
774
					break;
775
			}
980
			}
981
			context.setExpectedTypesSignatures(expTypes);
982
			context.setExpectedTypesKeys(expKeys);
983
		}
776
984
777
			if (guessedType == null || !guessedType.isValidBinding()) return;
985
		context.setOffset(this.actualCompletionPosition + 1 - this.offset);
778
986
779
			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
987
		// Set javadoc info
988
		if (astNode instanceof CompletionOnJavadoc) {
989
			this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
990
			context.setJavadoc(this.assistNodeInJavadoc);
780
		}
991
		}
781
992
782
		int relevance = computeBaseRelevance();
993
		if (!(astNode instanceof CompletionOnJavadoc)) {
783
		relevance += computeRelevanceForResolution();
994
			CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
784
		relevance += computeRelevanceForInterestingProposal();
995
			context.setToken(scanner.completionIdentifier);
785
		relevance += computeRelevanceForRestrictions(accessibility);
996
			context.setTokenRange(
786
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
997
					scanner.completedIdentifierStart - this.offset,
787
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
998
					scanner.completedIdentifierEnd - this.offset,
788
		relevance += computeRelevanceForQualification(isQualified);
999
					scanner.endOfEmptyToken - this.offset);
789
1000
		} else if(astNode instanceof CompletionOnJavadocTag) {
790
		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
1001
			CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
791
		switch (kind) {
1002
			context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
792
			case ClassFileConstants.AccAnnotation:
1003
			context.setTokenRange(
793
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
1004
					javadocTag.tagSourceStart - this.offset,
794
				relevance += computeRelevanceForAnnotation();
1005
					javadocTag.tagSourceEnd - this.offset,
795
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
1006
					((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
796
				relevance += computeRelevanceForInterface();
1007
		} else {
797
				break;
1008
			CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
798
			case ClassFileConstants.AccEnum:
1009
			context.setToken(scanner.completionIdentifier);
799
				relevance += computeRelevanceForEnum();
1010
			context.setTokenRange(
800
				break;
1011
					scanner.completedIdentifierStart - this.offset,
801
			case ClassFileConstants.AccInterface:
1012
					scanner.completedIdentifierEnd - this.offset,
802
				relevance += computeRelevanceForInterface();
1013
					scanner.endOfEmptyToken - this.offset);
803
				break;
804
			default:
805
				relevance += computeRelevanceForClass();
806
				relevance += computeRelevanceForException(simpleTypeName);
807
				break;
808
		}
1014
		}
809
1015
810
		this.noProposal = false;
1016
		if(astNode instanceof CompletionOnStringLiteral) {
811
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1017
			context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
812
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
1018
		} else {
813
		}
1019
			context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
814
	}
815
816
	/**
817
	 * One result of the search consists of a new package.
818
	 *
819
	 * NOTE - All package names are presented in their readable form:
820
	 *    Package names are in the form "a.b.c".
821
	 *    The default package is represented by an empty array.
822
	 */
823
	public void acceptPackage(char[] packageName) {
824
825
		if (this.knownPkgs.containsKey(packageName)) return;
826
827
		this.knownPkgs.put(packageName, this);
828
829
		char[] completion;
830
		if(this.resolvingImports) {
831
			if(this.resolvingStaticImports) {
832
				completion = CharOperation.concat(packageName, new char[] { '.' });
833
			} else {
834
				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
835
			}
836
		} else {
837
			completion = packageName;
838
		}
839
840
		int relevance = computeBaseRelevance();
841
		relevance += computeRelevanceForResolution();
842
		relevance += computeRelevanceForInterestingProposal();
843
		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
844
		if(!this.resolvingImports) {
845
			relevance += computeRelevanceForQualification(true);
846
		}
847
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
848
849
		this.noProposal = false;
850
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
851
			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
852
			proposal.setDeclarationSignature(packageName);
853
			proposal.setPackageName(packageName);
854
			proposal.setCompletion(completion);
855
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
856
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
857
			proposal.setRelevance(relevance);
858
			this.requestor.accept(proposal);
859
			if(DEBUG) {
860
				this.printDebug(proposal);
861
			}
862
		}
863
	}
864
865
	private void buildContext(
866
			ASTNode astNode,
867
			ASTNode astNodeParent,
868
			CompilationUnitDeclaration compilationUnitDeclaration,
869
			Binding qualifiedBinding,
870
			Scope scope) {
871
		InternalCompletionContext context = new InternalCompletionContext();
872
		if (this.requestor.isExtendedContextRequired()) {
873
			context.setExtendedData(
874
					this.typeRoot,
875
					compilationUnitDeclaration,
876
					this.lookupEnvironment,
877
					scope,
878
					astNode,
879
					this.owner,
880
					this.parser);
881
		}
882
883
		// build expected types context
884
		if (this.expectedTypesPtr > -1) {
885
			int length = this.expectedTypesPtr + 1;
886
			char[][] expTypes = new char[length][];
887
			char[][] expKeys = new char[length][];
888
			for (int i = 0; i < length; i++) {
889
				expTypes[i] = getSignature(this.expectedTypes[i]);
890
				expKeys[i] = this.expectedTypes[i].computeUniqueKey();
891
			}
892
			context.setExpectedTypesSignatures(expTypes);
893
			context.setExpectedTypesKeys(expKeys);
894
		}
895
896
		context.setOffset(this.actualCompletionPosition + 1 - this.offset);
897
898
		// Set javadoc info
899
		if (astNode instanceof CompletionOnJavadoc) {
900
			this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
901
			context.setJavadoc(this.assistNodeInJavadoc);
902
		}
903
904
		if (!(astNode instanceof CompletionOnJavadoc)) {
905
			CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
906
			context.setToken(scanner.completionIdentifier);
907
			context.setTokenRange(
908
					scanner.completedIdentifierStart - this.offset,
909
					scanner.completedIdentifierEnd - this.offset,
910
					scanner.endOfEmptyToken - this.offset);
911
		} else if(astNode instanceof CompletionOnJavadocTag) {
912
			CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
913
			context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
914
			context.setTokenRange(
915
					javadocTag.tagSourceStart - this.offset,
916
					javadocTag.tagSourceEnd - this.offset,
917
					((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
918
		} else {
919
			CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
920
			context.setToken(scanner.completionIdentifier);
921
			context.setTokenRange(
922
					scanner.completedIdentifierStart - this.offset,
923
					scanner.completedIdentifierEnd - this.offset,
924
					scanner.endOfEmptyToken - this.offset);
925
		}
926
927
		if(astNode instanceof CompletionOnStringLiteral) {
928
			context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
929
		} else {
930
			context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
931
		}
1020
		}
932
1021
933
		buildTokenLocationContext(context, scope, astNode, astNodeParent);
1022
		buildTokenLocationContext(context, scope, astNode, astNodeParent);
Lines 991-996 Link Here
991
		}
1080
		}
992
	}
1081
	}
993
1082
1083
	private void checkTimeout() {
1084
		if (!this.timeoutExceeded) {
1085
			long threshold = this.requestor.getThreshold();
1086
			if (threshold > -1 &&
1087
					System.currentTimeMillis() >= this.timeStart + threshold) {
1088
				this.requestor.aborting();
1089
				this.timeoutExceeded = true;
1090
				throw new AbortCompletion();
1091
			}
1092
		}
1093
	}
1094
994
	private boolean complete(
1095
	private boolean complete(
995
			ASTNode astNode,
1096
			ASTNode astNode,
996
			ASTNode astNodeParent,
1097
			ASTNode astNodeParent,
Lines 1012-1982 Link Here
1012
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1113
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1013
1114
1014
		if (astNode instanceof CompletionOnFieldType) {
1115
		if (astNode instanceof CompletionOnFieldType) {
1116
			completionOnFieldType(astNode, scope);
1117
		} else if (astNode instanceof CompletionOnMethodReturnType) {
1118
			completionOnMethodReturnType(astNode, scope);
1119
		} else if (astNode instanceof CompletionOnSingleNameReference) {
1120
			completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
1121
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1122
			completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1123
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
1124
			completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1125
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1126
			completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1127
		} else if (astNode instanceof CompletionOnMemberAccess) {
1128
			completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1129
		} else if (astNode instanceof CompletionOnMessageSend) {
1130
			completionOnMessageSend(astNode, qualifiedBinding, scope);
1131
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1132
			completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
1133
		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
1134
			completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
1135
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1136
			completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
1137
		} else if (astNode instanceof CompletionOnMethodName) {
1138
			completionOnMethodName(astNode, scope);
1139
		} else if (astNode instanceof CompletionOnFieldName) {
1140
			completionOnFieldName(astNode, scope);
1141
		} else if (astNode instanceof CompletionOnLocalName) {
1142
			completionOnLocalOrArgumentName(astNode, scope);
1143
		} else if (astNode instanceof CompletionOnArgumentName) {
1144
			completionOnLocalOrArgumentName(astNode, scope);
1145
		} else if (astNode instanceof CompletionOnKeyword) {
1146
			completionOnKeyword(astNode);
1147
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1148
			completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1149
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1150
			completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
1151
		} else if (astNode instanceof CompletionOnMemberValueName) {
1152
			completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
1153
		} else if(astNode instanceof CompletionOnBranchStatementLabel) {
1154
			completionOnBranchStatementLabel(astNode);
1155
		} else if(astNode instanceof CompletionOnMessageSendName) {
1156
			completionOnMessageSendName(astNode, qualifiedBinding, scope);
1157
		// Completion on Javadoc nodes
1158
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
1159
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
1160
				completionOnJavadocSingleTypeReference(astNode, scope);
1161
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
1162
				completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
1163
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
1164
				completionOnJavadocFieldReference(astNode, scope);
1165
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
1166
				completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
1167
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
1168
				completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
1169
			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
1170
				completionOnJavadocParamNameReference(astNode);
1171
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
1172
				completionOnJavadocTypeParamReference(astNode);
1173
			} else if (astNode instanceof CompletionOnJavadocTag) {
1174
				completionOnJavadocTag(astNode);
1175
			}
1176
		}
1177
		return true;
1178
	}
1015
1179
1016
			CompletionOnFieldType field = (CompletionOnFieldType) astNode;
1180
	/**
1017
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
1181
	 * Ask the engine to compute a completion at the specified position
1018
			this.completionToken = type.token;
1182
	 * of the given compilation unit.
1019
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1183
	 *
1184
	 *  No return
1185
	 *      completion results are answered through a requestor.
1186
	 *
1187
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
1188
	 *      the source of the current compilation unit.
1189
	 *
1190
	 *  @param completionPosition int
1191
	 *      a position in the source where the completion is taking place.
1192
	 *      This position is relative to the source provided.
1193
	 */
1194
	public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
1020
1195
1021
			findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
1196
		if(DEBUG) {
1022
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1197
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
1023
				findKeywordsForMember(this.completionToken, field.modifiers);
1198
			System.out.print(sourceUnit.getFileName());
1024
			}
1199
			System.out.print(" AT POSITION "); //$NON-NLS-1$
1200
			System.out.println(completionPosition);
1201
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
1202
			System.out.println(sourceUnit.getContents());
1203
		}
1204
		this.requestor.beginReporting();
1205
		boolean contextAccepted = false;
1206
		try {
1207
			this.fileName = sourceUnit.getFileName();
1208
			this.actualCompletionPosition = completionPosition - 1;
1209
			this.offset = pos;
1210
			this.typeRoot = root;
1211
			// for now until we can change the UI.
1212
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1213
			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
1025
1214
1026
			if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
1215
			//		boolean completionNodeFound = false;
1027
				SourceTypeBinding enclosingType = scope.enclosingSourceType();
1216
			if (parsedUnit != null) {
1028
				if (!enclosingType.isAnnotationType()) {
1217
				if(DEBUG) {
1029
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1218
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
1030
						findMethods(
1219
					System.out.println(parsedUnit.toString());
1031
								this.completionToken,
1032
								null,
1033
								null,
1034
								enclosingType,
1035
								scope,
1036
								new ObjectVector(),
1037
								false,
1038
								false,
1039
								true,
1040
								null,
1041
								null,
1042
								false,
1043
								false,
1044
								true,
1045
								null,
1046
								null,
1047
								null,
1048
								false,
1049
								null,
1050
								-1,
1051
								-1);
1052
					}
1053
					if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1054
						proposeNewMethod(this.completionToken, enclosingType);
1055
					}
1056
				}
1220
				}
1057
			}
1058
		} else if (astNode instanceof CompletionOnMethodReturnType) {
1059
1221
1060
			CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
1222
				// scan the package & import statements first
1061
			SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
1223
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
1062
			this.completionToken = type.token;
1224
					contextAccepted = true;
1063
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1225
					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
1064
			findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
1226
					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
1065
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1227
						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
1066
				findKeywordsForMember(this.completionToken, method.modifiers);
1067
			}
1068
1069
			if (method.modifiers == ClassFileConstants.AccDefault) {
1070
				SourceTypeBinding enclosingType = scope.enclosingSourceType();
1071
				if (!enclosingType.isAnnotationType()) {
1072
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1073
						findMethods(
1074
								this.completionToken,
1075
								null,null,
1076
								scope.enclosingSourceType(),
1077
								scope,
1078
								new ObjectVector(),
1079
								false,
1080
								false,
1081
								true,
1082
								null,
1083
								null,
1084
								false,
1085
								false,
1086
								true,
1087
								null,
1088
								null,
1089
								null,
1090
								false,
1091
								null,
1092
								-1,
1093
								-1);
1094
					}
1228
					}
1095
					if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1229
					if(this.noProposal && this.problem != null) {
1096
						proposeNewMethod(this.completionToken, scope.enclosingSourceType());
1230
						this.requestor.completionFailure(this.problem);
1231
						if(DEBUG) {
1232
							this.printDebug(this.problem);
1233
						}
1097
					}
1234
					}
1235
					return;
1098
				}
1236
				}
1099
			}
1100
		} else if (astNode instanceof CompletionOnSingleNameReference) {
1101
1237
1102
			CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
1238
				ImportReference[] imports = parsedUnit.imports;
1103
			this.completionToken = singleNameReference.token;
1239
				if (imports != null) {
1104
			SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
1240
					for (int i = 0, length = imports.length; i < length; i++) {
1105
			if (switchStatement != null
1241
						ImportReference importReference = imports[i];
1106
					&& switchStatement.expression.resolvedType != null
1242
						if (importReference instanceof CompletionOnImportReference) {
1107
					&& switchStatement.expression.resolvedType.isEnum()) {
1243
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1108
				if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1244
							if ((this.unitScope = parsedUnit.scope) != null) {
1109
					this.assistNodeIsEnum = true;
1245
								contextAccepted = true;
1110
					findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
1246
								buildContext(importReference, null, parsedUnit, null, null);
1111
				}
1112
			} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1113
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1114
			} else {
1115
				if (this.expectedTypesPtr > -1) {
1116
					this.assistNodeIsEnum = true;
1117
					done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1118
						if (!this.expectedTypes[i].isEnum()) {
1119
							this.assistNodeIsEnum = false;
1120
							break done;
1121
						}
1122
					}
1123
1124
				}
1125
				if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1126
					char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
1127
1128
					findUnresolvedReference(
1129
							singleNameReference.sourceStart,
1130
							singleNameReference.sourceEnd,
1131
							(BlockScope)scope,
1132
							alreadyDefinedName);
1133
				}
1134
				findVariablesAndMethods(
1135
					this.completionToken,
1136
					scope,
1137
					singleNameReference,
1138
					scope,
1139
					insideTypeAnnotation,
1140
					singleNameReference.isInsideAnnotationAttribute);
1141
				// can be the start of a qualified type name
1142
				findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
1143
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1144
					if (this.completionToken != null && this.completionToken.length != 0) {
1145
						findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
1146
					} else {
1147
						findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
1148
					}
1149
				}
1150
				if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
1151
					if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
1152
						ReferenceBinding ref = scope.enclosingSourceType();
1153
						findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
1154
					} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
1155
						ReferenceBinding ref = scope.enclosingSourceType();
1156
						findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
1157
					}
1158
				}
1159
			}
1160
1161
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1162
1163
			CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
1164
1247
1165
			this.completionToken = singleRef.token;
1248
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
1249
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
1166
1250
1167
			this.assistNodeIsClass = singleRef.isClass();
1251
								char[][] oldTokens = importReference.tokens;
1168
			this.assistNodeIsException = singleRef.isException();
1252
								int tokenCount = oldTokens.length;
1169
			this.assistNodeIsInterface = singleRef.isInterface();
1253
								if (tokenCount == 1) {
1170
			this.assistNodeIsConstructor = singleRef.isConstructorType;
1254
									findImports((CompletionOnImportReference)importReference, true);
1171
			this.assistNodeIsSuperType = singleRef.isSuperType();
1255
								} else if(tokenCount > 1){
1256
									this.insideQualifiedReference = true;
1172
1257
1173
			// can be the start of a qualified type name
1258
									char[] lastToken = oldTokens[tokenCount - 1];
1174
			if (qualifiedBinding == null) {
1259
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
1175
				if (this.completionToken.length == 0 &&
1176
						(astNodeParent instanceof ParameterizedSingleTypeReference ||
1177
								astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
1178
					this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
1179
1260
1180
					findParameterizedType((TypeReference)astNodeParent, scope);
1261
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
1181
				} else {
1262
									if(binding != null) {
1182
					ObjectVector typesFound = new ObjectVector();
1263
										if(binding instanceof PackageBinding) {
1183
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1264
											findImports((CompletionOnImportReference)importReference, false);
1184
						findExceptionFromTryStatement(
1265
										} else {
1185
								this.completionToken,
1266
											ReferenceBinding ref = (ReferenceBinding) binding;
1186
								null,
1187
								scope.enclosingSourceType(),
1188
								(BlockScope)scope,
1189
								typesFound);
1190
					}
1191
					findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
1192
				}
1193
			} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1194
				findMemberTypes(
1195
					this.completionToken,
1196
					(ReferenceBinding) qualifiedBinding,
1197
					scope,
1198
					scope.enclosingSourceType(),
1199
					false,
1200
					false,
1201
					false,
1202
					false,
1203
					!this.assistNodeIsConstructor,
1204
					null,
1205
					new ObjectVector(),
1206
					null,
1207
					null,
1208
					null,
1209
					false);
1210
			}
1211
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
1212
1267
1213
			this.insideQualifiedReference = true;
1268
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1214
			CompletionOnQualifiedNameReference ref =
1269
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
1215
				(CompletionOnQualifiedNameReference) astNode;
1270
											}
1216
			this.completionToken = ref.completionIdentifier;
1271
											if(importReference.isStatic()) {
1217
			long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
1218
1272
1219
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1273
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1220
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1274
													findImportsOfStaticFields(lastToken, ref);
1221
				// complete field members with missing fields type
1275
												}
1222
				// class X {
1276
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
1223
				//   Missing f;
1277
													findImportsOfStaticMethods(lastToken, ref);
1224
				//   void foo() {
1278
												}
1225
				//     f.|
1279
											}
1226
				//   }
1280
										}
1227
				// }
1281
									}
1228
				if (this.assistNodeInJavadoc == 0 &&
1282
								}
1229
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1230
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
1231
								this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1232
					if(ref.tokens.length == 1) {
1233
						boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
1234
1283
1235
						if (!foundSomeFields) {
1284
								if(this.noProposal && this.problem != null) {
1236
							findMembersFromMissingType(
1285
									this.requestor.completionFailure(this.problem);
1237
									ref.tokens[0],
1286
									if(DEBUG) {
1238
									ref.sourcePositions[0],
1287
										this.printDebug(this.problem);
1239
									null,
1288
									}
1240
									scope,
1289
								}
1241
									ref,
1290
							}
1242
									ref.isInsideAnnotationAttribute);
1291
							return;
1292
						} else if(importReference instanceof CompletionOnKeyword) {
1293
							contextAccepted = true;
1294
							buildContext(importReference, null, parsedUnit, null, null);
1295
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1296
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
1297
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
1298
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
1299
							}
1300
							if(this.noProposal && this.problem != null) {
1301
								this.requestor.completionFailure(this.problem);
1302
								if(DEBUG) {
1303
									this.printDebug(this.problem);
1304
								}
1305
							}
1306
							return;
1243
						}
1307
						}
1244
					}
1308
					}
1245
				}
1309
				}
1246
			} else if (qualifiedBinding instanceof VariableBinding) {
1247
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1248
				TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
1249
				if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
1250
					ObjectVector fieldsFound = new ObjectVector();
1251
					ObjectVector methodsFound = new ObjectVector();
1252
1253
					findFieldsAndMethods(
1254
							this.completionToken,
1255
							receiverType.capture(scope, ref.sourceEnd),
1256
							scope,
1257
							fieldsFound,
1258
							methodsFound,
1259
							ref,
1260
							scope,
1261
							false,
1262
							false,
1263
							null,
1264
							null,
1265
							null,
1266
							false,
1267
							null,
1268
							-1,
1269
							-1);
1270
1310
1271
					findFieldsAndMethodsFromCastedReceiver(
1311
				if (parsedUnit.types != null) {
1272
							enclosingNode,
1312
					try {
1273
							qualifiedBinding,
1313
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1274
							scope,
1275
							fieldsFound,
1276
							methodsFound,
1277
							ref,
1278
							scope,
1279
							ref);
1280
1314
1281
				} else if (this.assistNodeInJavadoc == 0 &&
1315
						if ((this.unitScope = parsedUnit.scope) != null) {
1282
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1316
							this.source = sourceUnit.getContents();
1283
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1317
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
1284
					boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
1318
							parsedUnit.scope.faultInTypes();
1285
					boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
1319
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
1286
					if (proposeField || proposeMethod) {
1320
							if(DEBUG) {
1287
						if(ref.tokens.length == 1) {
1321
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
1288
							if (qualifiedBinding instanceof LocalVariableBinding) {
1322
								System.out.println(parsedUnit.toString());
1289
								// complete local variable members with missing variables type
1290
								// class X {
1291
								//   void foo() {
1292
								//     Missing f;
1293
								//     f.|
1294
								//   }
1295
								// }
1296
								LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
1297
								findFieldsAndMethodsFromMissingType(
1298
										localVariableBinding.declaration.type,
1299
										localVariableBinding.declaringScope,
1300
										ref,
1301
										scope);
1302
							} else {
1303
								// complete field members with missing fields type
1304
								// class X {
1305
								//   Missing f;
1306
								//   void foo() {
1307
								//     f.|
1308
								//   }
1309
								// }
1310
								findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
1311
							}
1323
							}
1312
1324
							parsedUnit.resolve();
1325
						}
1326
					} catch (CompletionNodeFound e) {
1327
						//					completionNodeFound = true;
1328
						if (e.astNode != null) {
1329
							// if null then we found a problem in the completion node
1330
							if(DEBUG) {
1331
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
1332
								System.out.println(e.astNode.toString());
1333
								if(this.parser.assistNodeParent != null) {
1334
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
1335
									System.out.println(this.parser.assistNodeParent);
1336
								}
1337
							}
1338
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
1339
							contextAccepted =
1340
								complete(
1341
									e.astNode,
1342
									this.parser.assistNodeParent,
1343
									this.parser.enclosingNode,
1344
									parsedUnit,
1345
									e.qualifiedBinding,
1346
									e.scope,
1347
									e.insideTypeAnnotation);
1313
						}
1348
						}
1314
					}
1349
					}
1315
				}
1350
				}
1316
1317
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1318
				boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
1319
				ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
1320
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1321
1322
				findMembers(
1323
						this.completionToken,
1324
						receiverType,
1325
						scope,
1326
						ref,
1327
						isInsideAnnotationAttribute,
1328
						null,
1329
						null,
1330
						null,
1331
						false);
1332
1333
			} else if (qualifiedBinding instanceof PackageBinding) {
1334
1335
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1336
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1337
1338
				// replace to the end of the completion identifier
1339
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1340
			}
1351
			}
1341
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1342
1343
			this.insideQualifiedReference = true;
1344
1345
			CompletionOnQualifiedTypeReference ref =
1346
				(CompletionOnQualifiedTypeReference) astNode;
1347
1348
			this.assistNodeIsClass = ref.isClass();
1349
			this.assistNodeIsException = ref.isException();
1350
			this.assistNodeIsInterface = ref.isInterface();
1351
			this.assistNodeIsSuperType = ref.isSuperType();
1352
1353
			this.completionToken = ref.completionIdentifier;
1354
			long completionPosition = ref.sourcePositions[ref.tokens.length];
1355
1352
1356
			// get the source positions of the completion identifier
1353
			if(this.noProposal && this.problem != null) {
1357
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1354
				if(!contextAccepted) {
1358
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1355
					contextAccepted = true;
1359
				if (this.assistNodeInJavadoc == 0 &&
1356
					InternalCompletionContext context = new InternalCompletionContext();
1360
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1357
					context.setOffset(completionPosition - this.offset);
1361
					if(ref.tokens.length == 1) {
1358
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1362
						findMemberTypesFromMissingType(
1359
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
1363
								ref.tokens[0],
1360
					this.requestor.acceptContext(context);
1364
								ref.sourcePositions[0],
1365
								scope);
1366
					}
1367
				}
1361
				}
1368
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1362
				this.requestor.completionFailure(this.problem);
1369
				if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1363
				if(DEBUG) {
1370
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1364
					this.printDebug(this.problem);
1371
1372
					ObjectVector typesFound = new ObjectVector();
1373
1374
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1375
						findExceptionFromTryStatement(
1376
								this.completionToken,
1377
								(ReferenceBinding)qualifiedBinding,
1378
								scope.enclosingSourceType(),
1379
								(BlockScope)scope,
1380
								typesFound);
1381
					}
1382
1383
					findMemberTypes(
1384
						this.completionToken,
1385
						(ReferenceBinding) qualifiedBinding,
1386
						scope,
1387
						scope.enclosingSourceType(),
1388
						false,
1389
						false,
1390
						typesFound,
1391
						null,
1392
						null,
1393
						null,
1394
						false);
1395
				}
1365
				}
1396
			} else if (qualifiedBinding instanceof PackageBinding) {
1397
1398
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1399
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1400
				// replace to the end of the completion identifier
1401
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1402
			}
1366
			}
1403
		} else if (astNode instanceof CompletionOnMemberAccess) {
1367
			/* Ignore package, import, class & interface keywords for now...
1404
			this.insideQualifiedReference = true;
1368
					if (!completionNodeFound) {
1405
			CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1369
						if (parsedUnit == null || parsedUnit.types == null) {
1406
			long completionPosition = access.nameSourcePosition;
1370
							// this is not good enough... can still be trying to define a second type
1407
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1371
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
1408
1372
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
1409
			this.completionToken = access.token;
1373
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
1410
1374
						}
1411
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1375
						// currently have no way to know if extends/implements are possible keywords
1412
				// complete method members with missing return type
1413
				// class X {
1414
				//   Missing f() {return null;}
1415
				//   void foo() {
1416
				//     f().|
1417
				//   }
1418
				// }
1419
				if (this.assistNodeInJavadoc == 0 &&
1420
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1421
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1422
					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1423
					findFieldsAndMethodsFromMissingReturnType(
1424
							problemMethodBinding.selector,
1425
							problemMethodBinding.parameters,
1426
							scope,
1427
							access,
1428
							insideTypeAnnotation);
1429
				}
1430
			} else {
1431
				if (!access.isInsideAnnotation) {
1432
					if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1433
						findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
1434
					}
1435
1436
					ObjectVector fieldsFound = new ObjectVector();
1437
					ObjectVector methodsFound = new ObjectVector();
1438
1439
					boolean superCall = access.receiver instanceof SuperReference;
1440
1441
					findFieldsAndMethods(
1442
						this.completionToken,
1443
						((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
1444
						scope,
1445
						fieldsFound,
1446
						methodsFound,
1447
						access,
1448
						scope,
1449
						false,
1450
						superCall,
1451
						null,
1452
						null,
1453
						null,
1454
						false,
1455
						null,
1456
						-1,
1457
						-1);
1458
1459
					if (!superCall) {
1460
						findFieldsAndMethodsFromCastedReceiver(
1461
								enclosingNode,
1462
								qualifiedBinding,
1463
								scope,
1464
								fieldsFound,
1465
								methodsFound,
1466
								access,
1467
								scope,
1468
								access.receiver);
1469
					}
1376
					}
1470
				}
1377
			*/
1378
		} catch (AbortCompletion e) {
1379
			if(!contextAccepted) {
1380
				contextAccepted = true;
1381
				InternalCompletionContext context = new InternalCompletionContext();
1382
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1383
				context.setOffset(completionPosition - this.offset);
1384
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
1385
				this.requestor.acceptContext(context);
1471
			}
1386
			}
1472
1387
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
1473
		} else if (astNode instanceof CompletionOnMessageSend) {
1388
			if(DEBUG) {
1474
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1389
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1475
1390
				e.printStackTrace(System.out);
1476
			CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1477
			TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1478
			this.completionToken = messageSend.selector;
1479
			if (qualifiedBinding == null) {
1480
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1481
					ObjectVector methodsFound = new ObjectVector();
1482
1483
					findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
1484
1485
					findLocalMethodsFromStaticImports(
1486
							this.completionToken,
1487
							scope,
1488
							messageSend,
1489
							scope,
1490
							true,
1491
							methodsFound,
1492
							true);
1493
				}
1494
			} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1495
				findMethods(
1496
					this.completionToken,
1497
					null,
1498
					argTypes,
1499
					(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1500
					scope,
1501
					new ObjectVector(),
1502
					false,
1503
					true,
1504
					false,
1505
					messageSend,
1506
					scope,
1507
					false,
1508
					messageSend.receiver instanceof SuperReference,
1509
					false,
1510
					null,
1511
					null,
1512
					null,
1513
					false,
1514
					null,
1515
					-1,
1516
					-1);
1517
			}
1391
			}
1518
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1392
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
1519
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1393
			if(DEBUG) {
1520
				setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1394
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1521
1395
				e.printStackTrace(System.out);
1522
				CompletionOnExplicitConstructorCall constructorCall =
1523
					(CompletionOnExplicitConstructorCall) astNode;
1524
				TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1525
				findConstructors(
1526
					(ReferenceBinding) qualifiedBinding,
1527
					argTypes,
1528
					scope,
1529
					constructorCall,
1530
					false);
1531
									}
1532
		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
1533
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1534
1535
			CompletionOnQualifiedAllocationExpression allocExpression =
1536
				(CompletionOnQualifiedAllocationExpression) astNode;
1537
			TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1538
1539
			ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1540
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1541
					&& ref.isClass()
1542
					&& !ref.isAbstract()) {
1543
					findConstructors(
1544
						ref,
1545
						argTypes,
1546
						scope,
1547
						allocExpression,
1548
						false);
1549
			}
1396
			}
1550
			if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
1397
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
1551
					&& !ref.isFinal()
1398
			if(DEBUG) {
1552
					&& !ref.isEnum()){
1399
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1553
				findAnonymousType(
1400
				e.printStackTrace(System.out);
1554
					ref,
1555
					argTypes,
1556
					scope,
1557
					allocExpression);
1558
			}
1401
			}
1559
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1402
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
1560
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1403
			if(DEBUG) {
1561
				CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1404
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1562
				setSourceAndTokenRange(access.classStart, access.sourceEnd);
1405
				e.printStackTrace(System.out);
1563
1564
				this.completionToken = access.completionIdentifier;
1565
1566
				findClassField(
1567
						this.completionToken,
1568
						(TypeBinding) qualifiedBinding,
1569
						scope,
1570
						null,
1571
						null,
1572
						null,
1573
						false);
1574
			}
1406
			}
1575
		} else if (astNode instanceof CompletionOnMethodName) {
1407
		} finally {
1576
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1408
			if(!contextAccepted) {
1577
				CompletionOnMethodName method = (CompletionOnMethodName) astNode;
1409
				contextAccepted = true;
1410
				InternalCompletionContext context = new InternalCompletionContext();
1411
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1412
				context.setOffset(completionPosition - this.offset);
1413
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
1414
				this.requestor.acceptContext(context);
1415
			}
1416
			this.requestor.endReporting();
1417
			reset();
1418
		}
1419
	}
1578
1420
1579
				setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
1421
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
1422
		if(this.requestor != null){
1423
			this.requestor.beginReporting();
1424
		}
1425
		boolean contextAccepted = false;
1426
		IType topLevelType = type;
1427
		while(topLevelType.getDeclaringType() != null) {
1428
			topLevelType = topLevelType.getDeclaringType();
1429
		}
1580
1430
1581
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1431
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
1582
				char[][] excludeNames = new char[fields.length][];
1432
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1583
				for(int i = 0 ; i < fields.length ; i++){
1584
					excludeNames[i] = fields[i].name;
1585
				}
1586
1433
1587
				this.completionToken = method.selector;
1434
		CompilationUnitDeclaration compilationUnit = null;
1588
1435
1589
				findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
1436
		try {
1437
			// TypeConverter is used instead of SourceTypeConverter because the type
1438
			// to convert can be a binary type or a source type
1439
			TypeDeclaration typeDeclaration = null;
1440
			if (type instanceof SourceType) {
1441
				SourceType sourceType = (SourceType) type;
1442
				ISourceType info = (ISourceType) sourceType.getElementInfo();
1443
				compilationUnit = SourceTypeConverter.buildCompilationUnit(
1444
					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
1445
					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
1446
					| SourceTypeConverter.MEMBER_TYPE, // need member types
1447
					// no need for field initialization
1448
					this.problemReporter,
1449
					compilationResult);
1450
				if (compilationUnit.types != null)
1451
					typeDeclaration = compilationUnit.types[0];
1452
			} else {
1453
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
1454
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
1590
			}
1455
			}
1591
		} else if (astNode instanceof CompletionOnFieldName) {
1592
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1593
				CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1594
1595
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1596
				char[][] excludeNames = new char[fields.length][];
1597
				for(int i = 0 ; i < fields.length ; i++){
1598
					excludeNames[i] = fields[i].name;
1599
				}
1600
1601
				this.completionToken = field.realName;
1602
1456
1603
				findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1457
			if(typeDeclaration != null) {
1604
			}
1458
				// build AST from snippet
1605
		} else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) {
1459
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
1606
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1607
				LocalDeclaration variable = (LocalDeclaration) astNode;
1608
1460
1609
				int kind;
1461
				// merge AST
1610
				if (variable instanceof CompletionOnLocalName){
1462
				FieldDeclaration[] oldFields = typeDeclaration.fields;
1611
					this.completionToken = ((CompletionOnLocalName) variable).realName;
1463
				FieldDeclaration[] newFields = null;
1612
					kind = LOCAL;
1464
				if (oldFields != null) {
1465
					newFields = new FieldDeclaration[oldFields.length + 1];
1466
					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
1467
					newFields[oldFields.length] = fakeInitializer;
1613
				} else {
1468
				} else {
1614
					CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1469
					newFields = new FieldDeclaration[] {fakeInitializer};
1615
					this.completionToken = arg.realName;
1616
					kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1617
				}
1470
				}
1471
				typeDeclaration.fields = newFields;
1618
1472
1619
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1473
				if(DEBUG) {
1620
1474
					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
1621
				char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1475
					System.out.println(compilationUnit.toString());
1622
1623
				LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1624
				char[][] discouragedNames = new char[locals.length][];
1625
				int localCount = 0;
1626
				for(int i = 0 ; i < locals.length ; i++){
1627
					if (locals[i] != null) {
1628
						discouragedNames[localCount++] = locals[i].name;
1629
					}
1630
				}
1476
				}
1631
1477
1632
				System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1478
				if (compilationUnit.types != null) {
1633
1479
					try {
1634
				findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1480
						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
1635
			}
1636
		} else if (astNode instanceof CompletionOnKeyword) {
1637
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1638
				CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1639
				findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1640
			}
1641
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1642
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1643
				CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
1644
1645
				this.insideQualifiedReference = true;
1646
1647
				this.assistNodeIsClass = ref.isClass();
1648
				this.assistNodeIsException = ref.isException();
1649
				this.assistNodeIsInterface = ref.isInterface();
1650
				this.assistNodeIsSuperType = ref.isSuperType();
1651
1652
				this.completionToken = ref.completionIdentifier;
1653
				long completionPosition = ref.sourcePositions[ref.tokens.length];
1654
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1655
1481
1656
				if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
1482
						if ((this.unitScope = compilationUnit.scope) != null) {
1657
						(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
1483
							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
1658
					if (this.assistNodeInJavadoc == 0 &&
1484
							compilationUnit.scope.faultInTypes();
1659
							(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1485
							compilationUnit.resolve();
1660
						if(ref.tokens.length == 1) {
1486
						}
1661
							findMemberTypesFromMissingType(
1487
					} catch (CompletionNodeFound e) {
1662
									ref,
1488
						//					completionNodeFound = true;
1663
									ref.sourcePositions[0],
1489
						if (e.astNode != null) {
1664
									scope);
1490
							// if null then we found a problem in the completion node
1491
							contextAccepted =
1492
								complete(
1493
									e.astNode,
1494
									this.parser.assistNodeParent,
1495
									this.parser.enclosingNode,
1496
									compilationUnit,
1497
									e.qualifiedBinding,
1498
									e.scope,
1499
									e.insideTypeAnnotation);
1665
						}
1500
						}
1666
					}
1501
					}
1667
				} else {
1502
				}
1668
					ObjectVector typesFound = new ObjectVector();
1503
				if(this.noProposal && this.problem != null) {
1669
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1504
					if(!contextAccepted) {
1670
						findExceptionFromTryStatement(
1505
						contextAccepted = true;
1671
								this.completionToken,
1506
						InternalCompletionContext context = new InternalCompletionContext();
1672
								(ReferenceBinding)qualifiedBinding,
1507
						if (this.requestor.isExtendedContextRequired()) context.setExtended();
1673
								scope.enclosingSourceType(),
1508
						this.requestor.acceptContext(context);
1674
								(BlockScope)scope,
1509
					}
1675
								typesFound);
1510
					this.requestor.completionFailure(this.problem);
1511
					if(DEBUG) {
1512
						this.printDebug(this.problem);
1676
					}
1513
					}
1677
1678
					findMemberTypes(
1679
						this.completionToken,
1680
						(ReferenceBinding) qualifiedBinding,
1681
						scope,
1682
						scope.enclosingSourceType(),
1683
						false,
1684
						false,
1685
						typesFound,
1686
						null,
1687
						null,
1688
						null,
1689
						false);
1690
				}
1514
				}
1691
			}
1515
			}
1692
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1516
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
1693
			CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1517
			if(DEBUG) {
1694
1518
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1695
			CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1519
				e.printStackTrace(System.out);
1696
			if (fakeType.annotations[0] == annot) {
1697
				// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1698
				// So 'targetedElement' is not computed in this case.
1699
				if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1700
					this.targetedElement = computeTargetedElement(fakeType);
1701
				}
1702
1703
			}
1520
			}
1521
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
1522
			if(DEBUG) {
1523
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1524
				e.printStackTrace(System.out);
1525
			}
1526
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
1527
			if(DEBUG) {
1528
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1529
				e.printStackTrace(System.out);
1530
			}
1531
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
1532
			if(DEBUG) {
1533
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1534
				e.printStackTrace(System.out);
1535
			}
1536
		} catch(JavaModelException e) {
1537
			// Do nothing
1538
		}
1539
		if(!contextAccepted) {
1540
			contextAccepted = true;
1541
			InternalCompletionContext context = new InternalCompletionContext();
1542
			if (this.requestor.isExtendedContextRequired()) context.setExtended();
1543
			this.requestor.acceptContext(context);
1544
		}
1545
		if(this.requestor != null){
1546
			this.requestor.endReporting();
1547
		}
1548
	}
1549
	
1550
	private void completionOnBranchStatementLabel(ASTNode astNode) {
1551
		if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1552
			CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
1553
			this.completionToken = label.label;
1554
			findLabels(this.completionToken, label.possibleLabels);
1555
		}
1556
	}
1557
	
1558
	private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1559
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1560
			CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1561
			setSourceAndTokenRange(access.classStart, access.sourceEnd);
1562
			this.completionToken = access.completionIdentifier;
1563
			findClassField(
1564
					this.completionToken,
1565
					(TypeBinding) qualifiedBinding,
1566
					scope,
1567
					null,
1568
					null,
1569
					null,
1570
					false);
1571
		}
1572
	}
1573
	
1574
	private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1575
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1576
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1577
			CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
1578
			TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1579
			findConstructors(
1580
				(ReferenceBinding) qualifiedBinding,
1581
				argTypes,
1582
				scope,
1583
				constructorCall,
1584
				false);
1585
		}
1586
	}
1587
	
1588
	private void completionOnFieldName(ASTNode astNode, Scope scope) {
1589
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1590
			CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1704
1591
1705
			this.assistNodeIsAnnotation = true;
1592
			FieldBinding[] fields = scope.enclosingSourceType().fields();
1706
			if (annot.type instanceof CompletionOnSingleTypeReference) {
1593
			char[][] excludeNames = new char[fields.length][];
1707
				CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1594
			for(int i = 0 ; i < fields.length ; i++){
1708
				this.completionToken = type.token;
1595
				excludeNames[i] = fields[i].name;
1709
				setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1596
			}
1710
1711
				if (scope.parent.parent != null &&
1712
						!(scope.parent.parent instanceof MethodScope) &&
1713
						!fakeType.isParameter) {
1714
1715
					if (this.completionToken.length <= Keywords.INTERFACE.length
1716
						&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
1717
					)){
1718
						int relevance = computeBaseRelevance();
1719
						relevance += computeRelevanceForResolution();
1720
						relevance += computeRelevanceForInterestingProposal();
1721
						relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
1722
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1723
						relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
1724
1725
						this.noProposal = false;
1726
						if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1727
							CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1728
							proposal.setName(Keywords.INTERFACE);
1729
							proposal.setCompletion(Keywords.INTERFACE);
1730
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1731
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
1732
							proposal.setRelevance(relevance);
1733
							this.requestor.accept(proposal);
1734
							if(DEBUG) {
1735
								this.printDebug(proposal);
1736
							}
1737
						}
1738
					}
1739
				}
1740
1597
1741
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1598
			this.completionToken = field.realName;
1742
			} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1743
				this.insideQualifiedReference = true;
1744
1745
				CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1746
				this.completionToken = type.completionIdentifier;
1747
				long completionPosition = type.sourcePositions[type.tokens.length];
1748
				if (qualifiedBinding instanceof PackageBinding) {
1749
1750
					setSourceRange(astNode.sourceStart, (int) completionPosition);
1751
					setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1752
					// replace to the end of the completion identifier
1753
					findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1754
				} else {
1755
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1756
1599
1757
					findMemberTypes(
1600
			findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1758
						this.completionToken,
1601
		}
1759
						(ReferenceBinding) qualifiedBinding,
1602
	}
1760
						scope,
1603
	
1761
						scope.enclosingSourceType(),
1604
	private void completionOnFieldType(ASTNode astNode, Scope scope) {
1762
						false,
1605
		CompletionOnFieldType field = (CompletionOnFieldType) astNode;
1763
						false,
1606
		CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
1764
						new ObjectVector(),
1607
		this.completionToken = type.token;
1765
						null,
1608
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1766
						null,
1609
1767
						null,
1610
		findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
1768
						false);
1611
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1612
			findKeywordsForMember(this.completionToken, field.modifiers);
1613
		}
1614
1615
		if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
1616
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
1617
			if (!enclosingType.isAnnotationType()) {
1618
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1619
					findMethodDeclarations(
1620
							this.completionToken,
1621
							enclosingType,
1622
							scope,
1623
							new ObjectVector(),
1624
							null,
1625
							null,
1626
							null,
1627
							false);
1628
				}
1629
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1630
					proposeNewMethod(this.completionToken, enclosingType);
1769
				}
1631
				}
1770
			}
1632
			}
1771
		} else if (astNode instanceof CompletionOnMemberValueName) {
1633
		}
1772
			CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
1634
	}
1773
			Annotation annotation = (Annotation) astNodeParent;
1635
	//TODO
1774
1636
	private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1775
			this.completionToken = memberValuePair.name;
1637
		// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1638
		
1639
		CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
1640
		this.javadocTagPosition = allocExpression.tagSourceStart;
1641
		int rangeStart = astNode.sourceStart;
1642
		if (allocExpression.type.isThis()) {
1643
			if (allocExpression.completeInText()) {
1644
				rangeStart = allocExpression.separatorPosition;
1645
			}
1646
		} else if (allocExpression.completeInText()) {
1647
			rangeStart = allocExpression.type.sourceStart;
1648
		}
1649
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1650
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1776
1651
1777
			ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
1652
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1653
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
1654
			findConstructors(ref, argTypes, scope, allocExpression, false);
1655
		}
1656
	}
1657
	//TODO
1658
	private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
1659
		this.insideQualifiedReference = true;
1660
		CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1661
		this.completionToken = fieldRef.token;
1662
		long completionPosition = fieldRef.nameSourcePosition;
1663
		this.javadocTagPosition = fieldRef.tagSourceStart;
1778
1664
1779
			if (annotationType != null && annotationType.isAnnotationType()) {
1665
		if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1780
				if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
1666
				ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1781
					findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
1667
			int rangeStart = (int) (completionPosition >>> 32);
1668
			if (fieldRef.receiver.isThis()) {
1669
				if (fieldRef.completeInText()) {
1670
					rangeStart = fieldRef.separatorPosition;
1782
				}
1671
				}
1783
				if (this.assistNodeCanBeSingleMemberAnnotation) {
1672
			} else if (fieldRef.completeInText()) {
1784
					if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1673
				rangeStart = fieldRef.receiver.sourceStart;
1785
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1674
			}
1786
					} else {
1675
			setSourceAndTokenRange(rangeStart, (int) completionPosition);
1787
						if (this.expectedTypesPtr > -1) {
1788
							this.assistNodeIsEnum = true;
1789
							done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1790
								if (!this.expectedTypes[i].isEnum()) {
1791
									this.assistNodeIsEnum = false;
1792
									break done;
1793
								}
1794
							}
1795
1676
1796
						}
1677
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1797
						if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1678
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1798
							char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
1679
				findFields(this.completionToken,
1680
					receiverType,
1681
					scope,
1682
					new ObjectVector(),
1683
					new ObjectVector(),
1684
					false, /*not only static */
1685
					fieldRef,
1686
					scope,
1687
					false,
1688
					true,
1689
					null,
1690
					null,
1691
					null,
1692
					false,
1693
					null,
1694
					-1,
1695
					-1);
1696
			}
1799
1697
1800
							findUnresolvedReference(
1698
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1801
									memberValuePair.sourceStart,
1699
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
1802
									memberValuePair.sourceEnd,
1700
				findMethods(
1803
									(BlockScope)scope,
1701
					this.completionToken,
1804
									alreadyDefinedName);
1702
					null,
1805
						}
1703
					null,
1806
						findVariablesAndMethods(
1704
					receiverType,
1807
							this.completionToken,
1705
					scope,
1808
							scope,
1706
					new ObjectVector(),
1809
							FakeInvocationSite,
1707
					false, /*not only static */
1810
							scope,
1708
					false,
1811
							insideTypeAnnotation,
1709
					fieldRef,
1812
							true);
1710
					scope,
1813
						// can be the start of a qualified type name
1711
					false,
1814
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1712
					false,
1713
					true,
1714
					null,
1715
					null,
1716
					null,
1717
					false,
1718
					null,
1719
					-1,
1720
					-1);
1721
				if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
1722
					ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
1723
					if (this.completionToken == null
1724
							|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1725
							|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1726
						findConstructors(refBinding, null, scope, fieldRef, false);
1815
					}
1727
					}
1816
				}
1728
				}
1817
			}
1729
			}
1818
		} else if(astNode instanceof CompletionOnBrankStatementLabel) {
1730
		}
1819
			if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1731
	}
1820
				CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode;
1732
	//TODO
1821
1733
	private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1822
				this.completionToken = label.label;
1734
		CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
1735
		TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
1736
		this.completionToken = messageSend.selector;
1737
		this.javadocTagPosition = messageSend.tagSourceStart;
1823
1738
1824
				findLabels(this.completionToken, label.possibleLabels);
1739
		// Set source range
1740
		int rangeStart = astNode.sourceStart;
1741
		if (messageSend.receiver.isThis()) {
1742
			if (messageSend.completeInText()) {
1743
				rangeStart = messageSend.separatorPosition;
1825
			}
1744
			}
1826
		} else if(astNode instanceof CompletionOnMessageSendName) {
1745
		} else if (messageSend.completeInText()) {
1746
			rangeStart = messageSend.receiver.sourceStart;
1747
		}
1748
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1749
1750
		if (qualifiedBinding == null) {
1827
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1751
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1828
				CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
1752
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
1753
			}
1754
		} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1755
			findMethods(
1756
				this.completionToken,
1757
				null,
1758
				argTypes,
1759
				(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1760
				scope,
1761
				new ObjectVector(),
1762
				false,
1763
				false/* prefix match */,
1764
				messageSend,
1765
				scope,
1766
				false,
1767
				messageSend.receiver instanceof SuperReference,
1768
				true,
1769
				null,
1770
				null,
1771
				null,
1772
				false,
1773
				null,
1774
				-1,
1775
				-1);
1776
		}
1777
	}
1778
	//TODO
1779
	private void completionOnJavadocParamNameReference(ASTNode astNode) {
1780
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1781
			CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
1782
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1783
			findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
1784
			findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
1785
		}
1786
	}
1787
	//TODO
1788
	private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1789
		this.insideQualifiedReference = true;
1790
1791
		CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
1792
		this.completionToken = typeRef.completionIdentifier;
1793
		long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
1794
		this.javadocTagPosition = typeRef.tagSourceStart;
1795
1796
		// get the source positions of the completion identifier
1797
		if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1798
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
1799
					((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
1800
				int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1801
				setSourceAndTokenRange(rangeStart, (int) completionPosition);
1802
				findMemberTypes(
1803
					this.completionToken,
1804
					(ReferenceBinding) qualifiedBinding,
1805
					scope,
1806
					scope.enclosingSourceType(),
1807
					false,
1808
					false,
1809
					new ObjectVector(),
1810
					null,
1811
					null,
1812
					null,
1813
					false);
1814
			}
1815
		} else if (qualifiedBinding instanceof PackageBinding) {
1829
1816
1830
				this.insideQualifiedReference = true;
1817
			setSourceRange(astNode.sourceStart, (int) completionPosition);
1831
				this.completionToken = messageSend.selector;
1818
			int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1832
				boolean onlyStatic = false;
1819
			setTokenRange(rangeStart, (int) completionPosition);
1833
				if (messageSend.receiver instanceof NameReference) {
1820
			// replace to the end of the completion identifier
1834
					onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
1821
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1835
				} else if (!(messageSend.receiver instanceof MessageSend) &&
1822
		}
1836
						!(messageSend.receiver instanceof FieldReference) &&
1823
	}
1837
						!(messageSend.receiver.isThis())) {
1824
	//TODO
1838
					onlyStatic = true;
1825
	private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
1839
				}
1826
		CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
1840
1827
		this.completionToken = typeRef.token;
1841
				TypeBinding receiverType = (TypeBinding)qualifiedBinding;
1828
		this.javadocTagPosition = typeRef.tagSourceStart;
1842
1829
		setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
1843
				if(receiverType != null && receiverType instanceof ReferenceBinding) {
1830
		findTypesAndPackages(
1844
					TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
1831
				this.completionToken,
1845
					if(typeArgTypes != null) {
1832
				scope,
1846
						findMethods(
1833
				(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
1847
								this.completionToken,
1834
				false,
1848
								typeArgTypes,
1835
				new ObjectVector());
1849
								null,
1836
	}
1850
								(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
1837
	//TODO
1851
								scope,
1838
	private void completionOnJavadocTag(ASTNode astNode) {
1852
								new ObjectVector(),
1839
		CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
1853
								onlyStatic,
1840
		setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
1854
								false,
1841
		findJavadocBlockTags(javadocTag);
1855
								false,
1842
		findJavadocInlineTags(javadocTag);
1856
								messageSend,
1843
	}
1857
								scope,
1844
	//TODO
1858
								false,
1845
	private void completionOnJavadocTypeParamReference(ASTNode astNode) {
1859
								false,
1846
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1860
								false,
1847
			CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
1861
								null,
1848
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1862
								null,
1849
			findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
1863
								null,
1850
		}
1864
								false,
1851
	}
1865
								null,
1852
	
1866
								-1,
1853
	private void completionOnKeyword(ASTNode astNode) {
1867
								-1);
1854
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1868
					}
1855
			CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1856
			findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1857
		}
1858
	}
1859
	
1860
	private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
1861
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1862
			LocalDeclaration variable = (LocalDeclaration) astNode;
1863
1864
			int kind;
1865
			if (variable instanceof CompletionOnLocalName){
1866
				this.completionToken = ((CompletionOnLocalName) variable).realName;
1867
				kind = LOCAL;
1868
			} else {
1869
				CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1870
				this.completionToken = arg.realName;
1871
				kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1872
			}
1873
1874
			char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1875
1876
			char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1877
1878
			LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1879
			char[][] discouragedNames = new char[locals.length][];
1880
			int localCount = 0;
1881
			for(int i = 0 ; i < locals.length ; i++){
1882
				if (locals[i] != null) {
1883
					discouragedNames[localCount++] = locals[i].name;
1869
				}
1884
				}
1870
			}
1885
			}
1871
		// Completion on Javadoc nodes
1872
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
1873
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
1874
1886
1875
				CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
1887
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1876
				this.completionToken = typeRef.token;
1877
				this.javadocTagPosition = typeRef.tagSourceStart;
1878
				setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
1879
				findTypesAndPackages(
1880
						this.completionToken,
1881
						scope,
1882
						(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
1883
						false,
1884
						new ObjectVector());
1885
1888
1886
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
1889
			findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1890
		}
1891
	}
1892
	
1893
	private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1894
		CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1887
1895
1888
				this.insideQualifiedReference = true;
1896
		CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1897
		if (fakeType.annotations[0] == annot) {
1898
			// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1899
			// So 'targetedElement' is not computed in this case.
1900
			if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1901
				this.targetedElement = computeTargetedElement(fakeType);
1902
			}
1889
1903
1890
				CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
1904
		}
1891
				this.completionToken = typeRef.completionIdentifier;
1892
				long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
1893
				this.javadocTagPosition = typeRef.tagSourceStart;
1894
1895
				// get the source positions of the completion identifier
1896
				if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1897
					if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
1898
							((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
1899
						int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1900
						setSourceAndTokenRange(rangeStart, (int) completionPosition);
1901
						findMemberTypes(
1902
							this.completionToken,
1903
							(ReferenceBinding) qualifiedBinding,
1904
							scope,
1905
							scope.enclosingSourceType(),
1906
							false,
1907
							false,
1908
							new ObjectVector(),
1909
							null,
1910
							null,
1911
							null,
1912
							false);
1913
					}
1914
				} else if (qualifiedBinding instanceof PackageBinding) {
1915
1905
1916
					setSourceRange(astNode.sourceStart, (int) completionPosition);
1906
		this.assistNodeIsAnnotation = true;
1917
					int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1907
		if (annot.type instanceof CompletionOnSingleTypeReference) {
1918
					setTokenRange(rangeStart, (int) completionPosition);
1908
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1919
					// replace to the end of the completion identifier
1909
			this.completionToken = type.token;
1920
					findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1910
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1921
				}
1922
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
1923
1911
1924
				this.insideQualifiedReference = true;
1912
			if (scope.parent.parent != null &&
1925
				CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1913
					!(scope.parent.parent instanceof MethodScope) &&
1926
				this.completionToken = fieldRef.token;
1914
					!fakeType.isParameter) {
1927
				long completionPosition = fieldRef.nameSourcePosition;
1915
1928
				this.javadocTagPosition = fieldRef.tagSourceStart;
1916
				if (this.completionToken.length <= Keywords.INTERFACE.length
1929
1917
					&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
1930
				if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1918
				)){
1931
					ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1919
					int relevance = computeBaseRelevance();
1932
					int rangeStart = (int) (completionPosition >>> 32);
1920
					relevance += computeRelevanceForResolution();
1933
					if (fieldRef.receiver.isThis()) {
1921
					relevance += computeRelevanceForInterestingProposal();
1934
						if (fieldRef.completeInText()) {
1922
					relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
1935
							rangeStart = fieldRef.separatorPosition;
1923
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1924
					relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
1925
1926
					this.noProposal = false;
1927
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1928
						CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1929
						proposal.setName(Keywords.INTERFACE);
1930
						proposal.setCompletion(Keywords.INTERFACE);
1931
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1932
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
1933
						proposal.setRelevance(relevance);
1934
						this.requestor.accept(proposal);
1935
						if(DEBUG) {
1936
							this.printDebug(proposal);
1936
						}
1937
						}
1937
					} else if (fieldRef.completeInText()) {
1938
						rangeStart = fieldRef.receiver.sourceStart;
1939
					}
1938
					}
1940
					setSourceAndTokenRange(rangeStart, (int) completionPosition);
1939
				}
1941
1940
			}
1942
					if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1941
1943
							|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1942
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1944
						findFields(this.completionToken,
1943
		} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1945
							receiverType,
1944
			this.insideQualifiedReference = true;
1945
1946
			CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1947
			this.completionToken = type.completionIdentifier;
1948
			long completionPosition = type.sourcePositions[type.tokens.length];
1949
			if (qualifiedBinding instanceof PackageBinding) {
1950
1951
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1952
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1953
				// replace to the end of the completion identifier
1954
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1955
			} else {
1956
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1957
1958
				findMemberTypes(
1959
					this.completionToken,
1960
					(ReferenceBinding) qualifiedBinding,
1961
					scope,
1962
					scope.enclosingSourceType(),
1963
					false,
1964
					false,
1965
					new ObjectVector(),
1966
					null,
1967
					null,
1968
					null,
1969
					false);
1970
			}
1971
		}
1972
	}
1973
	
1974
	private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
1975
			Scope scope, boolean insideTypeAnnotation) {
1976
		this.insideQualifiedReference = true;
1977
		CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1978
		long completionPosition = access.nameSourcePosition;
1979
		setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1980
1981
		this.completionToken = access.token;
1982
1983
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1984
			// complete method members with missing return type
1985
			// class X {
1986
			//   Missing f() {return null;}
1987
			//   void foo() {
1988
			//     f().|
1989
			//   }
1990
			// }
1991
			if (this.assistNodeInJavadoc == 0 &&
1992
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1993
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1994
				ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1995
				findFieldsAndMethodsFromMissingReturnType(
1996
						problemMethodBinding.selector,
1997
						problemMethodBinding.parameters,
1998
						scope,
1999
						access,
2000
						insideTypeAnnotation);
2001
			}
2002
		} else {
2003
			if (!access.isInsideAnnotation) {
2004
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2005
					findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
2006
				}
2007
2008
				ObjectVector fieldsFound = new ObjectVector();
2009
				ObjectVector methodsFound = new ObjectVector();
2010
2011
				boolean superCall = access.receiver instanceof SuperReference;
2012
2013
				findFieldsAndMethods(
2014
					this.completionToken,
2015
					((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
2016
					scope,
2017
					fieldsFound,
2018
					methodsFound,
2019
					access,
2020
					scope,
2021
					false,
2022
					superCall,
2023
					null,
2024
					null,
2025
					null,
2026
					false,
2027
					null,
2028
					-1,
2029
					-1);
2030
2031
				if (!superCall) {
2032
					
2033
					checkTimeout();
2034
					
2035
					findFieldsAndMethodsFromCastedReceiver(
2036
							enclosingNode,
2037
							qualifiedBinding,
1946
							scope,
2038
							scope,
1947
							new ObjectVector(),
2039
							fieldsFound,
1948
							new ObjectVector(),
2040
							methodsFound,
1949
							false, /*not only static */
2041
							access,
1950
							fieldRef,
1951
							scope,
2042
							scope,
1952
							false,
2043
							access.receiver);
1953
							true,
2044
				}
1954
							null,
2045
			}
1955
							null,
2046
		}
1956
							null,
2047
	}
1957
							false,
2048
	
1958
							null,
2049
	private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
1959
							-1,
2050
			boolean insideTypeAnnotation) {
1960
							-1);
2051
		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
2052
		Annotation annotation = (Annotation) astNodeParent;
2053
2054
		this.completionToken = memberValuePair.name;
2055
2056
		ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
2057
2058
		if (annotationType != null && annotationType.isAnnotationType()) {
2059
			if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2060
				findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
2061
			}
2062
			if (this.assistNodeCanBeSingleMemberAnnotation) {
2063
				if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
2064
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2065
				} else {
2066
					if (this.expectedTypesPtr > -1) {
2067
						this.assistNodeIsEnum = true;
2068
						done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2069
							if (!this.expectedTypes[i].isEnum()) {
2070
								this.assistNodeIsEnum = false;
2071
								break done;
2072
							}
2073
						}
2074
1961
					}
2075
					}
2076
					if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
2077
						char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
2078
2079
						findUnresolvedReference(
2080
								memberValuePair.sourceStart,
2081
								memberValuePair.sourceEnd,
2082
								(BlockScope)scope,
2083
								alreadyDefinedName);
2084
					}
2085
					findVariablesAndMethods(
2086
						this.completionToken,
2087
						scope,
2088
						FakeInvocationSite,
2089
						scope,
2090
						insideTypeAnnotation,
2091
						true);
2092
					// can be the start of a qualified type name
2093
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2094
				}
2095
			}
2096
		}
2097
	}
2098
	
2099
	private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2100
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
2101
2102
		CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
2103
		TypeBinding[] argTypes = computeTypes(messageSend.arguments);
2104
		this.completionToken = messageSend.selector;
2105
		if (qualifiedBinding == null) {
2106
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2107
				ObjectVector methodsFound = new ObjectVector();
2108
2109
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
2110
				
2111
				checkTimeout();
2112
				
2113
				findLocalMethodsFromStaticImports(
2114
						this.completionToken,
2115
						scope,
2116
						messageSend,
2117
						scope,
2118
						true,
2119
						methodsFound,
2120
						true);
2121
			}
2122
		} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2123
			findMethods(
2124
				this.completionToken,
2125
				null,
2126
				argTypes,
2127
				(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
2128
				scope,
2129
				new ObjectVector(),
2130
				false,
2131
				true,
2132
				messageSend,
2133
				scope,
2134
				false,
2135
				messageSend.receiver instanceof SuperReference,
2136
				false,
2137
				null,
2138
				null,
2139
				null,
2140
				false,
2141
				null,
2142
				-1,
2143
				-1);
2144
		}
2145
	}
2146
	
2147
	private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2148
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2149
			CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
2150
2151
			this.insideQualifiedReference = true;
2152
			this.completionToken = messageSend.selector;
2153
			boolean onlyStatic = false;
2154
			if (messageSend.receiver instanceof NameReference) {
2155
				onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
2156
			} else if (!(messageSend.receiver instanceof MessageSend) &&
2157
					!(messageSend.receiver instanceof FieldReference) &&
2158
					!(messageSend.receiver.isThis())) {
2159
				onlyStatic = true;
2160
			}
1962
2161
1963
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2162
			TypeBinding receiverType = (TypeBinding)qualifiedBinding;
1964
							|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
2163
1965
						findMethods(
2164
			if(receiverType != null && receiverType instanceof ReferenceBinding) {
2165
				TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
2166
				if(typeArgTypes != null) {
2167
					findMethods(
1966
							this.completionToken,
2168
							this.completionToken,
2169
							typeArgTypes,
1967
							null,
2170
							null,
1968
							null,
2171
							(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
1969
							receiverType,
1970
							scope,
2172
							scope,
1971
							new ObjectVector(),
2173
							new ObjectVector(),
1972
							false, /*not only static */
2174
							onlyStatic,
1973
							false,
2175
							false,
1974
							false,
2176
							messageSend,
1975
							fieldRef,
1976
							scope,
2177
							scope,
1977
							false,
2178
							false,
1978
							false,
2179
							false,
1979
							true,
2180
							false,
1980
							null,
2181
							null,
1981
							null,
2182
							null,
1982
							null,
2183
							null,
Lines 1984-2037 Link Here
1984
							null,
2185
							null,
1985
							-1,
2186
							-1,
1986
							-1);
2187
							-1);
1987
						if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
2188
				}
1988
							ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
2189
			}
1989
							if (this.completionToken == null
2190
		}
1990
									|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
2191
	}
1991
									|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
2192
	
1992
								findConstructors(refBinding, null, scope, fieldRef, false);
2193
	private void completionOnMethodName(ASTNode astNode, Scope scope) {
1993
							}
2194
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1994
						}
2195
			CompletionOnMethodName method = (CompletionOnMethodName) astNode;
2196
2197
			setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
2198
2199
			FieldBinding[] fields = scope.enclosingSourceType().fields();
2200
			char[][] excludeNames = new char[fields.length][];
2201
			for(int i = 0 ; i < fields.length ; i++){
2202
				excludeNames[i] = fields[i].name;
2203
			}
2204
2205
			this.completionToken = method.selector;
2206
2207
			findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
2208
		}
2209
	}
2210
	
2211
	private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
2212
		CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
2213
		SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
2214
		this.completionToken = type.token;
2215
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
2216
		findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
2217
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2218
			findKeywordsForMember(this.completionToken, method.modifiers);
2219
		}
2220
2221
		if (method.modifiers == ClassFileConstants.AccDefault) {
2222
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
2223
			if (!enclosingType.isAnnotationType()) {
2224
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
2225
					findMethodDeclarations(
2226
							this.completionToken,
2227
							scope.enclosingSourceType(),
2228
							scope,
2229
							new ObjectVector(),
2230
							null,
2231
							null,
2232
							null,
2233
							false);
2234
				}
2235
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
2236
					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
2237
				}
2238
			}
2239
		}
2240
	}
2241
	
2242
	private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2243
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2244
			CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
2245
2246
			this.insideQualifiedReference = true;
2247
2248
			this.assistNodeIsClass = ref.isClass();
2249
			this.assistNodeIsException = ref.isException();
2250
			this.assistNodeIsInterface = ref.isInterface();
2251
			this.assistNodeIsSuperType = ref.isSuperType();
2252
2253
			this.completionToken = ref.completionIdentifier;
2254
			long completionPosition = ref.sourcePositions[ref.tokens.length];
2255
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2256
2257
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
2258
					(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
2259
				if (this.assistNodeInJavadoc == 0 &&
2260
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2261
					if(ref.tokens.length == 1) {
2262
						findMemberTypesFromMissingType(
2263
								ref,
2264
								ref.sourcePositions[0],
2265
								scope);
1995
					}
2266
					}
1996
				}
2267
				}
1997
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
2268
			} else {
2269
				ObjectVector typesFound = new ObjectVector();
2270
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2271
					findExceptionFromTryStatement(
2272
							this.completionToken,
2273
							(ReferenceBinding)qualifiedBinding,
2274
							scope.enclosingSourceType(),
2275
							(BlockScope)scope,
2276
							typesFound);
2277
				}
2278
				
2279
				checkTimeout();
2280
				
2281
				findMemberTypes(
2282
					this.completionToken,
2283
					(ReferenceBinding) qualifiedBinding,
2284
					scope,
2285
					scope.enclosingSourceType(),
2286
					false,
2287
					false,
2288
					typesFound,
2289
					null,
2290
					null,
2291
					null,
2292
					false);
2293
			}
2294
		}
2295
	}
2296
	
2297
	private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2298
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
2299
2300
		CompletionOnQualifiedAllocationExpression allocExpression =
2301
			(CompletionOnQualifiedAllocationExpression) astNode;
2302
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
2303
2304
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
2305
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2306
				&& ref.isClass()
2307
				&& !ref.isAbstract()) {
2308
				findConstructors(
2309
					ref,
2310
					argTypes,
2311
					scope,
2312
					allocExpression,
2313
					false);
2314
		}
2315
		
2316
		checkTimeout();
2317
		
2318
		if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
2319
				&& !ref.isFinal()
2320
				&& !ref.isEnum()){
2321
			findAnonymousType(
2322
				ref,
2323
				argTypes,
2324
				scope,
2325
				allocExpression);
2326
		}
2327
	}
2328
	
2329
	private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
2330
			Scope scope, boolean insideTypeAnnotation) {
2331
		this.insideQualifiedReference = true;
2332
		CompletionOnQualifiedNameReference ref =
2333
			(CompletionOnQualifiedNameReference) astNode;
2334
		this.completionToken = ref.completionIdentifier;
2335
		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
1998
2336
1999
				CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
2337
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2000
				TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
2338
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2001
				this.completionToken = messageSend.selector;
2339
			// complete field members with missing fields type
2002
				this.javadocTagPosition = messageSend.tagSourceStart;
2340
			// class X {
2003
2341
			//   Missing f;
2004
				// Set source range
2342
			//   void foo() {
2005
				int rangeStart = astNode.sourceStart;
2343
			//     f.|
2006
				if (messageSend.receiver.isThis()) {
2344
			//   }
2007
					if (messageSend.completeInText()) {
2345
			// }
2008
						rangeStart = messageSend.separatorPosition;
2346
			if (this.assistNodeInJavadoc == 0 &&
2009
					}
2347
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2010
				} else if (messageSend.completeInText()) {
2348
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
2011
					rangeStart = messageSend.receiver.sourceStart;
2349
							this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2012
				}
2350
				if(ref.tokens.length == 1) {
2013
				setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
2351
					boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2014
2352
2015
				if (qualifiedBinding == null) {
2353
					if (!foundSomeFields) {
2016
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2354
						
2017
						findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
2355
						checkTimeout();
2356
						
2357
						findMembersFromMissingType(
2358
								ref.tokens[0],
2359
								ref.sourcePositions[0],
2360
								null,
2361
								scope,
2362
								ref,
2363
								ref.isInsideAnnotationAttribute);
2018
					}
2364
					}
2019
				} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2365
				}
2020
					findMethods(
2366
			}
2367
		} else if (qualifiedBinding instanceof VariableBinding) {
2368
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2369
			TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
2370
			if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
2371
				ObjectVector fieldsFound = new ObjectVector();
2372
				ObjectVector methodsFound = new ObjectVector();
2373
2374
				findFieldsAndMethods(
2021
						this.completionToken,
2375
						this.completionToken,
2022
						null,
2376
						receiverType.capture(scope, ref.sourceEnd),
2023
						argTypes,
2024
						(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
2025
						scope,
2377
						scope,
2026
						new ObjectVector(),
2378
						fieldsFound,
2027
						false,
2379
						methodsFound,
2028
						false/* prefix match */,
2380
						ref,
2029
						false,
2030
						messageSend,
2031
						scope,
2381
						scope,
2032
						false,
2382
						false,
2033
						messageSend.receiver instanceof SuperReference,
2383
						false,
2034
						true,
2035
						null,
2384
						null,
2036
						null,
2385
						null,
2037
						null,
2386
						null,
Lines 2039-5072 Link Here
2039
						null,
2388
						null,
2040
						-1,
2389
						-1,
2041
						-1);
2390
						-1);
2042
				}
2391
				
2043
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
2392
				checkTimeout();
2044
//				setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
2045
2393
2046
				CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
2394
				findFieldsAndMethodsFromCastedReceiver(
2047
				this.javadocTagPosition = allocExpression.tagSourceStart;
2395
						enclosingNode,
2048
				int rangeStart = astNode.sourceStart;
2396
						qualifiedBinding,
2049
				if (allocExpression.type.isThis()) {
2397
						scope,
2050
					if (allocExpression.completeInText()) {
2398
						fieldsFound,
2051
						rangeStart = allocExpression.separatorPosition;
2399
						methodsFound,
2052
					}
2400
						ref,
2053
				} else if (allocExpression.completeInText()) {
2401
						scope,
2054
					rangeStart = allocExpression.type.sourceStart;
2402
						ref);
2055
				}
2056
				setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
2057
				TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
2058
2059
				ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
2060
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
2061
					findConstructors(ref, argTypes, scope, allocExpression, false);
2062
				}
2063
			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
2064
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
2065
					CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
2066
					setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
2067
					findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
2068
					findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
2069
				}
2070
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
2071
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
2072
					CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
2073
					setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
2074
					findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
2075
				}
2076
			} else if (astNode instanceof CompletionOnJavadocTag) {
2077
				CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
2078
				setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
2079
				findJavadocBlockTags(javadocTag);
2080
				findJavadocInlineTags(javadocTag);
2081
			}
2082
		}
2083
		return true;
2084
	}
2085
2086
	private void findFieldsAndMethodsFromCastedReceiver(
2087
			ASTNode enclosingNode,
2088
			Binding qualifiedBinding,
2089
			Scope scope,
2090
			ObjectVector fieldsFound,
2091
			ObjectVector methodsFound,
2092
			InvocationSite invocationSite,
2093
			Scope invocationScope,
2094
			Expression receiver) {
2095
2096
		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
2097
2098
		IfStatement ifStatement = (IfStatement)enclosingNode;
2099
2100
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
2101
2102
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
2103
2104
		TypeReference instanceOfType = instanceOfExpression.type;
2105
2106
		if (instanceOfType.resolvedType == null) return;
2107
2108
		boolean findFromAnotherReceiver = false;
2109
2110
		char[][] receiverName = null;
2111
		int receiverStart = -1;
2112
		int receiverEnd = -1;
2113
2114
		if (receiver instanceof QualifiedNameReference) {
2115
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
2116
2117
			receiverName = qualifiedNameReference.tokens;
2118
2119
			if (receiverName.length != 1) return;
2120
2121
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
2122
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
2123
2124
			// if (local instanceof X) local.|
2125
			// if (field instanceof X) field.|
2126
			if (instanceOfExpression.expression instanceof SingleNameReference &&
2127
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
2128
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
2129
				findFromAnotherReceiver = true;
2130
			}
2131
2403
2132
			// if (this.field instanceof X) field.|
2404
			} else if (this.assistNodeInJavadoc == 0 &&
2133
			if (instanceOfExpression.expression instanceof FieldReference) {
2405
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2134
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
2406
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
2407
				boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
2408
				boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
2409
				if (proposeField || proposeMethod) {
2410
					if(ref.tokens.length == 1) {
2411
						if (qualifiedBinding instanceof LocalVariableBinding) {
2412
							// complete local variable members with missing variables type
2413
							// class X {
2414
							//   void foo() {
2415
							//     Missing f;
2416
							//     f.|
2417
							//   }
2418
							// }
2419
							LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
2420
							findFieldsAndMethodsFromMissingType(
2421
									localVariableBinding.declaration.type,
2422
									localVariableBinding.declaringScope,
2423
									ref,
2424
									scope);
2425
						} else {
2426
							// complete field members with missing fields type
2427
							// class X {
2428
							//   Missing f;
2429
							//   void foo() {
2430
							//     f.|
2431
							//   }
2432
							// }
2433
							findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2434
						}
2135
2435
2136
				if (fieldReference.receiver instanceof ThisReference &&
2436
					}
2137
						qualifiedBinding instanceof FieldBinding &&
2138
						fieldReference.binding == qualifiedBinding) {
2139
							findFromAnotherReceiver = true;
2140
				}
2437
				}
2141
			}
2438
			}
2142
		} else if (receiver instanceof FieldReference) {
2143
			FieldReference fieldReference1 = (FieldReference) receiver;
2144
2439
2145
			receiverStart = fieldReference1.sourceStart;
2440
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2146
			receiverEnd = fieldReference1.sourceEnd + 1;
2441
			boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
2147
2442
			ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
2148
			if (fieldReference1.receiver instanceof ThisReference) {
2443
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2149
2444
2150
				receiverName = new char[][] {THIS, fieldReference1.token};
2445
			findMembers(
2446
					this.completionToken,
2447
					receiverType,
2448
					scope,
2449
					ref,
2450
					isInsideAnnotationAttribute,
2451
					null,
2452
					null,
2453
					null,
2454
					false);
2151
2455
2152
				// if (field instanceof X) this.field.|
2456
		} else if (qualifiedBinding instanceof PackageBinding) {
2153
				if (instanceOfExpression.expression instanceof SingleNameReference &&
2154
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
2155
					findFromAnotherReceiver = true;
2156
				}
2157
2457
2158
				// if (this.field instanceof X) this.field.|
2458
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2159
				if (instanceOfExpression.expression instanceof FieldReference) {
2459
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2160
					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
2161
2460
2162
					if (fieldReference2.receiver instanceof ThisReference &&
2461
			// replace to the end of the completion identifier
2163
							fieldReference2.binding == fieldReference1.binding) {
2462
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2164
								findFromAnotherReceiver = true;
2165
					}
2166
				}
2167
			}
2168
		}
2463
		}
2464
	}
2465
	
2466
	private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
2467
			Scope scope) {
2468
		this.insideQualifiedReference = true;
2169
2469
2170
		if (findFromAnotherReceiver) {
2470
		CompletionOnQualifiedTypeReference ref =
2171
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
2471
			(CompletionOnQualifiedTypeReference) astNode;
2172
			char[] castedReceiver = null;
2173
2472
2174
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
2473
		this.assistNodeIsClass = ref.isClass();
2175
			if(this.source != null) {
2474
		this.assistNodeIsException = ref.isException();
2176
				int memberRefStart = this.startPosition;
2475
		this.assistNodeIsInterface = ref.isInterface();
2476
		this.assistNodeIsSuperType = ref.isSuperType();
2177
2477
2178
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
2478
		this.completionToken = ref.completionIdentifier;
2179
				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
2479
		long completionPosition = ref.sourcePositions[ref.tokens.length];
2180
2480
2181
				castedReceiver =
2481
		// get the source positions of the completion identifier
2182
					CharOperation.concat(
2482
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2183
						CharOperation.concat(
2483
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2184
							'(',
2484
			if (this.assistNodeInJavadoc == 0 &&
2185
							CharOperation.concat(
2485
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2186
								CharOperation.concat('(', castedTypeChars, ')'),
2486
				if(ref.tokens.length == 1) {
2187
								receiverChars),
2487
					findMemberTypesFromMissingType(
2188
							')'),
2488
							ref.tokens[0],
2189
						dotChars);
2489
							ref.sourcePositions[0],
2190
			} else {
2490
							scope);
2191
				castedReceiver =
2491
				}
2192
					CharOperation.concat(
2193
						CharOperation.concat(
2194
							'(',
2195
							CharOperation.concat(
2196
								CharOperation.concat('(', castedTypeChars, ')'),
2197
								CharOperation.concatWith(receiverName, '.')),
2198
							')'),
2199
						DOT);
2200
			}
2492
			}
2493
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2494
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2495
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2201
2496
2202
			if (castedReceiver == null) return;
2497
				ObjectVector typesFound = new ObjectVector();
2203
2498
2204
			int oldStartPosition = this.startPosition;
2499
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2205
			this.startPosition = receiverStart;
2500
					findExceptionFromTryStatement(
2501
							this.completionToken,
2502
							(ReferenceBinding)qualifiedBinding,
2503
							scope.enclosingSourceType(),
2504
							(BlockScope)scope,
2505
							typesFound);
2506
				}
2507
				
2508
				checkTimeout();
2206
2509
2207
			findFieldsAndMethods(
2510
				findMemberTypes(
2208
					this.completionToken,
2511
					this.completionToken,
2209
					receiverTypeBinding,
2512
					(ReferenceBinding) qualifiedBinding,
2210
					scope,
2513
					scope,
2211
					fieldsFound,
2514
					scope.enclosingSourceType(),
2212
					methodsFound,
2213
					invocationSite,
2214
					invocationScope,
2215
					false,
2515
					false,
2216
					false,
2516
					false,
2517
					typesFound,
2217
					null,
2518
					null,
2218
					null,
2519
					null,
2219
					null,
2520
					null,
2220
					false,
2521
					false);
2221
					castedReceiver,
2522
			}
2222
					receiverStart,
2523
		} else if (qualifiedBinding instanceof PackageBinding) {
2223
					receiverEnd);
2224
2524
2225
			this.startPosition = oldStartPosition;
2525
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2526
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2527
			// replace to the end of the completion identifier
2528
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2226
		}
2529
		}
2227
	}
2530
	}
2531
	
2532
	private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
2533
			boolean insideTypeAnnotation) {
2534
		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
2535
		this.completionToken = singleNameReference.token;
2536
		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
2537
		if (switchStatement != null
2538
				&& switchStatement.expression.resolvedType != null
2539
				&& switchStatement.expression.resolvedType.isEnum()) {
2540
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2541
				this.assistNodeIsEnum = true;
2542
				findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
2543
			}
2544
		} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
2545
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2546
		} else {
2547
			if (this.expectedTypesPtr > -1) {
2548
				this.assistNodeIsEnum = true;
2549
				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2550
					if (!this.expectedTypes[i].isEnum()) {
2551
						this.assistNodeIsEnum = false;
2552
						break done;
2553
					}
2554
				}
2228
2555
2229
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2556
			}
2230
		if(this.requestor != null){
2557
			if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
2231
			this.requestor.beginReporting();
2558
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
2232
		}
2559
2233
		boolean contextAccepted = false;
2560
				findUnresolvedReference(
2234
		IType topLevelType = type;
2561
						singleNameReference.sourceStart,
2235
		while(topLevelType.getDeclaringType() != null) {
2562
						singleNameReference.sourceEnd,
2236
			topLevelType = topLevelType.getDeclaringType();
2563
						(BlockScope)scope,
2564
						alreadyDefinedName);
2565
			}
2566
			
2567
			checkTimeout();
2568
			
2569
			findVariablesAndMethods(
2570
				this.completionToken,
2571
				scope,
2572
				singleNameReference,
2573
				scope,
2574
				insideTypeAnnotation,
2575
				singleNameReference.isInsideAnnotationAttribute);
2576
			
2577
			checkTimeout();
2578
			
2579
			// can be the start of a qualified type name
2580
			findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
2581
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2582
				if (this.completionToken != null && this.completionToken.length != 0) {
2583
					findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
2584
				} else {
2585
					findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
2586
				}
2587
			}
2588
			if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
2589
				if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
2590
					ReferenceBinding ref = scope.enclosingSourceType();
2591
					findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
2592
				} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
2593
					ReferenceBinding ref = scope.enclosingSourceType();
2594
					findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
2595
				}
2596
			}
2237
		}
2597
		}
2598
	}
2599
	
2600
	private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2601
		CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
2238
2602
2239
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
2603
		this.completionToken = singleRef.token;
2240
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2241
2604
2242
		CompilationUnitDeclaration compilationUnit = null;
2605
		this.assistNodeIsClass = singleRef.isClass();
2606
		this.assistNodeIsException = singleRef.isException();
2607
		this.assistNodeIsInterface = singleRef.isInterface();
2608
		this.assistNodeIsConstructor = singleRef.isConstructorType;
2609
		this.assistNodeIsSuperType = singleRef.isSuperType();
2610
2611
		// can be the start of a qualified type name
2612
		if (qualifiedBinding == null) {
2613
			if (this.completionToken.length == 0 &&
2614
					(astNodeParent instanceof ParameterizedSingleTypeReference ||
2615
							astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
2616
				this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
2243
2617
2244
		try {
2618
				findParameterizedType((TypeReference)astNodeParent, scope);
2245
			// TypeConverter is used instead of SourceTypeConverter because the type
2246
			// to convert can be a binary type or a source type
2247
			TypeDeclaration typeDeclaration = null;
2248
			if (type instanceof SourceType) {
2249
				SourceType sourceType = (SourceType) type;
2250
				ISourceType info = (ISourceType) sourceType.getElementInfo();
2251
				compilationUnit = SourceTypeConverter.buildCompilationUnit(
2252
					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
2253
					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
2254
					| SourceTypeConverter.MEMBER_TYPE, // need member types
2255
					// no need for field initialization
2256
					this.problemReporter,
2257
					compilationResult);
2258
				if (compilationUnit.types != null)
2259
					typeDeclaration = compilationUnit.types[0];
2260
			} else {
2619
			} else {
2261
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
2620
				ObjectVector typesFound = new ObjectVector();
2262
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
2621
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2622
					findExceptionFromTryStatement(
2623
							this.completionToken,
2624
							null,
2625
							scope.enclosingSourceType(),
2626
							(BlockScope)scope,
2627
							typesFound);
2628
				}
2629
				
2630
				checkTimeout();
2631
				
2632
				findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
2263
			}
2633
			}
2634
		} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2635
			findMemberTypes(
2636
				this.completionToken,
2637
				(ReferenceBinding) qualifiedBinding,
2638
				scope,
2639
				scope.enclosingSourceType(),
2640
				false,
2641
				false,
2642
				false,
2643
				false,
2644
				!this.assistNodeIsConstructor,
2645
				null,
2646
				new ObjectVector(),
2647
				null,
2648
				null,
2649
				null,
2650
				false);
2651
		}
2652
	}
2264
2653
2265
			if(typeDeclaration != null) {
2654
	private char[][] computeAlreadyDefinedName(
2266
				// build AST from snippet
2655
			BlockScope scope,
2267
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
2656
			InvocationSite invocationSite) {
2657
		ArrayList result = new ArrayList();
2268
2658
2269
				// merge AST
2659
		boolean staticsOnly = false;
2270
				FieldDeclaration[] oldFields = typeDeclaration.fields;
2271
				FieldDeclaration[] newFields = null;
2272
				if (oldFields != null) {
2273
					newFields = new FieldDeclaration[oldFields.length + 1];
2274
					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
2275
					newFields[oldFields.length] = fakeInitializer;
2276
				} else {
2277
					newFields = new FieldDeclaration[] {fakeInitializer};
2278
				}
2279
				typeDeclaration.fields = newFields;
2280
2660
2281
				if(DEBUG) {
2661
		Scope currentScope = scope;
2282
					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
2283
					System.out.println(compilationUnit.toString());
2284
				}
2285
2286
				if (compilationUnit.types != null) {
2287
					try {
2288
						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
2289
2662
2290
						if ((this.unitScope = compilationUnit.scope) != null) {
2663
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
2291
							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
2292
							compilationUnit.scope.faultInTypes();
2293
							compilationUnit.resolve();
2294
						}
2295
					} catch (CompletionNodeFound e) {
2296
						//					completionNodeFound = true;
2297
						if (e.astNode != null) {
2298
							// if null then we found a problem in the completion node
2299
							contextAccepted =
2300
								complete(
2301
									e.astNode,
2302
									this.parser.assistNodeParent,
2303
									this.parser.enclosingNode,
2304
									compilationUnit,
2305
									e.qualifiedBinding,
2306
									e.scope,
2307
									e.insideTypeAnnotation);
2308
						}
2309
					}
2310
				}
2311
				if(this.noProposal && this.problem != null) {
2312
					if(!contextAccepted) {
2313
						contextAccepted = true;
2314
						InternalCompletionContext context = new InternalCompletionContext();
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
			}
2324
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
2325
			if(DEBUG) {
2326
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2327
				e.printStackTrace(System.out);
2328
			}
2329
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
2330
			if(DEBUG) {
2331
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2332
				e.printStackTrace(System.out);
2333
			}
2334
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
2335
			if(DEBUG) {
2336
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2337
				e.printStackTrace(System.out);
2338
			}
2339
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
2340
			if(DEBUG) {
2341
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2342
				e.printStackTrace(System.out);
2343
			}
2344
		} catch(JavaModelException e) {
2345
			// Do nothing
2346
		}
2347
		if(!contextAccepted) {
2348
			contextAccepted = true;
2349
			InternalCompletionContext context = new InternalCompletionContext();
2350
			if (this.requestor.isExtendedContextRequired()) context.setExtended();
2351
			this.requestor.acceptContext(context);
2352
		}
2353
		if(this.requestor != null){
2354
			this.requestor.endReporting();
2355
		}
2356
	}
2357
2664
2358
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2665
			switch (currentScope.kind) {
2359
		StringBuffer prefix = new StringBuffer();
2360
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
2361
		if(isStatic) {
2362
			prefix.append("static "); //$NON-NLS-1$
2363
		}
2364
		prefix.append("{\n"); //$NON-NLS-1$
2365
		for (int i = 0; i < localVariableTypeNames.length; i++) {
2366
			ASTNode.printModifiers(localVariableModifiers[i], prefix);
2367
			prefix.append(' ');
2368
			prefix.append(localVariableTypeNames[i]);
2369
			prefix.append(' ');
2370
			prefix.append(localVariableNames[i]);
2371
			prefix.append(';');
2372
		}
2373
2666
2374
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
2667
				case Scope.METHOD_SCOPE :
2375
		this.offset = prefix.length();
2668
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
2669
					MethodScope methodScope = (MethodScope) currentScope;
2670
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
2376
2671
2377
		String encoding = this.compilerOptions.defaultEncoding;
2672
				//$FALL-THROUGH$
2378
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
2673
				case Scope.BLOCK_SCOPE :
2379
			fakeSource,
2674
					BlockScope blockScope = (BlockScope) currentScope;
2380
			null,
2381
			"FakeType.java", //$NON-NLS-1$
2382
			encoding);
2383
2675
2384
		this.actualCompletionPosition = prefix.length() + position - 1;
2676
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
2677
						LocalVariableBinding local = blockScope.locals[i];
2385
2678
2386
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2679
						if (local == null)
2387
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
2680
							break next;
2388
2681
2389
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
2682
						if (local.isSecret())
2683
							continue next;
2390
2684
2391
		return (Initializer)fakeAST.types[0].fields[0];
2685
						result.add(local.name);
2392
	}
2686
					}
2687
					break;
2393
2688
2394
	/**
2689
				case Scope.CLASS_SCOPE :
2395
	 * Ask the engine to compute a completion at the specified position
2690
					ClassScope classScope = (ClassScope) currentScope;
2396
	 * of the given compilation unit.
2691
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
2397
	 *
2692
					computeAlreadyDefinedName(
2398
	 *  No return
2693
							enclosingType,
2399
	 *      completion results are answered through a requestor.
2694
							classScope,
2400
	 *
2695
							staticsOnly,
2401
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
2696
							invocationSite,
2402
	 *      the source of the current compilation unit.
2697
							result);
2403
	 *
2698
					staticsOnly |= enclosingType.isStatic();
2404
	 *  @param completionPosition int
2699
					break;
2405
	 *      a position in the source where the completion is taking place.
2406
	 *      This position is relative to the source provided.
2407
	 */
2408
	public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
2409
2700
2410
		if(DEBUG) {
2701
				case Scope.COMPILATION_UNIT_SCOPE :
2411
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
2702
					break done1;
2412
			System.out.print(sourceUnit.getFileName());
2703
			}
2413
			System.out.print(" AT POSITION "); //$NON-NLS-1$
2704
			currentScope = currentScope.parent;
2414
			System.out.println(completionPosition);
2415
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
2416
			System.out.println(sourceUnit.getContents());
2417
		}
2705
		}
2418
		this.requestor.beginReporting();
2419
		boolean contextAccepted = false;
2420
		try {
2421
			this.fileName = sourceUnit.getFileName();
2422
			this.actualCompletionPosition = completionPosition - 1;
2423
			this.offset = pos;
2424
			this.typeRoot = root;
2425
			// for now until we can change the UI.
2426
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2427
			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
2428
2706
2429
			//		boolean completionNodeFound = false;
2707
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
2430
			if (parsedUnit != null) {
2431
				if(DEBUG) {
2432
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
2433
					System.out.println(parsedUnit.toString());
2434
				}
2435
2708
2436
				// scan the package & import statements first
2709
		return (char[][])result.toArray(new char[result.size()][]);
2437
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
2710
	}
2438
					contextAccepted = true;
2439
					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
2440
					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
2441
						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
2442
					}
2443
					if(this.noProposal && this.problem != null) {
2444
						this.requestor.completionFailure(this.problem);
2445
						if(DEBUG) {
2446
							this.printDebug(this.problem);
2447
						}
2448
					}
2449
					return;
2450
				}
2451
2711
2452
				ImportReference[] imports = parsedUnit.imports;
2712
	private void computeAlreadyDefinedName(
2453
				if (imports != null) {
2713
			FieldBinding[] fields,
2454
					for (int i = 0, length = imports.length; i < length; i++) {
2714
			Scope scope,
2455
						ImportReference importReference = imports[i];
2715
			boolean onlyStaticFields,
2456
						if (importReference instanceof CompletionOnImportReference) {
2716
			ReferenceBinding receiverType,
2457
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2717
			InvocationSite invocationSite,
2458
							if ((this.unitScope = parsedUnit.scope) != null) {
2718
			ArrayList result) {
2459
								contextAccepted = true;
2460
								buildContext(importReference, null, parsedUnit, null, null);
2461
2719
2462
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
2720
		next : for (int f = fields.length; --f >= 0;) {
2463
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
2721
			FieldBinding field = fields[f];
2464
2722
2465
								char[][] oldTokens = importReference.tokens;
2723
			if (field.isSynthetic()) continue next;
2466
								int tokenCount = oldTokens.length;
2467
								if (tokenCount == 1) {
2468
									findImports((CompletionOnImportReference)importReference, true);
2469
								} else if(tokenCount > 1){
2470
									this.insideQualifiedReference = true;
2471
2724
2472
									char[] lastToken = oldTokens[tokenCount - 1];
2725
			if (onlyStaticFields && !field.isStatic()) continue next;
2473
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
2474
2726
2475
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
2727
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
2476
									if(binding != null) {
2477
										if(binding instanceof PackageBinding) {
2478
											findImports((CompletionOnImportReference)importReference, false);
2479
										} else {
2480
											ReferenceBinding ref = (ReferenceBinding) binding;
2481
2728
2482
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2729
			result.add(field.name);
2483
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
2730
		}
2484
											}
2731
	}
2485
											if(importReference.isStatic()) {
2486
2732
2487
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2733
	private void computeAlreadyDefinedName(
2488
													findImportsOfStaticFields(lastToken, ref);
2734
			SourceTypeBinding receiverType,
2489
												}
2735
			ClassScope scope,
2490
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
2736
			boolean onlyStaticFields,
2491
													findImportsOfStaticMethods(lastToken, ref);
2737
			InvocationSite invocationSite,
2492
												}
2738
			ArrayList result) {
2493
											}
2494
										}
2495
									}
2496
								}
2497
2739
2498
								if(this.noProposal && this.problem != null) {
2740
		ReferenceBinding currentType = receiverType;
2499
									this.requestor.completionFailure(this.problem);
2741
		ReferenceBinding[] interfacesToVisit = null;
2500
									if(DEBUG) {
2742
		int nextPosition = 0;
2501
										this.printDebug(this.problem);
2743
		do {
2502
									}
2744
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
2503
								}
2745
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2504
							}
2746
				if (interfacesToVisit == null) {
2505
							return;
2747
					interfacesToVisit = itsInterfaces;
2506
						} else if(importReference instanceof CompletionOnKeyword) {
2748
					nextPosition = interfacesToVisit.length;
2507
							contextAccepted = true;
2749
				} else {
2508
							buildContext(importReference, null, parsedUnit, null, null);
2750
					int itsLength = itsInterfaces.length;
2509
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2751
					if (nextPosition + itsLength >= interfacesToVisit.length)
2510
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
2752
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2511
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
2753
					nextInterface : for (int a = 0; a < itsLength; a++) {
2512
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
2754
						ReferenceBinding next = itsInterfaces[a];
2513
							}
2755
						for (int b = 0; b < nextPosition; b++)
2514
							if(this.noProposal && this.problem != null) {
2756
							if (next == interfacesToVisit[b]) continue nextInterface;
2515
								this.requestor.completionFailure(this.problem);
2757
						interfacesToVisit[nextPosition++] = next;
2516
								if(DEBUG) {
2517
									this.printDebug(this.problem);
2518
								}
2519
							}
2520
							return;
2521
						}
2522
					}
2758
					}
2523
				}
2759
				}
2760
			}
2524
2761
2525
				if (parsedUnit.types != null) {
2762
			FieldBinding[] fields = currentType.availableFields();
2526
					try {
2763
			if(fields != null && fields.length > 0) {
2527
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2764
				computeAlreadyDefinedName(
2765
					fields,
2766
					scope,
2767
					onlyStaticFields,
2768
					receiverType,
2769
					invocationSite,
2770
					result);
2771
			}
2772
			currentType = currentType.superclass();
2773
		} while ( currentType != null);
2528
2774
2529
						if ((this.unitScope = parsedUnit.scope) != null) {
2775
		if (interfacesToVisit != null) {
2530
							this.source = sourceUnit.getContents();
2776
			for (int i = 0; i < nextPosition; i++) {
2531
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
2777
				ReferenceBinding anInterface = interfacesToVisit[i];
2532
							parsedUnit.scope.faultInTypes();
2778
				FieldBinding[] fields = anInterface.availableFields();
2533
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
2779
				if(fields !=  null) {
2534
							if(DEBUG) {
2780
					computeAlreadyDefinedName(
2535
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
2781
						fields,
2536
								System.out.println(parsedUnit.toString());
2782
						scope,
2537
							}
2783
						onlyStaticFields,
2538
							parsedUnit.resolve();
2784
						receiverType,
2539
						}
2785
						invocationSite,
2540
					} catch (CompletionNodeFound e) {
2786
						result);
2541
						//					completionNodeFound = true;
2787
				}
2542
						if (e.astNode != null) {
2788
2543
							// if null then we found a problem in the completion node
2789
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
2544
							if(DEBUG) {
2790
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2545
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
2791
					int itsLength = itsInterfaces.length;
2546
								System.out.println(e.astNode.toString());
2792
					if (nextPosition + itsLength >= interfacesToVisit.length)
2547
								if(this.parser.assistNodeParent != null) {
2793
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2548
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
2794
					nextInterface : for (int a = 0; a < itsLength; a++) {
2549
									System.out.println(this.parser.assistNodeParent);
2795
						ReferenceBinding next = itsInterfaces[a];
2550
								}
2796
						for (int b = 0; b < nextPosition; b++)
2551
							}
2797
							if (next == interfacesToVisit[b]) continue nextInterface;
2552
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
2798
						interfacesToVisit[nextPosition++] = next;
2553
							contextAccepted =
2554
								complete(
2555
									e.astNode,
2556
									this.parser.assistNodeParent,
2557
									this.parser.enclosingNode,
2558
									parsedUnit,
2559
									e.qualifiedBinding,
2560
									e.scope,
2561
									e.insideTypeAnnotation);
2562
						}
2563
					}
2799
					}
2564
				}
2800
				}
2565
			}
2801
			}
2802
		}
2803
	}
2566
2804
2567
			if(this.noProposal && this.problem != null) {
2805
	int computeBaseRelevance(){
2568
				if(!contextAccepted) {
2806
		return R_DEFAULT;
2569
					contextAccepted = true;
2807
	}
2570
					InternalCompletionContext context = new InternalCompletionContext();
2808
2571
					context.setOffset(completionPosition - this.offset);
2809
	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
2572
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2810
2573
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
2811
		// default filter
2574
					this.requestor.acceptContext(context);
2812
		this.expectedTypesFilter = SUBTYPE;
2575
				}
2813
		this.hasJavaLangObjectAsExpectedType = false;
2576
				this.requestor.completionFailure(this.problem);
2814
2577
				if(DEBUG) {
2815
		// find types from parent
2578
					this.printDebug(this.problem);
2816
		if(parent instanceof AbstractVariableDeclaration) {
2817
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
2818
			TypeBinding binding = variable.type.resolvedType;
2819
			if(binding != null) {
2820
				if(!(variable.initialization instanceof ArrayInitializer)) {
2821
					addExpectedType(binding, scope);
2579
				}
2822
				}
2580
			}
2823
			}
2581
			/* Ignore package, import, class & interface keywords for now...
2824
		} else if(parent instanceof Assignment) {
2582
					if (!completionNodeFound) {
2825
			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
2583
						if (parsedUnit == null || parsedUnit.types == null) {
2826
			if(binding != null) {
2584
							// this is not good enough... can still be trying to define a second type
2827
				addExpectedType(binding, scope);
2585
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
2586
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
2587
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
2588
						}
2589
						// currently have no way to know if extends/implements are possible keywords
2590
					}
2591
			*/
2592
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
2593
			if(DEBUG) {
2594
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2595
				e.printStackTrace(System.out);
2596
			}
2597
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
2598
			if(DEBUG) {
2599
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2600
				e.printStackTrace(System.out);
2601
			}
2602
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
2603
			if(DEBUG) {
2604
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2605
				e.printStackTrace(System.out);
2606
			}
2828
			}
2607
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
2829
		} else if(parent instanceof ReturnStatement) {
2608
			if(DEBUG) {
2830
			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
2609
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2831
				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
2610
				e.printStackTrace(System.out);
2832
				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
2833
				if(binding != null) {
2834
					addExpectedType(binding, scope);
2835
				}
2611
			}
2836
			}
2612
		} finally {
2837
		} else if(parent instanceof CastExpression) {
2613
			reset();
2838
			Expression e = ((CastExpression)parent).type;
2614
			if(!contextAccepted) {
2839
			TypeBinding binding = e.resolvedType;
2615
				contextAccepted = true;
2840
			if(binding != null){
2616
				InternalCompletionContext context = new InternalCompletionContext();
2841
				addExpectedType(binding, scope);
2617
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2842
				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2618
				context.setOffset(completionPosition - this.offset);
2619
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
2620
				this.requestor.acceptContext(context);
2621
			}
2843
			}
2622
			this.requestor.endReporting();
2844
		} else if(parent instanceof MessageSend) {
2623
		}
2845
			MessageSend messageSend = (MessageSend) parent;
2624
	}
2625
2846
2626
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
2847
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
2627
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
2848
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
2849
				boolean isStatic = messageSend.receiver.isTypeReference();
2628
2850
2629
		if (annotatedElement instanceof TypeDeclaration) {
2851
				while(binding != null) {
2630
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
2852
					computeExpectedTypesForMessageSend(
2631
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
2853
						binding,
2632
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
2854
						messageSend.selector,
2633
			}
2855
						messageSend.arguments,
2634
			return TagBits.AnnotationForType;
2856
						(ReferenceBinding)messageSend.actualReceiverType,
2635
		} else if (annotatedElement instanceof FieldDeclaration) {
2857
						scope,
2636
			if (fakeNode.isParameter) {
2858
						messageSend,
2637
				return TagBits.AnnotationForParameter;
2859
						isStatic);
2860
					computeExpectedTypesForMessageSendForInterface(
2861
						binding,
2862
						messageSend.selector,
2863
						messageSend.arguments,
2864
						(ReferenceBinding)messageSend.actualReceiverType,
2865
						scope,
2866
						messageSend,
2867
						isStatic);
2868
					binding = binding.superclass();
2869
				}
2638
			}
2870
			}
2639
			return TagBits.AnnotationForField;
2871
		} else if(parent instanceof AllocationExpression) {
2640
		} else if (annotatedElement instanceof MethodDeclaration) {
2872
			AllocationExpression allocationExpression = (AllocationExpression) parent;
2641
			return TagBits.AnnotationForMethod;
2642
		} else if (annotatedElement instanceof Argument) {
2643
			return TagBits.AnnotationForParameter;
2644
		} else if (annotatedElement instanceof ConstructorDeclaration) {
2645
			return TagBits.AnnotationForConstructor;
2646
		} else if (annotatedElement instanceof LocalDeclaration) {
2647
			return TagBits.AnnotationForLocalVariable;
2648
		} else if (annotatedElement instanceof ImportReference) {
2649
			return TagBits.AnnotationForPackage;
2650
		}
2651
		return 0;
2652
	}
2653
2873
2654
	private TypeBinding[] computeTypes(Expression[] arguments) {
2874
			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
2655
		if (arguments == null) return null;
2656
		int argsLength = arguments.length;
2657
		TypeBinding[] argTypes = new TypeBinding[argsLength];
2658
		for (int a = argsLength; --a >= 0;) {
2659
			argTypes[a] = arguments[a].resolvedType;
2660
		}
2661
		return argTypes;
2662
	}
2663
2664
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
2665
		if (arguments == null) return null;
2666
		int argsLength = arguments.length;
2667
		TypeBinding[] argTypes = new TypeBinding[argsLength];
2668
		for (int a = argsLength; --a >= 0;) {
2669
			TypeBinding typeBinding = arguments[a].resolvedType;
2670
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
2671
			argTypes[a] = typeBinding;
2672
		}
2673
		return argTypes;
2674
	}
2675
2676
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
2677
		MethodBinding[] methods = annotation.availableMethods();
2678
		nextAttribute: for (int i = 0; i < methods.length; i++) {
2679
			MethodBinding method = methods[i];
2680
2875
2681
			if(!CharOperation.prefixEquals(token, method.selector, false)
2876
			if(binding != null) {
2682
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
2877
				computeExpectedTypesForAllocationExpression(
2878
					binding,
2879
					allocationExpression.arguments,
2880
					scope,
2881
					allocationExpression);
2882
			}
2883
		} else if(parent instanceof OperatorExpression) {
2884
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
2885
			if(parent instanceof ConditionalExpression) {
2886
				// for future use
2887
			} else if(parent instanceof InstanceOfExpression) {
2888
				InstanceOfExpression e = (InstanceOfExpression) parent;
2889
				TypeBinding binding = e.expression.resolvedType;
2890
				if(binding != null){
2891
					addExpectedType(binding, scope);
2892
					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2893
				}
2894
			} else if(parent instanceof BinaryExpression) {
2895
				BinaryExpression binaryExpression = (BinaryExpression) parent;
2896
				switch(operator) {
2897
					case OperatorIds.EQUAL_EQUAL :
2898
						// expected type is not relevant in this case
2899
						TypeBinding binding = binaryExpression.left.resolvedType;
2900
						if (binding != null) {
2901
							addExpectedType(binding, scope);
2902
							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2903
						}
2904
						break;
2905
					case OperatorIds.PLUS :
2906
						addExpectedType(TypeBinding.SHORT, scope);
2907
						addExpectedType(TypeBinding.INT, scope);
2908
						addExpectedType(TypeBinding.LONG, scope);
2909
						addExpectedType(TypeBinding.FLOAT, scope);
2910
						addExpectedType(TypeBinding.DOUBLE, scope);
2911
						addExpectedType(TypeBinding.CHAR, scope);
2912
						addExpectedType(TypeBinding.BYTE, scope);
2913
						addExpectedType(scope.getJavaLangString(), scope);
2914
						break;
2915
					case OperatorIds.AND_AND :
2916
					case OperatorIds.OR_OR :
2917
					case OperatorIds.XOR :
2918
						addExpectedType(TypeBinding.BOOLEAN, scope);
2919
						break;
2920
					default :
2921
						addExpectedType(TypeBinding.SHORT, scope);
2922
						addExpectedType(TypeBinding.INT, scope);
2923
						addExpectedType(TypeBinding.LONG, scope);
2924
						addExpectedType(TypeBinding.FLOAT, scope);
2925
						addExpectedType(TypeBinding.DOUBLE, scope);
2926
						addExpectedType(TypeBinding.CHAR, scope);
2927
						addExpectedType(TypeBinding.BYTE, scope);
2928
						break;
2929
				}
2930
				if(operator == OperatorIds.LESS) {
2931
					if(binaryExpression.left instanceof SingleNameReference){
2932
						SingleNameReference name = (SingleNameReference) binaryExpression.left;
2933
						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
2934
						if(b instanceof ReferenceBinding) {
2935
							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
2936
							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
2937
								addExpectedType(typeVariableBindings[0].firstBound, scope);
2938
							}
2683
2939
2684
			int length = attributesFound == null ? 0 : attributesFound.length;
2940
						}
2685
			for (int j = 0; j < length; j++) {
2941
					}
2686
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
2942
				}
2943
			} else if(parent instanceof UnaryExpression) {
2944
				switch(operator) {
2945
					case OperatorIds.NOT :
2946
						addExpectedType(TypeBinding.BOOLEAN, scope);
2947
						break;
2948
					case OperatorIds.TWIDDLE :
2949
						addExpectedType(TypeBinding.SHORT, scope);
2950
						addExpectedType(TypeBinding.INT, scope);
2951
						addExpectedType(TypeBinding.LONG, scope);
2952
						addExpectedType(TypeBinding.CHAR, scope);
2953
						addExpectedType(TypeBinding.BYTE, scope);
2954
						break;
2955
					case OperatorIds.PLUS :
2956
					case OperatorIds.MINUS :
2957
					case OperatorIds.PLUS_PLUS :
2958
					case OperatorIds.MINUS_MINUS :
2959
						addExpectedType(TypeBinding.SHORT, scope);
2960
						addExpectedType(TypeBinding.INT, scope);
2961
						addExpectedType(TypeBinding.LONG, scope);
2962
						addExpectedType(TypeBinding.FLOAT, scope);
2963
						addExpectedType(TypeBinding.DOUBLE, scope);
2964
						addExpectedType(TypeBinding.CHAR, scope);
2965
						addExpectedType(TypeBinding.BYTE, scope);
2966
						break;
2967
				}
2687
			}
2968
			}
2969
		} else if(parent instanceof ArrayReference) {
2970
			addExpectedType(TypeBinding.SHORT, scope);
2971
			addExpectedType(TypeBinding.INT, scope);
2972
			addExpectedType(TypeBinding.LONG, scope);
2973
		} else if(parent instanceof ParameterizedSingleTypeReference) {
2974
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
2975
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2976
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
2977
			if(typeVariables != null && typeVariables.length >= length) {
2978
				int index = length - 1;
2979
				while(index > -1 && ref.typeArguments[index] != node) index--;
2688
2980
2689
			int relevance = computeBaseRelevance();
2981
				TypeBinding bound = typeVariables[index].firstBound;
2690
			relevance += computeRelevanceForResolution();
2982
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2691
			relevance += computeRelevanceForInterestingProposal(method);
2983
			}
2692
			relevance += computeRelevanceForCaseMatching(token, method.selector);
2984
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
2693
			relevance += computeRelevanceForQualification(false);
2985
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
2694
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2986
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2987
			TypeReference[][] arguments = ref.typeArguments;
2988
			if(typeVariables != null) {
2989
				int iLength = arguments == null ? 0 : arguments.length;
2990
				done: for (int i = 0; i < iLength; i++) {
2991
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
2992
					for (int j = 0; j < jLength; j++) {
2993
						if(arguments[i][j] == node && typeVariables.length > j) {
2994
							TypeBinding bound = typeVariables[j].firstBound;
2995
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2996
							break done;
2997
						}
2998
					}
2999
				}
3000
			}
3001
		} else if(parent instanceof MemberValuePair) {
3002
			MemberValuePair memberValuePair = (MemberValuePair) parent;
3003
			if(memberValuePair.binding != null) {
3004
				addExpectedType(memberValuePair.binding.returnType, scope);
3005
			}
3006
		} else if (parent instanceof NormalAnnotation) {
3007
			NormalAnnotation annotation = (NormalAnnotation) parent;
3008
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
3009
			if(memberValuePairs == null || memberValuePairs.length == 0) {
3010
				if(annotation.resolvedType instanceof ReferenceBinding) {
3011
					MethodBinding[] methodBindings =
3012
						((ReferenceBinding)annotation.resolvedType).availableMethods();
3013
					if (methodBindings != null &&
3014
							methodBindings.length > 0 &&
3015
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
3016
						boolean canBeSingleMemberAnnotation = true;
3017
						done : for (int i = 1; i < methodBindings.length; i++) {
3018
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
3019
								canBeSingleMemberAnnotation = false;
3020
								break done;
3021
							}
3022
						}
3023
						if (canBeSingleMemberAnnotation) {
3024
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
3025
							addExpectedType(methodBindings[0].returnType, scope);
3026
						}
3027
					}
3028
				}
3029
			}
3030
		} else if (parent instanceof TryStatement) {
3031
			boolean isException = false;
3032
			if (node instanceof CompletionOnSingleTypeReference) {
3033
				isException = ((CompletionOnSingleTypeReference)node).isException();
3034
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
3035
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
3036
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
3037
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
3038
			}
3039
			if (isException) {
3040
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
3041
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
3042
				if (bindings != null && bindings.length > 0) {
3043
					for (int i = 0; i < bindings.length; i++) {
3044
						addExpectedType(bindings[i], scope);
3045
					}
3046
					this.expectedTypesFilter = SUPERTYPE;
3047
				}
3048
			}
3049
		} else if (parent instanceof SwitchStatement) {
3050
			SwitchStatement switchStatement = (SwitchStatement) parent;
3051
			if (switchStatement.expression != null &&
3052
					switchStatement.expression.resolvedType != null) {
3053
				addExpectedType(switchStatement.expression.resolvedType, scope);
3054
			}
2695
3055
2696
			this.noProposal = false;
3056
		// Expected types for javadoc
2697
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
3057
		} else if (parent instanceof Javadoc) {
2698
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
3058
			if (scope.kind == Scope.METHOD_SCOPE) {
2699
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
3059
				MethodScope methodScope = (MethodScope) scope;
2700
				proposal.setSignature(getSignature(method.returnType));
3060
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
2701
				proposal.setName(method.selector);
3061
				if (methodDecl != null && methodDecl.binding != null) {
2702
				proposal.setCompletion(method.selector);
3062
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
2703
				proposal.setFlags(method.modifiers);
3063
					if (exceptions != null) {
2704
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3064
						for (int i = 0; i < exceptions.length; i++) {
2705
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3065
							addExpectedType(exceptions[i], scope);
2706
				proposal.setRelevance(relevance);
3066
						}
2707
				this.requestor.accept(proposal);
3067
					}
2708
				if(DEBUG) {
2709
					this.printDebug(proposal);
2710
				}
3068
				}
2711
			}
3069
			}
2712
		}
3070
		}
3071
3072
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
3073
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
3074
		}
2713
	}
3075
	}
2714
	private void findAnonymousType(
3076
2715
		ReferenceBinding currentType,
3077
	private void computeExpectedTypesForAllocationExpression(
2716
		TypeBinding[] argTypes,
3078
		ReferenceBinding binding,
3079
		Expression[] arguments,
2717
		Scope scope,
3080
		Scope scope,
2718
		InvocationSite invocationSite) {
3081
		InvocationSite invocationSite) {
2719
3082
2720
		if (currentType.isInterface()) {
3083
		MethodBinding[] methods = binding.availableMethods();
2721
			char[] completion = CharOperation.NO_CHAR;
3084
		nextMethod : for (int i = 0; i < methods.length; i++) {
2722
			int relevance = computeBaseRelevance();
3085
			MethodBinding method = methods[i];
2723
			relevance += computeRelevanceForResolution();
2724
			relevance += computeRelevanceForInterestingProposal();
2725
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2726
3086
2727
			this.noProposal = false;
3087
			if (!method.isConstructor()) continue nextMethod;
2728
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
2729
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
2730
				proposal.setDeclarationSignature(getSignature(currentType));
2731
				proposal.setDeclarationKey(currentType.computeUniqueKey());
2732
				proposal.setSignature(
2733
						createMethodSignature(
2734
								CharOperation.NO_CHAR_CHAR,
2735
								CharOperation.NO_CHAR_CHAR,
2736
								CharOperation.NO_CHAR,
2737
								CharOperation.NO_CHAR));
2738
				//proposal.setOriginalSignature(null);
2739
				//proposal.setUniqueKey(null);
2740
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2741
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2742
				//proposal.setParameterPackageNames(null);
2743
				//proposal.setParameterTypeNames(null);
2744
				//proposal.setPackageName(null);
2745
				//proposal.setTypeName(null);
2746
				proposal.setCompletion(completion);
2747
				proposal.setFlags(Flags.AccPublic);
2748
				proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
2749
				proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
2750
				proposal.setRelevance(relevance);
2751
				this.requestor.accept(proposal);
2752
				if(DEBUG) {
2753
					this.printDebug(proposal);
2754
				}
2755
			}
2756
		} else {
2757
			findConstructors(
2758
				currentType,
2759
				argTypes,
2760
				scope,
2761
				invocationSite,
2762
				true);
2763
		}
2764
	}
2765
3088
2766
	private void findClassField(
3089
			if (method.isSynthetic()) continue nextMethod;
2767
			char[] token,
2768
			TypeBinding receiverType,
2769
			Scope scope,
2770
			Binding[] missingElements,
2771
			int[] missingElementsStarts,
2772
			int[] missingElementsEnds,
2773
			boolean missingElementsHaveProblems) {
2774
3090
2775
		if (token == null) return;
3091
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
2776
3092
2777
		if (token.length <= classField.length
3093
			TypeBinding[] parameters = method.parameters;
2778
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
3094
			if(parameters.length < arguments.length)
2779
		)) {
3095
				continue nextMethod;
2780
			int relevance = computeBaseRelevance();
2781
			relevance += computeRelevanceForResolution();
2782
			relevance += computeRelevanceForInterestingProposal();
2783
			relevance += computeRelevanceForCaseMatching(token, classField);
2784
			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
2785
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
2786
			relevance += R_NON_INHERITED;
2787
3096
2788
			if (missingElements != null) {
3097
			int length = arguments.length - 1;
2789
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3098
3099
			for (int j = 0; j < length; j++) {
3100
				Expression argument = arguments[j];
3101
				TypeBinding argType = argument.resolvedType;
3102
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
3103
					continue nextMethod;
2790
			}
3104
			}
2791
3105
2792
			this.noProposal = false;
3106
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2793
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
3107
			if(expectedType != null) {
2794
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3108
				addExpectedType(expectedType, scope);
2795
				//proposal.setDeclarationSignature(null);
2796
				char[] signature =
2797
					createNonGenericTypeSignature(
2798
						CharOperation.concatWith(JAVA_LANG, '.'),
2799
						CLASS);
2800
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
2801
					// add type argument
2802
					char[] typeArgument = getTypeSignature(receiverType);
2803
					int oldLength = signature.length;
2804
					int argumentLength = typeArgument.length;
2805
					int newLength = oldLength + argumentLength + 2;
2806
					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
2807
					signature[oldLength - 1] = '<';
2808
					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
2809
					signature[newLength - 2] = '>';
2810
					signature[newLength - 1] = ';';
2811
				}
2812
				proposal.setSignature(signature);
2813
				//proposal.setDeclarationPackageName(null);
2814
				//proposal.setDeclarationTypeName(null);
2815
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
2816
				proposal.setTypeName(CLASS);
2817
				proposal.setName(classField);
2818
				if (missingElements != null) {
2819
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
2820
					for (int i = 0; i < missingElements.length; i++) {
2821
						subProposals[i] =
2822
							createRequiredTypeProposal(
2823
									missingElements[i],
2824
									missingElementsStarts[i],
2825
									missingElementsEnds[i],
2826
									relevance);
2827
					}
2828
					proposal.setRequiredProposals(subProposals);
2829
				}
2830
				proposal.setCompletion(classField);
2831
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
2832
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2833
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2834
				proposal.setRelevance(relevance);
2835
				this.requestor.accept(proposal);
2836
				if(DEBUG) {
2837
					this.printDebug(proposal);
2838
				}
2839
			}
3109
			}
2840
		}
3110
		}
2841
	}
3111
	}
3112
	private void computeExpectedTypesForMessageSend(
3113
		ReferenceBinding binding,
3114
		char[] selector,
3115
		Expression[] arguments,
3116
		ReferenceBinding receiverType,
3117
		Scope scope,
3118
		InvocationSite invocationSite,
3119
		boolean isStatic) {
2842
3120
2843
	private void findEnumConstants(
3121
		MethodBinding[] methods = binding.availableMethods();
2844
			char[] enumConstantName,
3122
		nextMethod : for (int i = 0; i < methods.length; i++) {
2845
			ReferenceBinding enumType,
3123
			MethodBinding method = methods[i];
2846
			Scope invocationScope,
2847
			ObjectVector fieldsFound,
2848
			char[][] alreadyUsedConstants,
2849
			int alreadyUsedConstantCount,
2850
			boolean needQualification) {
2851
3124
2852
		FieldBinding[] fields = enumType.fields();
3125
			if (method.isSynthetic()) continue nextMethod;
2853
3126
2854
		int enumConstantLength = enumConstantName.length;
3127
			if (method.isDefaultAbstract())	continue nextMethod;
2855
		next : for (int f = fields.length; --f >= 0;) {
2856
			FieldBinding field = fields[f];
2857
3128
2858
			if (field.isSynthetic()) continue next;
3129
			if (method.isConstructor()) continue nextMethod;
2859
3130
2860
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
3131
			if (isStatic && !method.isStatic()) continue nextMethod;
2861
3132
2862
			if (enumConstantLength > field.name.length) continue next;
3133
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
2863
3134
2864
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
3135
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
2865
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
2866
3136
2867
			char[] fieldName = field.name;
3137
			TypeBinding[] parameters = method.parameters;
3138
			if(parameters.length < arguments.length)
3139
				continue nextMethod;
2868
3140
2869
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
3141
			int length = arguments.length - 1;
2870
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
3142
3143
			for (int j = 0; j < length; j++) {
3144
				Expression argument = arguments[j];
3145
				TypeBinding argType = argument.resolvedType;
3146
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
3147
					continue nextMethod;
2871
			}
3148
			}
2872
3149
2873
			int relevance = computeBaseRelevance();
3150
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2874
			relevance += computeRelevanceForResolution();
3151
			if(expectedType != null) {
2875
			relevance += computeRelevanceForInterestingProposal(field);
3152
				addExpectedType(expectedType, scope);
2876
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
3153
			}
2877
			relevance += computeRelevanceForExpectingType(field.type);
3154
		}
2878
			relevance += computeRelevanceForEnumConstant(field.type);
3155
	}
2879
			relevance += computeRelevanceForQualification(needQualification);
3156
	private void computeExpectedTypesForMessageSendForInterface(
2880
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3157
		ReferenceBinding binding,
3158
		char[] selector,
3159
		Expression[] arguments,
3160
		ReferenceBinding receiverType,
3161
		Scope scope,
3162
		InvocationSite invocationSite,
3163
		boolean isStatic) {
2881
3164
2882
			this.noProposal = false;
3165
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
2883
			if (!needQualification) {
3166
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2884
				char[] completion = fieldName;
3167
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
3168
			int nextPosition = interfacesToVisit.length;
2885
3169
2886
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3170
			for (int i = 0; i < nextPosition; i++) {
2887
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3171
				ReferenceBinding currentType = interfacesToVisit[i];
2888
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3172
				computeExpectedTypesForMessageSend(
2889
					proposal.setSignature(getSignature(field.type));
3173
					currentType,
2890
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3174
					selector,
2891
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3175
					arguments,
2892
					proposal.setPackageName(field.type.qualifiedPackageName());
3176
					receiverType,
2893
					proposal.setTypeName(field.type.qualifiedSourceName());
3177
					scope,
2894
					proposal.setName(field.name);
3178
					invocationSite,
2895
					proposal.setCompletion(completion);
3179
					isStatic);
2896
					proposal.setFlags(field.modifiers);
3180
2897
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3181
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
2898
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3182
					int itsLength = itsInterfaces.length;
2899
					proposal.setRelevance(relevance);
3183
					if (nextPosition + itsLength >= interfacesToVisit.length)
2900
					this.requestor.accept(proposal);
3184
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2901
					if(DEBUG) {
3185
					nextInterface : for (int a = 0; a < itsLength; a++) {
2902
						this.printDebug(proposal);
3186
						ReferenceBinding next = itsInterfaces[a];
3187
						for (int b = 0; b < nextPosition; b++)
3188
							if (next == interfacesToVisit[b]) continue nextInterface;
3189
						interfacesToVisit[nextPosition++] = next;
2903
					}
3190
					}
2904
				}
3191
				}
3192
			}
3193
		}
3194
	}
2905
3195
2906
			} else {
3196
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
2907
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
3197
		this.forbbidenBindingsFilter = NONE;
2908
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
3198
		if(scope instanceof ClassScope) {
2909
3199
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
2910
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
3200
			if(typeDeclaration.superclass == astNode) {
2911
3201
				addForbiddenBindings(typeDeclaration.binding);
2912
				if (!needImport) {
3202
				return scope.parent;
2913
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3203
			}
2914
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3204
			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
2915
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
3205
			int length = superInterfaces == null ? 0 : superInterfaces.length;
2916
						proposal.setSignature(getSignature(field.type));
3206
			for (int i = 0; i < length; i++) {
2917
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3207
				if(superInterfaces[i] == astNode) {
2918
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3208
					addForbiddenBindings(typeDeclaration.binding);
2919
						proposal.setPackageName(field.type.qualifiedPackageName());
3209
					return scope.parent;
2920
						proposal.setTypeName(field.type.qualifiedSourceName());
3210
				}
2921
						proposal.setName(field.name);
3211
			}
2922
						proposal.setCompletion(completion);
3212
		} else {
2923
						proposal.setFlags(field.modifiers);
3213
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
2924
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3214
				boolean isException = false;
2925
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3215
				if (astNode instanceof CompletionOnSingleTypeReference) {
2926
						proposal.setRelevance(relevance);
3216
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
2927
						this.requestor.accept(proposal);
3217
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
2928
						if(DEBUG) {
3218
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
2929
							this.printDebug(proposal);
3219
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
3220
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
3221
				}
3222
				if (isException) {
3223
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
3224
					int length = catchArguments == null ? 0 : catchArguments.length;
3225
					for (int i = 0; i < length; i++) {
3226
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
3227
						if (caughtException != null) {
3228
							addForbiddenBindings(caughtException);
3229
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
2930
						}
3230
						}
2931
					}
3231
					}
2932
				} else {
3232
					this.forbbidenBindingsFilter = SUBTYPE;
2933
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
3233
				}
2934
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
3234
			}
2935
						int importStart = cu.types[0].declarationSourceStart;
3235
		}
2936
						int importEnd = importStart;
3236
//		else if(scope instanceof MethodScope) {
3237
//			MethodScope methodScope = (MethodScope) scope;
3238
//			if(methodScope.insideTypeAnnotation) {
3239
//				return methodScope.parent.parent;
3240
//			}
3241
//		}
3242
		return scope;
3243
	}
2937
3244
2938
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
3245
	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
2939
3246
2940
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3247
		StringBuffer completion = new StringBuffer(10);
2941
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
2942
						proposal.setSignature(getSignature(field.type));
2943
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
2944
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
2945
						proposal.setPackageName(field.type.qualifiedPackageName());
2946
						proposal.setTypeName(field.type.qualifiedSourceName());
2947
						proposal.setName(field.name);
2948
						proposal.setCompletion(completion);
2949
						proposal.setFlags(field.modifiers);
2950
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2951
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2952
						proposal.setRelevance(relevance);
2953
3248
2954
						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
3249
		if (isStatic) {
3250
			completion.append(declarationType.sourceName());
2955
3251
2956
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
3252
		} else if (declarationType == invocationType) {
2957
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
3253
			completion.append(THIS);
2958
						typeImportProposal.completionEngine = this;
2959
						char[] packageName = fieldType.qualifiedPackageName();
2960
						typeImportProposal.setDeclarationSignature(packageName);
2961
						typeImportProposal.setSignature(getSignature(fieldType));
2962
						typeImportProposal.setPackageName(packageName);
2963
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
2964
						typeImportProposal.setCompletion(typeImportCompletion);
2965
						typeImportProposal.setFlags(fieldType.modifiers);
2966
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
2967
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
2968
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
2969
						typeImportProposal.setRelevance(relevance);
2970
3254
2971
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
3255
		} else {
3256
3257
			if (!declarationType.isNestedType()) {
3258
3259
				completion.append(declarationType.sourceName());
3260
				completion.append('.');
3261
				completion.append(THIS);
3262
3263
			} else if (!declarationType.isAnonymousType()) {
3264
3265
				completion.append(declarationType.sourceName());
3266
				completion.append('.');
3267
				completion.append(THIS);
2972
3268
2973
						this.requestor.accept(proposal);
2974
						if(DEBUG) {
2975
							this.printDebug(proposal);
2976
						}
2977
					}
2978
				}
2979
			}
3269
			}
2980
		}
3270
		}
3271
3272
		return completion.toString().toCharArray();
2981
	}
3273
	}
2982
3274
2983
	private void findEnumConstantsFromExpectedTypes(
3275
	private int computeRelevanceForAnnotation(){
2984
			char[] token,
3276
		if(this.assistNodeIsAnnotation) {
2985
			Scope invocationScope,
3277
			return R_ANNOTATION;
2986
			ObjectVector fieldsFound) {
2987
		int length = this.expectedTypesPtr + 1;
2988
		for (int i = 0; i < length; i++) {
2989
			if (this.expectedTypes[i].isEnum()) {
2990
				findEnumConstants(
2991
						token,
2992
						(ReferenceBinding)this.expectedTypes[i],
2993
						invocationScope,
2994
						fieldsFound,
2995
						CharOperation.NO_CHAR_CHAR,
2996
						0,
2997
						true);
2998
			}
2999
		}
3278
		}
3279
		return 0;
3280
	}
3000
3281
3282
	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
3283
		if (this.assistNodeIsAnnotation &&
3284
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
3285
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
3286
			if(target == 0 || (target & this.targetedElement) != 0) {
3287
				return R_TARGET;
3288
			}
3289
		}
3290
		return 0;
3291
	}
3292
	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
3293
		if (this.options.camelCaseMatch) {
3294
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3295
				return R_CASE + R_EXACT_NAME;
3296
			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3297
				return R_CASE;
3298
			} else if (CharOperation.camelCaseMatch(token, proposalName)){
3299
				return R_CAMEL_CASE;
3300
			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3301
				return R_EXACT_NAME;
3302
			}
3303
		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3304
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3305
				return R_CASE + R_EXACT_NAME;
3306
			} else {
3307
				return R_CASE;
3308
			}
3309
		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3310
			return R_EXACT_NAME;
3311
		}
3312
		return 0;
3001
	}
3313
	}
3002
3314
3003
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
3315
	private int computeRelevanceForClass(){
3004
		TypeBinding expressionType = switchStatement.expression.resolvedType;
3316
		if(this.assistNodeIsClass) {
3005
		if(expressionType != null && expressionType.isEnum()) {
3317
			return R_CLASS;
3006
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
3318
		}
3319
		return 0;
3320
	}
3007
3321
3008
			CaseStatement[] cases = switchStatement.cases;
3322
	private int computeRelevanceForEnum(){
3323
		if(this.assistNodeIsEnum) {
3324
			return R_ENUM;
3325
		}
3326
		return 0;
3327
	}
3009
3328
3010
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
3329
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
3011
			int alreadyUsedConstantCount = 0;
3330
		if(this.assistNodeIsEnum &&
3012
			for (int i = 0; i < switchStatement.caseCount; i++) {
3331
				proposalType != null &&
3013
				Expression caseExpression = cases[i].constantExpression;
3332
				this.expectedTypes != null) {
3014
				if((caseExpression instanceof SingleNameReference)
3333
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3015
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
3334
				if (proposalType.isEnum() &&
3016
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
3335
						proposalType == this.expectedTypes[i]) {
3336
					return R_ENUM + R_ENUM_CONSTANT;
3017
				}
3337
				}
3338
3018
			}
3339
			}
3340
		}
3341
		return 0;
3342
	}
3019
3343
3020
			findEnumConstants(
3344
	private int computeRelevanceForException(){
3021
					enumConstantName,
3345
		if (this.assistNodeIsException) {
3022
					enumType,
3346
			return R_EXCEPTION;
3023
					null /* doesn't need invocation scope */,
3024
					new ObjectVector(),
3025
					alreadyUsedConstants,
3026
					alreadyUsedConstantCount,
3027
					false);
3028
		}
3347
		}
3348
		return 0;
3029
	}
3349
	}
3030
3350
3031
	private void findExceptionFromTryStatement(
3351
	private int computeRelevanceForException(char[] proposalName){
3032
			char[] typeName,
3033
			ReferenceBinding exceptionType,
3034
			ReferenceBinding receiverType,
3035
			SourceTypeBinding invocationType,
3036
			BlockScope scope,
3037
			ObjectVector typesFound,
3038
			boolean searchSuperClasses) {
3039
3352
3040
		if (searchSuperClasses) {
3353
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
3041
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
3354
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
3042
			if (exceptionType != javaLangThrowable) {
3355
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
3043
				ReferenceBinding superClass = exceptionType.superclass();
3356
			return R_EXCEPTION;
3044
				while(superClass != null && superClass != javaLangThrowable) {
3357
		}
3045
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
3358
		return 0;
3046
					superClass = superClass.superclass();
3359
	}
3360
3361
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
3362
		if(this.expectedTypes != null) {
3363
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3364
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
3365
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
3366
					return R_EXACT_EXPECTED_TYPE;
3047
				}
3367
				}
3048
			}
3368
			}
3369
			if(this.hasJavaLangObjectAsExpectedType) {
3370
				return R_EXPECTED_TYPE;
3371
			}
3049
		}
3372
		}
3373
		return 0;
3374
	}
3050
3375
3051
		if (typeName.length > exceptionType.sourceName.length)
3376
	private int computeRelevanceForExpectingType(TypeBinding proposalType){
3052
			return;
3377
		if(this.expectedTypes != null && proposalType != null) {
3378
			int relevance = 0;
3379
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3380
				if((this.expectedTypesFilter & SUBTYPE) != 0
3381
						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
3053
3382
3054
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
3383
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3055
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
3384
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3056
			return;
3385
						return R_EXACT_EXPECTED_TYPE;
3386
					}
3057
3387
3058
		if (this.options.checkDeprecation &&
3388
					relevance = R_EXPECTED_TYPE;
3059
				exceptionType.isViewedAsDeprecated() &&
3389
				}
3060
				!scope.isDefinedInSameUnit(exceptionType))
3390
				if((this.expectedTypesFilter & SUPERTYPE) != 0
3061
			return;
3391
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
3062
3392
3063
		if (this.options.checkVisibility) {
3393
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3064
			if (invocationType != null) {
3394
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3065
				if (receiverType != null) {
3395
						return R_EXACT_EXPECTED_TYPE;
3066
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
3396
					}
3067
				} else {
3397
3068
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
3398
					relevance = R_EXPECTED_TYPE;
3069
				}
3399
				}
3070
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
3071
				return;
3072
			}
3400
			}
3401
			return relevance;
3073
		}
3402
		}
3403
		return 0;
3404
	}
3074
3405
3075
		for (int j = typesFound.size; --j >= 0;) {
3406
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
3076
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
3407
		if (receiverType == declaringClass) return R_NON_INHERITED;
3408
		return 0;
3409
	}
3077
3410
3078
			if (exceptionType == otherType)
3411
	int computeRelevanceForInterestingProposal(){
3079
				return;
3412
		return computeRelevanceForInterestingProposal(null);
3413
	}
3080
3414
3081
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
3415
	private int computeRelevanceForInterestingProposal(Binding binding){
3416
		if(this.uninterestingBindings != null) {
3417
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
3418
				if(this.uninterestingBindings[i] == binding) {
3419
					return 0;
3420
				}
3421
			}
3422
		}
3423
		return R_INTERESTING;
3424
	}
3082
3425
3083
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
3426
	private int computeRelevanceForInterface(){
3084
					return;
3427
		if(this.assistNodeIsInterface) {
3428
			return R_INTERFACE;
3429
		}
3430
		return 0;
3431
	}
3085
3432
3086
				if (otherType.enclosingType().isInterface())
3433
	private int computeRelevanceForMissingElements(boolean hasProblems) {
3087
					if (exceptionType.enclosingType()
3434
		if (!hasProblems) {
3088
						.implementsInterface(otherType.enclosingType(), true))
3435
			return R_NO_PROBLEMS;
3089
						return;
3436
		}
3437
		return 0;
3438
	}
3439
	int computeRelevanceForQualification(boolean prefixRequired) {
3440
		if(!prefixRequired && !this.insideQualifiedReference) {
3441
			return R_UNQUALIFIED;
3442
		}
3090
3443
3091
				if (exceptionType.enclosingType().isInterface())
3444
		if(prefixRequired && this.insideQualifiedReference) {
3092
					if (otherType.enclosingType()
3445
			return R_QUALIFIED;
3093
						.implementsInterface(exceptionType.enclosingType(), true))
3094
						return;
3095
			}
3096
		}
3446
		}
3447
		return 0;
3448
	}
3097
3449
3098
		typesFound.add(exceptionType);
3450
	int computeRelevanceForResolution(){
3451
		return computeRelevanceForResolution(true);
3452
	}
3099
3453
3100
		char[] completionName = exceptionType.sourceName();
3454
	int computeRelevanceForResolution(boolean isResolved){
3455
		if (isResolved) {
3456
			return R_RESOLVED;
3457
		}
3458
		return 0;
3459
	}
3101
3460
3102
		boolean isQualified = false;
3461
	int computeRelevanceForRestrictions(int accessRuleKind) {
3462
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
3463
			return R_NON_RESTRICTED;
3464
		}
3465
		return 0;
3466
	}
3103
3467
3104
		if(!this.insideQualifiedReference) {
3468
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
3105
			isQualified = true;
3469
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
3470
			return R_NON_STATIC;
3471
		}
3472
		return 0;
3473
	}
3106
3474
3107
			char[] memberPackageName = exceptionType.qualifiedPackageName();
3475
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
3108
			char[] memberTypeName = exceptionType.sourceName();
3476
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
3109
			char[] memberEnclosingTypeNames = null;
3110
3477
3111
			ReferenceBinding enclosingType = exceptionType.enclosingType();
3478
		if (annotatedElement instanceof TypeDeclaration) {
3112
			if (enclosingType != null) {
3479
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
3113
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
3480
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
3481
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
3482
			}
3483
			return TagBits.AnnotationForType;
3484
		} else if (annotatedElement instanceof FieldDeclaration) {
3485
			if (fakeNode.isParameter) {
3486
				return TagBits.AnnotationForParameter;
3114
			}
3487
			}
3488
			return TagBits.AnnotationForField;
3489
		} else if (annotatedElement instanceof MethodDeclaration) {
3490
			return TagBits.AnnotationForMethod;
3491
		} else if (annotatedElement instanceof Argument) {
3492
			return TagBits.AnnotationForParameter;
3493
		} else if (annotatedElement instanceof ConstructorDeclaration) {
3494
			return TagBits.AnnotationForConstructor;
3495
		} else if (annotatedElement instanceof LocalDeclaration) {
3496
			return TagBits.AnnotationForLocalVariable;
3497
		} else if (annotatedElement instanceof ImportReference) {
3498
			return TagBits.AnnotationForPackage;
3499
		}
3500
		return 0;
3501
	}
3502
	private TypeBinding[] computeTypes(Expression[] arguments) {
3503
		if (arguments == null) return null;
3504
		int argsLength = arguments.length;
3505
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3506
		for (int a = argsLength; --a >= 0;) {
3507
			argTypes[a] = arguments[a].resolvedType;
3508
		}
3509
		return argTypes;
3510
	}
3115
3511
3116
			Scope currentScope = scope;
3512
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
3117
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
3513
		if (arguments == null) return null;
3514
		int argsLength = arguments.length;
3515
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3516
		for (int a = argsLength; --a >= 0;) {
3517
			TypeBinding typeBinding = arguments[a].resolvedType;
3518
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
3519
			argTypes[a] = typeBinding;
3520
		}
3521
		return argTypes;
3522
	}
3118
3523
3119
				switch (currentScope.kind) {
3524
	private void computeUninterestingBindings(ASTNode parent, Scope scope){
3525
		if(parent instanceof LocalDeclaration) {
3526
			addUninterestingBindings(((LocalDeclaration)parent).binding);
3527
		} else if (parent instanceof FieldDeclaration) {
3528
			addUninterestingBindings(((FieldDeclaration)parent).binding);
3529
		}
3530
	}
3120
3531
3121
					case Scope.METHOD_SCOPE :
3532
	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
3122
					case Scope.BLOCK_SCOPE :
3533
		char[] result = IMPORT;
3123
						BlockScope blockScope = (BlockScope) currentScope;
3534
		if (isStatic) {
3535
			result = CharOperation.concat(result, STATIC, ' ');
3536
		}
3537
		result = CharOperation.concat(result, importedElement, ' ');
3538
		if (onDemand) {
3539
			result = CharOperation.concat(result, ON_DEMAND);
3540
		}
3541
		return CharOperation.concat(result, IMPORT_END);
3542
	}
3124
3543
3125
						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
3544
	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
3545
		//// Modifiers
3546
		// flush uninteresting modifiers
3547
		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
3548
		if(insertedModifiers != ClassFileConstants.AccDefault){
3549
			ASTNode.printModifiers(insertedModifiers, completion);
3550
		}
3126
3551
3127
							if (blockScope.subscopes[j] instanceof ClassScope) {
3552
		//// Type parameters
3128
								SourceTypeBinding localType =
3129
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
3130
3553
3131
								if (localType == exceptionType) {
3554
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
3132
									isQualified = false;
3555
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
3133
									break done;
3556
			completion.append('<');
3134
								}
3557
			for (int i = 0; i < typeVariableBindings.length; i++) {
3135
							}
3558
				if(i != 0) {
3136
						}
3559
					completion.append(',');
3137
						break;
3560
					completion.append(' ');
3561
				}
3562
				createTypeVariable(typeVariableBindings[i], scope, completion);
3563
			}
3564
			completion.append('>');
3565
			completion.append(' ');
3566
		}
3138
3567
3139
					case Scope.CLASS_SCOPE :
3568
		//// Return type
3140
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
3569
		createType(method.returnType, scope, completion);
3141
						ReferenceBinding[] memberTypes = type.memberTypes();
3570
		completion.append(' ');
3142
						if (memberTypes != null) {
3143
							for (int j = 0; j < memberTypes.length; j++) {
3144
								if (memberTypes[j] == exceptionType) {
3145
									isQualified = false;
3146
									break done;
3147
								}
3148
							}
3149
						}
3150
3571
3572
		//// Selector
3573
		completion.append(method.selector);
3151
3574
3152
						break;
3575
		completion.append('(');
3153
3576
3154
					case Scope.COMPILATION_UNIT_SCOPE :
3577
		////Parameters
3155
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
3578
		TypeBinding[] parameterTypes = method.parameters;
3156
						if (types != null) {
3579
		int length = parameterTypes.length;
3157
							for (int j = 0; j < types.length; j++) {
3580
		for (int i = 0; i < length; i++) {
3158
								if (types[j] == exceptionType) {
3581
			if(i != 0) {
3159
									isQualified = false;
3582
				completion.append(',');
3160
									break done;
3583
				completion.append(' ');
3161
								}
3162
							}
3163
						}
3164
						break done;
3165
				}
3166
				currentScope = currentScope.parent;
3167
			}
3584
			}
3168
3585
			createType(parameterTypes[i], scope, completion);
3169
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
3586
			completion.append(' ');
3170
				if (memberPackageName == null || memberPackageName.length == 0)
3587
			if(parameterNames != null){
3171
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
3588
				completion.append(parameterNames[i]);
3172
						return; // ignore types from the default package from outside it
3173
			} else {
3589
			} else {
3174
				isQualified = false;
3590
				completion.append('%');
3175
			}
3176
3177
			if (isQualified) {
3178
				completionName =
3179
					CharOperation.concat(
3180
							memberPackageName,
3181
							CharOperation.concat(
3182
									memberEnclosingTypeNames,
3183
									memberTypeName,
3184
									'.'),
3185
							'.');
3186
			}
3591
			}
3187
		}
3592
		}
3188
3593
3189
		int relevance = computeBaseRelevance();
3594
		completion.append(')');
3190
		relevance += computeRelevanceForResolution();
3191
		relevance += computeRelevanceForInterestingProposal();
3192
		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
3193
		relevance += computeRelevanceForExpectingType(exceptionType);
3194
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3195
		if(!this.insideQualifiedReference) {
3196
			relevance += computeRelevanceForQualification(isQualified);
3197
		}
3198
		relevance += computeRelevanceForClass();
3199
		relevance += computeRelevanceForException();
3200
3201
		this.noProposal = false;
3202
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3203
			createTypeProposal(
3204
					exceptionType,
3205
					exceptionType.qualifiedSourceName(),
3206
					IAccessRule.K_ACCESSIBLE,
3207
					completionName,
3208
					relevance,
3209
					null,
3210
					null,
3211
					null,
3212
					false);
3213
		}
3214
	}
3215
3216
	private void findExceptionFromTryStatement(
3217
			char[] typeName,
3218
			ReferenceBinding receiverType,
3219
			SourceTypeBinding invocationType,
3220
			BlockScope scope,
3221
			ObjectVector typesFound) {
3222
3595
3223
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
3596
		//// Exceptions
3224
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
3597
		ReferenceBinding[] exceptions = method.thrownExceptions;
3225
3598
3226
			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
3599
		if (exceptions != null && exceptions.length > 0){
3600
			completion.append(' ');
3601
			completion.append(THROWS);
3602
			completion.append(' ');
3603
			for(int i = 0; i < exceptions.length ; i++){
3604
				if(i != 0) {
3605
					completion.append(' ');
3606
					completion.append(',');
3607
				}
3608
				createType(exceptions[i], scope, completion);
3609
			}
3227
		}
3610
		}
3228
	}
3611
	}
3229
	private void findExplicitConstructors(
3230
		char[] name,
3231
		ReferenceBinding currentType,
3232
		MethodScope scope,
3233
		InvocationSite invocationSite) {
3234
3235
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
3236
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
3237
3238
		// No visibility checks can be performed without the scope & invocationSite
3239
		MethodBinding[] methods = currentType.availableMethods();
3240
		if(methods != null) {
3241
			next : for (int f = methods.length; --f >= 0;) {
3242
				MethodBinding constructor = methods[f];
3243
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
3244
3612
3245
					if (constructor.isSynthetic()) continue next;
3613
	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
3614
		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
3615
		proposal.nameLookup = this.nameEnvironment.nameLookup;
3616
		proposal.completionEngine = this;
3617
		return proposal;
3618
	}
3246
3619
3247
					if (this.options.checkDeprecation &&
3620
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
3248
							constructor.isViewedAsDeprecated() &&
3621
		InternalCompletionProposal proposal = null;
3249
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3622
		if (binding instanceof ReferenceBinding) {
3250
						continue next;
3623
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
3251
3624
3252
					if (this.options.checkVisibility
3625
			char[] packageName = typeBinding.qualifiedPackageName();
3253
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
3626
			char[] typeName = typeBinding.qualifiedSourceName();
3627
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
3254
3628
3255
					TypeBinding[] parameters = constructor.parameters;
3629
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
3256
					int paramLength = parameters.length;
3630
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3631
			proposal.completionEngine = this;
3632
			proposal.setDeclarationSignature(packageName);
3633
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
3634
			proposal.setPackageName(packageName);
3635
			proposal.setTypeName(typeName);
3636
			proposal.setCompletion(fullyQualifiedName);
3637
			proposal.setFlags(typeBinding.modifiers);
3638
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3639
			proposal.setTokenRange(start - this.offset, end - this.offset);
3640
			proposal.setRelevance(relevance);
3641
		} else if (binding instanceof PackageBinding) {
3642
			PackageBinding packageBinding = (PackageBinding) binding;
3257
3643
3258
					char[][] parameterPackageNames = new char[paramLength][];
3644
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
3259
					char[][] parameterTypeNames = new char[paramLength][];
3260
					for (int i = 0; i < paramLength; i++) {
3261
						TypeBinding type = parameters[i];
3262
						parameterPackageNames[i] = type.qualifiedPackageName();
3263
						parameterTypeNames[i] = type.qualifiedSourceName();
3264
					}
3265
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3266
3645
3267
					char[] completion = CharOperation.NO_CHAR;
3646
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
3268
					if (this.source != null
3647
			proposal.setDeclarationSignature(packageName);
3269
						&& this.source.length > this.endPosition
3648
			proposal.setPackageName(packageName);
3270
						&& this.source[this.endPosition] == '(')
3649
			proposal.setCompletion(packageName);
3271
						completion = name;
3650
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3272
					else
3651
			proposal.setTokenRange(start - this.offset, end - this.offset);
3273
						completion = CharOperation.concat(name, new char[] { '(', ')' });
3652
			proposal.setRelevance(relevance);
3653
		}
3654
		return proposal;
3655
	}
3274
3656
3275
					int relevance = computeBaseRelevance();
3657
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
3276
					relevance += computeRelevanceForResolution();
3658
		switch (type.kind()) {
3277
					relevance += computeRelevanceForInterestingProposal();
3659
			case Binding.BASE_TYPE :
3278
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
3660
				completion.append(type.sourceName());
3279
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3661
				break;
3662
			case Binding.WILDCARD_TYPE :
3663
			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
3664
				WildcardBinding wildcardBinding = (WildcardBinding) type;
3665
				completion.append('?');
3666
				switch (wildcardBinding.boundKind) {
3667
					case Wildcard.EXTENDS:
3668
						completion.append(' ');
3669
						completion.append(EXTENDS);
3670
						completion.append(' ');
3671
						createType(wildcardBinding.bound, scope, completion);
3672
						if(wildcardBinding.otherBounds != null) {
3280
3673
3281
					this.noProposal = false;
3674
							int length = wildcardBinding.otherBounds.length;
3282
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
3675
							for (int i = 0; i < length; i++) {
3283
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3676
								completion.append(' ');
3284
						proposal.setDeclarationSignature(getSignature(currentType));
3677
								completion.append('&');
3285
						proposal.setSignature(getSignature(constructor));
3678
								completion.append(' ');
3286
						MethodBinding original = constructor.original();
3679
								createType(wildcardBinding.otherBounds[i], scope, completion);
3287
						if(original != constructor) {
3680
							}
3288
							proposal.setOriginalSignature(getSignature(original));
3289
						}
3290
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3291
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3292
						proposal.setParameterPackageNames(parameterPackageNames);
3293
						proposal.setParameterTypeNames(parameterTypeNames);
3294
						//proposal.setPackageName(null);
3295
						//proposal.setTypeName(null);
3296
						proposal.setName(name);
3297
						proposal.setIsContructor(true);
3298
						proposal.setCompletion(completion);
3299
						proposal.setFlags(constructor.modifiers);
3300
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3301
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3302
						proposal.setRelevance(relevance);
3303
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
3304
						this.requestor.accept(proposal);
3305
						if(DEBUG) {
3306
							this.printDebug(proposal);
3307
						}
3681
						}
3308
					}
3682
						break;
3683
					case Wildcard.SUPER:
3684
						completion.append(' ');
3685
						completion.append(SUPER);
3686
						completion.append(' ');
3687
						createType(wildcardBinding.bound, scope, completion);
3688
						break;
3689
				}
3690
				break;
3691
			case Binding.ARRAY_TYPE :
3692
				createType(type.leafComponentType(), scope, completion);
3693
				int dim = type.dimensions();
3694
				for (int i = 0; i < dim; i++) {
3695
					completion.append('[');
3696
					completion.append(']');
3697
				}
3698
				break;
3699
			case Binding.PARAMETERIZED_TYPE :
3700
				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
3701
				if (type.isMemberType()) {
3702
					createType(parameterizedType.enclosingType(), scope, completion);
3703
					completion.append('.');
3704
					completion.append(parameterizedType.sourceName);
3705
				} else {
3706
					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
3707
				}
3708
				if (parameterizedType.arguments != null) {
3709
					completion.append('<');
3710
				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
3711
				        if (i != 0) completion.append(',');
3712
				        createType(parameterizedType.arguments[i], scope, completion);
3713
				    }
3714
				    completion.append('>');
3309
				}
3715
				}
3716
				break;
3717
			default :
3718
				char[] packageName = type.qualifiedPackageName();
3719
			char[] typeName = type.qualifiedSourceName();
3720
			if(mustQualifyType(
3721
					(ReferenceBinding)type,
3722
					packageName,
3723
					scope)) {
3724
				completion.append(CharOperation.concat(packageName, typeName,'.'));
3725
			} else {
3726
				completion.append(type.sourceName());
3310
			}
3727
			}
3728
			break;
3311
		}
3729
		}
3312
	}
3730
	}
3313
	private void findConstructors(
3314
		ReferenceBinding currentType,
3315
		TypeBinding[] argTypes,
3316
		Scope scope,
3317
		InvocationSite invocationSite,
3318
		boolean forAnonymousType) {
3319
3731
3320
		// No visibility checks can be performed without the scope & invocationSite
3732
	/*
3321
		MethodBinding[] methods = currentType.availableMethods();
3733
	 * Create a completion proposal for a member type.
3322
		if(methods != null) {
3734
	 */
3323
			int minArgLength = argTypes == null ? 0 : argTypes.length;
3735
	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
3324
			next : for (int f = methods.length; --f >= 0;) {
3736
		char[] completionName = typeParameter.name;
3325
				MethodBinding constructor = methods[f];
3326
				if (constructor.isConstructor()) {
3327
3328
					if (constructor.isSynthetic()) continue next;
3329
3330
					if (this.options.checkDeprecation &&
3331
							constructor.isViewedAsDeprecated() &&
3332
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3333
						continue next;
3334
3335
					if (this.options.checkVisibility
3336
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
3337
						if(!forAnonymousType || !constructor.isProtected())
3338
							continue next;
3339
					}
3340
3341
					TypeBinding[] parameters = constructor.parameters;
3342
					int paramLength = parameters.length;
3343
					if (minArgLength > paramLength)
3344
						continue next;
3345
					for (int a = minArgLength; --a >= 0;)
3346
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
3347
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
3348
								continue next;
3349
						}
3350
3351
					char[][] parameterPackageNames = new char[paramLength][];
3352
					char[][] parameterTypeNames = new char[paramLength][];
3353
					for (int i = 0; i < paramLength; i++) {
3354
						TypeBinding type = parameters[i];
3355
						parameterPackageNames[i] = type.qualifiedPackageName();
3356
						parameterTypeNames[i] = type.qualifiedSourceName();
3357
					}
3358
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3359
3360
					char[] completion = CharOperation.NO_CHAR;
3361
					if(forAnonymousType){
3362
						int relevance = computeBaseRelevance();
3363
						relevance += computeRelevanceForResolution();
3364
						relevance += computeRelevanceForInterestingProposal();
3365
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3366
3367
						this.noProposal = false;
3368
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
3369
							InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
3370
							proposal.setDeclarationSignature(getSignature(currentType));
3371
							proposal.setDeclarationKey(currentType.computeUniqueKey());
3372
							proposal.setSignature(getSignature(constructor));
3373
							MethodBinding original = constructor.original();
3374
							if(original != constructor) {
3375
								proposal.setOriginalSignature(getSignature(original));
3376
							}
3377
							proposal.setKey(constructor.computeUniqueKey());
3378
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3379
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3380
							proposal.setParameterPackageNames(parameterPackageNames);
3381
							proposal.setParameterTypeNames(parameterTypeNames);
3382
							//proposal.setPackageName(null);
3383
							//proposal.setTypeName(null);
3384
							proposal.setCompletion(completion);
3385
							proposal.setFlags(constructor.modifiers);
3386
							proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
3387
							proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
3388
							proposal.setRelevance(relevance);
3389
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
3390
							this.requestor.accept(proposal);
3391
							if(DEBUG) {
3392
								this.printDebug(proposal);
3393
							}
3394
						}
3395
					} else {
3396
						int relevance = computeBaseRelevance();
3397
						relevance += computeRelevanceForResolution();
3398
						relevance += computeRelevanceForInterestingProposal();
3399
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3400
3401
						// Special case for completion in javadoc
3402
						if (this.assistNodeInJavadoc > 0) {
3403
							Expression receiver = null;
3404
							char[] selector = null;
3405
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
3406
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
3407
								receiver = alloc.type;
3408
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3409
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3410
								receiver = fieldRef.receiver;
3411
							}
3412
							if (receiver != null) {
3413
								StringBuffer javadocCompletion = new StringBuffer();
3414
								if (receiver.isThis()) {
3415
									selector = (((JavadocImplicitTypeReference)receiver).token);
3416
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3417
										javadocCompletion.append('#');
3418
									}
3419
								} else if (receiver instanceof JavadocSingleTypeReference) {
3420
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
3421
									selector = typeRef.token;
3422
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3423
										javadocCompletion.append(typeRef.token);
3424
										javadocCompletion.append('#');
3425
									}
3426
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
3427
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
3428
									selector = typeRef.tokens[typeRef.tokens.length-1];
3429
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3430
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
3431
										javadocCompletion.append('#');
3432
									}
3433
								}
3434
								// Append parameters types
3435
								javadocCompletion.append(selector);
3436
								javadocCompletion.append('(');
3437
								if (constructor.parameters != null) {
3438
									boolean isVarargs = constructor.isVarargs();
3439
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
3440
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
3441
										TypeBinding argTypeBinding = constructor.parameters[p];
3442
										if (isVarargs && p == ln - 1)  {
3443
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
3444
										} else {
3445
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
3446
										}
3447
									}
3448
								}
3449
								javadocCompletion.append(')');
3450
								completion = javadocCompletion.toString().toCharArray();
3451
							}
3452
						}
3453
3454
						// Create standard proposal
3455
						this.noProposal = false;
3456
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3457
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3458
							proposal.setDeclarationSignature(getSignature(currentType));
3459
							proposal.setSignature(getSignature(constructor));
3460
							MethodBinding original = constructor.original();
3461
							if(original != constructor) {
3462
								proposal.setOriginalSignature(getSignature(original));
3463
							}
3464
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3465
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3466
							proposal.setParameterPackageNames(parameterPackageNames);
3467
							proposal.setParameterTypeNames(parameterTypeNames);
3468
							//proposal.setPackageName(null);
3469
							//proposal.setTypeName(null);
3470
							proposal.setName(currentType.sourceName());
3471
							proposal.setIsContructor(true);
3472
							proposal.setCompletion(completion);
3473
							proposal.setFlags(constructor.modifiers);
3474
							int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
3475
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3476
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3477
							proposal.setRelevance(relevance);
3478
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
3479
							this.requestor.accept(proposal);
3480
							if(DEBUG) {
3481
								this.printDebug(proposal);
3482
							}
3483
						}
3484
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
3485
							char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3486
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
3487
							proposal.setDeclarationSignature(getSignature(currentType));
3488
							proposal.setSignature(getSignature(constructor));
3489
							MethodBinding original = constructor.original();
3490
							if(original != constructor) {
3491
								proposal.setOriginalSignature(getSignature(original));
3492
							}
3493
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3494
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3495
							proposal.setParameterPackageNames(parameterPackageNames);
3496
							proposal.setParameterTypeNames(parameterTypeNames);
3497
							//proposal.setPackageName(null);
3498
							//proposal.setTypeName(null);
3499
							proposal.setName(currentType.sourceName());
3500
							proposal.setIsContructor(true);
3501
							proposal.setCompletion(javadocCompletion);
3502
							proposal.setFlags(constructor.modifiers);
3503
							int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3504
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3505
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3506
							proposal.setRelevance(relevance+R_INLINE_TAG);
3507
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
3508
							this.requestor.accept(proposal);
3509
							if(DEBUG) {
3510
								this.printDebug(proposal);
3511
							}
3512
						}
3513
					}
3514
				}
3515
			}
3516
		}
3517
	}
3518
3519
	private char[][] findEnclosingTypeNames(Scope scope){
3520
		char[][] excludedNames = new char[10][];
3521
		int excludedNameCount = 0;
3522
3523
		Scope currentScope = scope;
3524
		while(currentScope != null) {
3525
			switch (currentScope.kind) {
3526
				case Scope.CLASS_SCOPE :
3527
					ClassScope classScope = (ClassScope) currentScope;
3528
3529
					TypeDeclaration typeDeclaration = classScope.referenceContext;
3530
3531
					if(excludedNameCount == excludedNames.length) {
3532
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
3533
					}
3534
					excludedNames[excludedNameCount++] = typeDeclaration.name;
3535
3536
					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
3537
					if(classTypeParameters != null) {
3538
						for (int i = 0; i < classTypeParameters.length; i++) {
3539
							TypeParameter typeParameter = classTypeParameters[i];
3540
							if(excludedNameCount == excludedNames.length) {
3541
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
3542
							}
3543
							excludedNames[excludedNameCount++] = typeParameter.name;
3544
						}
3545
					}
3546
					break;
3547
				case Scope.METHOD_SCOPE :
3548
					MethodScope methodScope = (MethodScope) currentScope;
3549
					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
3550
						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
3551
						if(methodTypeParameters != null) {
3552
							for (int i = 0; i < methodTypeParameters.length; i++) {
3553
								TypeParameter typeParameter = methodTypeParameters[i];
3554
								if(excludedNameCount == excludedNames.length) {
3555
									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
3556
								}
3557
								excludedNames[excludedNameCount++] = typeParameter.name;
3558
							}
3559
						}
3560
					}
3561
					break;
3562
			}
3563
3564
			currentScope = currentScope.parent;
3565
		}
3566
3567
		if(excludedNameCount == 0) {
3568
			return CharOperation.NO_CHAR_CHAR;
3569
		}
3570
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
3571
		return excludedNames;
3572
	}
3573
3574
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
3575
	private void findFields(
3576
		char[] fieldName,
3577
		FieldBinding[] fields,
3578
		Scope scope,
3579
		ObjectVector fieldsFound,
3580
		ObjectVector localsFound,
3581
		boolean onlyStaticFields,
3582
		ReferenceBinding receiverType,
3583
		InvocationSite invocationSite,
3584
		Scope invocationScope,
3585
		boolean implicitCall,
3586
		boolean canBePrefixed,
3587
		Binding[] missingElements,
3588
		int[] missingElementsStarts,
3589
		int[] missingElementsEnds,
3590
		boolean missingElementsHaveProblems,
3591
		char[] castedReceiver,
3592
		int receiverStart,
3593
		int receiverEnd) {
3594
3595
		ObjectVector newFieldsFound = new ObjectVector();
3596
		// Inherited fields which are hidden by subclasses are filtered out
3597
		// No visibility checks can be performed without the scope & invocationSite
3598
3599
		int fieldLength = fieldName.length;
3600
		next : for (int f = fields.length; --f >= 0;) {
3601
			FieldBinding field = fields[f];
3602
3603
			if (field.isSynthetic())	continue next;
3604
3605
			if (onlyStaticFields && !field.isStatic()) continue next;
3606
3607
			if (fieldLength > field.name.length) continue next;
3608
3609
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
3610
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
3611
3612
			if (this.options.checkDeprecation &&
3613
					field.isViewedAsDeprecated() &&
3614
					!scope.isDefinedInSameUnit(field.declaringClass))
3615
				continue next;
3616
3617
			if (this.options.checkVisibility
3618
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
3619
3620
			boolean prefixRequired = false;
3621
3622
			for (int i = fieldsFound.size; --i >= 0;) {
3623
				Object[] other = (Object[])fieldsFound.elementAt(i);
3624
				FieldBinding otherField = (FieldBinding) other[0];
3625
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
3626
				if (field == otherField && receiverType == otherReceiverType)
3627
					continue next;
3628
				if (CharOperation.equals(field.name, otherField.name, true)) {
3629
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
3630
						continue next;
3631
					if (otherField.declaringClass.isInterface()) {
3632
						if (field.declaringClass == scope.getJavaLangObject())
3633
							continue next;
3634
						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
3635
							continue next;
3636
					}
3637
					if (field.declaringClass.isInterface())
3638
						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
3639
							continue next;
3640
					if(canBePrefixed) {
3641
						prefixRequired = true;
3642
					} else {
3643
						continue next;
3644
					}
3645
				}
3646
			}
3647
3648
			for (int l = localsFound.size; --l >= 0;) {
3649
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
3650
3651
				if (CharOperation.equals(field.name, local.name, true)) {
3652
					SourceTypeBinding declarationType = scope.enclosingSourceType();
3653
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
3654
						continue next;
3655
					}
3656
					if(canBePrefixed) {
3657
						prefixRequired = true;
3658
					} else {
3659
						continue next;
3660
					}
3661
					break;
3662
				}
3663
			}
3664
3665
			newFieldsFound.add(new Object[]{field, receiverType});
3666
3667
			char[] completion = field.name;
3668
3669
			if(prefixRequired || this.options.forceImplicitQualification){
3670
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
3671
				completion = CharOperation.concat(prefix,completion,'.');
3672
			}
3673
3674
3675
			if (castedReceiver != null) {
3676
				completion = CharOperation.concat(castedReceiver, completion);
3677
			}
3678
3679
			// Special case for javadoc completion
3680
			if (this.assistNodeInJavadoc > 0) {
3681
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3682
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3683
					if (fieldRef.receiver.isThis()) {
3684
						if (fieldRef.completeInText()) {
3685
							completion = CharOperation.concat(new char[] { '#' }, field.name);
3686
						}
3687
					} else if (fieldRef.completeInText()) {
3688
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
3689
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
3690
							completion = CharOperation.concat(typeRef.token, field.name, '#');
3691
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
3692
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
3693
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
3694
						}
3695
					}
3696
				}
3697
			}
3698
3699
			int relevance = computeBaseRelevance();
3700
			relevance += computeRelevanceForResolution();
3701
			relevance += computeRelevanceForInterestingProposal(field);
3702
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3703
			relevance += computeRelevanceForExpectingType(field.type);
3704
			relevance += computeRelevanceForEnumConstant(field.type);
3705
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
3706
			relevance += computeRelevanceForQualification(prefixRequired);
3707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3708
			if (onlyStaticFields && this.insideQualifiedReference) {
3709
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
3710
			}
3711
			if (missingElements != null) {
3712
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3713
			}
3714
3715
			this.noProposal = false;
3716
			if (castedReceiver == null) {
3717
				// Standard proposal
3718
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3719
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3720
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3721
					proposal.setSignature(getSignature(field.type));
3722
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3723
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3724
					proposal.setPackageName(field.type.qualifiedPackageName());
3725
					proposal.setTypeName(field.type.qualifiedSourceName());
3726
					proposal.setName(field.name);
3727
					if (missingElements != null) {
3728
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3729
						for (int i = 0; i < missingElements.length; i++) {
3730
							subProposals[i] =
3731
								createRequiredTypeProposal(
3732
										missingElements[i],
3733
										missingElementsStarts[i],
3734
										missingElementsEnds[i],
3735
										relevance);
3736
						}
3737
						proposal.setRequiredProposals(subProposals);
3738
					}
3739
					proposal.setCompletion(completion);
3740
					proposal.setFlags(field.modifiers);
3741
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3742
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3743
					proposal.setRelevance(relevance);
3744
					this.requestor.accept(proposal);
3745
					if(DEBUG) {
3746
						this.printDebug(proposal);
3747
					}
3748
				}
3749
3750
				// Javadoc completions
3751
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
3752
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3753
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
3754
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3755
					proposal.setSignature(getSignature(field.type));
3756
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3757
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3758
					proposal.setPackageName(field.type.qualifiedPackageName());
3759
					proposal.setTypeName(field.type.qualifiedSourceName());
3760
					proposal.setName(field.name);
3761
					proposal.setCompletion(javadocCompletion);
3762
					proposal.setFlags(field.modifiers);
3763
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3764
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3765
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3766
					proposal.setRelevance(relevance+R_INLINE_TAG);
3767
					this.requestor.accept(proposal);
3768
					if(DEBUG) {
3769
						this.printDebug(proposal);
3770
					}
3771
					// Javadoc value completion for static fields
3772
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
3773
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
3774
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
3775
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
3776
						valueProposal.setSignature(getSignature(field.type));
3777
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3778
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3779
						valueProposal.setPackageName(field.type.qualifiedPackageName());
3780
						valueProposal.setTypeName(field.type.qualifiedSourceName());
3781
						valueProposal.setName(field.name);
3782
						valueProposal.setCompletion(javadocCompletion);
3783
						valueProposal.setFlags(field.modifiers);
3784
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3785
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3786
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
3787
						this.requestor.accept(valueProposal);
3788
						if(DEBUG) {
3789
							this.printDebug(valueProposal);
3790
						}
3791
					}
3792
				}
3793
			} else {
3794
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
3795
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
3796
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3797
					proposal.setSignature(getSignature(field.type));
3798
					proposal.setReceiverSignature(getSignature(receiverType));
3799
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3800
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3801
					proposal.setPackageName(field.type.qualifiedPackageName());
3802
					proposal.setTypeName(field.type.qualifiedSourceName());
3803
					proposal.setName(field.name);
3804
					if (missingElements != null) {
3805
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3806
						for (int i = 0; i < missingElements.length; i++) {
3807
							subProposals[i] =
3808
								createRequiredTypeProposal(
3809
										missingElements[i],
3810
										missingElementsStarts[i],
3811
										missingElementsEnds[i],
3812
										relevance);
3813
						}
3814
						proposal.setRequiredProposals(subProposals);
3815
					}
3816
					proposal.setCompletion(completion);
3817
					proposal.setFlags(field.modifiers);
3818
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3819
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
3820
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3821
					proposal.setRelevance(relevance);
3822
					this.requestor.accept(proposal);
3823
					if(DEBUG) {
3824
						this.printDebug(proposal);
3825
					}
3826
				}
3827
			}
3828
		}
3829
3830
		fieldsFound.addAll(newFieldsFound);
3831
	}
3832
3833
	private void findFields(
3834
		char[] fieldName,
3835
		ReferenceBinding receiverType,
3836
		Scope scope,
3837
		ObjectVector fieldsFound,
3838
		ObjectVector localsFound,
3839
		boolean onlyStaticFields,
3840
		InvocationSite invocationSite,
3841
		Scope invocationScope,
3842
		boolean implicitCall,
3843
		boolean canBePrefixed,
3844
		Binding[] missingElements,
3845
		int[] missingElementsStarts,
3846
		int[] missingElementsEnds,
3847
		boolean missingElementsHaveProblems,
3848
		char[] castedReceiver,
3849
		int receiverStart,
3850
		int receiverEnd) {
3851
3852
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
3853
		if (fieldName == null && notInJavadoc)
3854
			return;
3855
3856
		ReferenceBinding currentType = receiverType;
3857
		ReferenceBinding[] interfacesToVisit = null;
3858
		int nextPosition = 0;
3859
		do {
3860
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
3861
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
3862
				if (interfacesToVisit == null) {
3863
					interfacesToVisit = itsInterfaces;
3864
					nextPosition = interfacesToVisit.length;
3865
				} else {
3866
					int itsLength = itsInterfaces.length;
3867
					if (nextPosition + itsLength >= interfacesToVisit.length)
3868
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3869
					nextInterface : for (int a = 0; a < itsLength; a++) {
3870
						ReferenceBinding next = itsInterfaces[a];
3871
						for (int b = 0; b < nextPosition; b++)
3872
							if (next == interfacesToVisit[b]) continue nextInterface;
3873
						interfacesToVisit[nextPosition++] = next;
3874
					}
3875
				}
3876
			}
3877
3878
			FieldBinding[] fields = currentType.availableFields();
3879
			if(fields != null && fields.length > 0) {
3880
				findFields(
3881
					fieldName,
3882
					fields,
3883
					scope,
3884
					fieldsFound,
3885
					localsFound,
3886
					onlyStaticFields,
3887
					receiverType,
3888
					invocationSite,
3889
					invocationScope,
3890
					implicitCall,
3891
					canBePrefixed,
3892
					missingElements,
3893
					missingElementsStarts,
3894
					missingElementsEnds,
3895
					missingElementsHaveProblems,
3896
					castedReceiver,
3897
					receiverStart,
3898
					receiverEnd);
3899
			}
3900
			currentType = currentType.superclass();
3901
		} while (notInJavadoc && currentType != null);
3902
3903
		if (notInJavadoc && interfacesToVisit != null) {
3904
			for (int i = 0; i < nextPosition; i++) {
3905
				ReferenceBinding anInterface = interfacesToVisit[i];
3906
				FieldBinding[] fields = anInterface.availableFields();
3907
				if(fields !=  null) {
3908
					findFields(
3909
						fieldName,
3910
						fields,
3911
						scope,
3912
						fieldsFound,
3913
						localsFound,
3914
						onlyStaticFields,
3915
						receiverType,
3916
						invocationSite,
3917
						invocationScope,
3918
						implicitCall,
3919
						canBePrefixed,
3920
						missingElements,
3921
						missingElementsStarts,
3922
						missingElementsEnds,
3923
						missingElementsHaveProblems,
3924
						castedReceiver,
3925
						receiverStart,
3926
						receiverEnd);
3927
				}
3928
3737
3929
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
3738
		// Create standard type proposal
3930
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3739
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3931
					int itsLength = itsInterfaces.length;
3740
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3932
					if (nextPosition + itsLength >= interfacesToVisit.length)
3741
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3933
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3742
			proposal.completionEngine = this;
3934
					nextInterface : for (int a = 0; a < itsLength; a++) {
3743
			proposal.setSignature(getSignature(typeParameter.binding));
3935
						ReferenceBinding next = itsInterfaces[a];
3744
			proposal.setTypeName(completionName);
3936
						for (int b = 0; b < nextPosition; b++)
3745
			proposal.setCompletion(completionName);
3937
							if (next == interfacesToVisit[b]) continue nextInterface;
3746
			proposal.setFlags(typeParameter.modifiers);
3938
						interfacesToVisit[nextPosition++] = next;
3747
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3939
					}
3748
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3940
				}
3749
			proposal.setRelevance(relevance);
3750
			this.requestor.accept(proposal);
3751
			if(DEBUG) {
3752
				this.printDebug(proposal);
3941
			}
3753
			}
3942
		}
3754
		}
3943
	}
3944
3945
	protected void findFieldsAndMethodsFromAnotherReceiver(
3946
			char[] token,
3947
			TypeReference receiverType,
3948
			Scope scope,
3949
			ObjectVector fieldsFound,
3950
			ObjectVector methodsFound,
3951
			InvocationSite invocationSite,
3952
			Scope invocationScope,
3953
			boolean implicitCall,
3954
			boolean superCall,
3955
			Binding[] missingElements,
3956
			int[] missingElementsStarts,
3957
			int[] missingElementsEnds,
3958
			boolean missingElementsHaveProblems,
3959
			char[][] receiverName,
3960
			int receiverStart,
3961
			int receiverEnd) {
3962
3963
		if (receiverType.resolvedType == null) return;
3964
3965
		TypeBinding receiverTypeBinding = receiverType.resolvedType;
3966
		char[] castedReceiver = null;
3967
3968
		char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
3969
		if(this.source != null) {
3970
			int memberRefStart = this.startPosition;
3971
3755
3972
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
3756
		// Create javadoc text proposal if necessary
3973
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
3757
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3974
3758
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3975
			castedReceiver =
3759
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3976
				CharOperation.concat(
3760
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3977
					CharOperation.concat(
3761
			proposal.completionEngine = this;
3978
						'(',
3762
			proposal.setSignature(getSignature(typeParameter.binding));
3979
						CharOperation.concat(
3763
			proposal.setTypeName(javadocCompletion);
3980
							CharOperation.concat('(', castedTypeChars, ')'),
3764
			proposal.setCompletion(javadocCompletion);
3981
							receiverChars),
3765
			proposal.setFlags(typeParameter.modifiers);
3982
						')'),
3766
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3983
					dotChars);
3767
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3984
		} else {
3768
			proposal.setRelevance(relevance+R_INLINE_TAG);
3985
			castedReceiver =
3769
			this.requestor.accept(proposal);
3986
				CharOperation.concat(
3770
			if(DEBUG) {
3987
					CharOperation.concat(
3771
				this.printDebug(proposal);
3988
						'(',
3772
			}
3989
						CharOperation.concat(
3990
							CharOperation.concat('(', castedTypeChars, ')'),
3991
							CharOperation.concatWith(receiverName, '.')),
3992
						')'),
3993
					DOT);
3994
		}
3773
		}
3995
3996
		if (castedReceiver == null) return;
3997
3998
		int oldStartPosition = this.startPosition;
3999
		this.startPosition = receiverStart;
4000
4001
		findFieldsAndMethods(
4002
				token,
4003
				receiverTypeBinding,
4004
				scope,
4005
				fieldsFound,
4006
				methodsFound,
4007
				invocationSite,
4008
				invocationScope,
4009
				implicitCall,
4010
				superCall,
4011
				missingElements,
4012
				missingElementsStarts,
4013
				missingElementsEnds,
4014
				missingElementsHaveProblems,
4015
				castedReceiver,
4016
				receiverStart,
4017
				receiverEnd);
4018
4019
		this.startPosition = oldStartPosition;
4020
	}
3774
	}
4021
	protected void findFieldsAndMethods(
4022
		char[] token,
4023
		TypeBinding receiverType,
4024
		Scope scope,
4025
		ObjectVector fieldsFound,
4026
		ObjectVector methodsFound,
4027
		InvocationSite invocationSite,
4028
		Scope invocationScope,
4029
		boolean implicitCall,
4030
		boolean superCall,
4031
		Binding[] missingElements,
4032
		int[] missingElementsStarts,
4033
		int[] missingElementsEnds,
4034
		boolean missingElementsHaveProblems,
4035
		char[] castedReceiver,
4036
		int receiverStart,
4037
		int receiverEnd) {
4038
4039
		if (token == null)
4040
			return;
4041
4042
		if (receiverType.isBaseType())
4043
			return; // nothing else is possible with base types
4044
4045
		boolean proposeField =
4046
			castedReceiver == null ?
4047
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
4048
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
4049
		boolean proposeMethod =
4050
			castedReceiver == null ?
4051
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
4052
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
4053
3775
4054
		if (receiverType.isArrayType()) {
3776
	/*
4055
			if (proposeField
3777
	 * Create a completion proposal for a type.
4056
				&& token.length <= lengthField.length
3778
	 */
4057
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
3779
	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance, boolean isNotOptimum) {
4058
			)) {
4059
3780
4060
				int relevance = computeBaseRelevance();
3781
		// Create standard type proposal
4061
				relevance += computeRelevanceForResolution();
3782
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4062
				relevance += computeRelevanceForInterestingProposal();
3783
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
4063
				relevance += computeRelevanceForCaseMatching(token,lengthField);
3784
			proposal.nameLookup = this.nameEnvironment.nameLookup;
4064
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
3785
			proposal.completionEngine = this;
4065
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
3786
			proposal.setDeclarationSignature(packageName);
4066
				if (missingElements != null) {
3787
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
4067
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3788
			proposal.setPackageName(packageName);
4068
				}
3789
			proposal.setTypeName(typeName);
4069
				this.noProposal = false;
3790
			proposal.setCompletion(completionName);
4070
				if (castedReceiver == null) {
3791
			proposal.setFlags(modifiers);
4071
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
3792
			if (isNotOptimum) proposal.setAdditionalFlags(CompletionFlags.NotOptimum);
4072
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3793
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4073
						proposal.setDeclarationSignature(getSignature(receiverType));
3794
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4074
						proposal.setSignature(INT_SIGNATURE);
3795
			proposal.setRelevance(relevance);
4075
						proposal.setTypeName(INT);
3796
			proposal.setAccessibility(accessibility);
4076
						proposal.setName(lengthField);
3797
			this.requestor.accept(proposal);
4077
						if (missingElements != null) {
3798
			if(DEBUG) {
4078
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3799
				this.printDebug(proposal);
4079
							for (int i = 0; i < missingElements.length; i++) {
3800
			}
4080
								subProposals[i] =
3801
		}
4081
									createRequiredTypeProposal(
4082
											missingElements[i],
4083
											missingElementsStarts[i],
4084
											missingElementsEnds[i],
4085
											relevance);
4086
							}
4087
							proposal.setRequiredProposals(subProposals);
4088
						}
4089
						proposal.setCompletion(lengthField);
4090
						proposal.setFlags(Flags.AccPublic);
4091
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4092
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4093
						proposal.setRelevance(relevance);
4094
						this.requestor.accept(proposal);
4095
						if(DEBUG) {
4096
							this.printDebug(proposal);
4097
						}
4098
					}
4099
				} else {
4100
					char[] completion = CharOperation.concat(castedReceiver, lengthField);
4101
3802
4102
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
3803
		// Create javadoc text proposal if necessary
4103
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
3804
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
4104
						proposal.setDeclarationSignature(getSignature(receiverType));
3805
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
4105
						proposal.setSignature(INT_SIGNATURE);
3806
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
4106
						proposal.setReceiverSignature(getSignature(receiverType));
3807
			proposal.nameLookup = this.nameEnvironment.nameLookup;
4107
						proposal.setTypeName(INT);
3808
			proposal.completionEngine = this;
4108
						proposal.setName(lengthField);
3809
			proposal.setDeclarationSignature(packageName);
4109
						if (missingElements != null) {
3810
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
4110
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3811
			proposal.setPackageName(packageName);
4111
							for (int i = 0; i < missingElements.length; i++) {
3812
			proposal.setTypeName(typeName);
4112
								subProposals[i] =
3813
			proposal.setCompletion(javadocCompletion);
4113
									createRequiredTypeProposal(
3814
			proposal.setFlags(modifiers);
4114
											missingElements[i],
3815
			if (isNotOptimum) proposal.setAdditionalFlags(CompletionFlags.NotOptimum);
4115
											missingElementsStarts[i],
3816
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4116
											missingElementsEnds[i],
3817
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4117
											relevance);
3818
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4118
							}
3819
			proposal.setRelevance(relevance+R_INLINE_TAG);
4119
							proposal.setRequiredProposals(subProposals);
3820
			proposal.setAccessibility(accessibility);
4120
						}
3821
			this.requestor.accept(proposal);
4121
						proposal.setCompletion(completion);
3822
			if(DEBUG) {
4122
						proposal.setFlags(Flags.AccPublic);
3823
				this.printDebug(proposal);
4123
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4124
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
4125
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4126
						proposal.setRelevance(relevance);
4127
						this.requestor.accept(proposal);
4128
						if(DEBUG) {
4129
							this.printDebug(proposal);
4130
						}
4131
					}
4132
				}
4133
			}
3824
			}
4134
			if (proposeMethod
3825
		}
4135
				&& token.length <= cloneMethod.length
3826
	}
4136
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
4137
			) {
4138
				ReferenceBinding objectRef = scope.getJavaLangObject();
4139
4140
				int relevance = computeBaseRelevance();
4141
				relevance += computeRelevanceForResolution();
4142
				relevance += computeRelevanceForInterestingProposal();
4143
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
4144
				relevance += computeRelevanceForExpectingType(objectRef);
4145
				relevance += computeRelevanceForStatic(false, false);
4146
				relevance += computeRelevanceForQualification(false);
4147
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
4148
				if (missingElements != null) {
4149
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4150
				}
4151
				char[] completion;
4152
				if (this.source != null
4153
					&& this.source.length > this.endPosition
4154
					&& this.source[this.endPosition] == '(') {
4155
					completion = cloneMethod;
4156
					} else {
4157
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
4158
				}
4159
3827
4160
				if (castedReceiver != null) {
3828
	/*
4161
					completion = CharOperation.concat(castedReceiver, completion);
3829
	 * Create a completion proposal for a member type.
4162
				}
3830
	 */
3831
	private void createTypeProposal(
3832
			ReferenceBinding refBinding,
3833
			char[] typeName,
3834
			int accessibility,
3835
			char[] completionName,
3836
			int relevance,
3837
			Binding[] missingElements,
3838
			int[] missingElementsStarts,
3839
			int[] missingElementsEnds,
3840
			boolean missingElementsHaveProblems) {
4163
3841
4164
				this.noProposal = false;
3842
		// Create standard type proposal
4165
				if (castedReceiver == null) {
3843
		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4166
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
3844
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
4167
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3845
			proposal.nameLookup = this.nameEnvironment.nameLookup;
4168
						proposal.setDeclarationSignature(getSignature(receiverType));
3846
			proposal.completionEngine = this;
4169
						proposal.setSignature(
3847
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
4170
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
3848
			proposal.setSignature(getCompletedTypeSignature(refBinding));
4171
										createMethodSignature(
3849
			proposal.setPackageName(refBinding.qualifiedPackageName());
4172
												CharOperation.NO_CHAR_CHAR,
3850
			proposal.setTypeName(typeName);
4173
												CharOperation.NO_CHAR_CHAR,
3851
			if (missingElements != null) {
4174
												getSignature(receiverType)) :
3852
				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4175
										createMethodSignature(
3853
				for (int i = 0; i < missingElements.length; i++) {
4176
												CharOperation.NO_CHAR_CHAR,
3854
					subProposals[i] =
4177
												CharOperation.NO_CHAR_CHAR,
3855
						createRequiredTypeProposal(
4178
												CharOperation.concatWith(JAVA_LANG, '.'),
3856
								missingElements[i],
4179
												OBJECT));
3857
								missingElementsStarts[i],
4180
						//proposal.setOriginalSignature(null);
3858
								missingElementsEnds[i],
4181
						//proposal.setDeclarationPackageName(null);
3859
								relevance);
4182
						//proposal.setDeclarationTypeName(null);
4183
						//proposal.setParameterPackageNames(null);
4184
						//proposal.setParameterTypeNames(null);
4185
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4186
						proposal.setTypeName(OBJECT);
4187
						proposal.setName(cloneMethod);
4188
						if (missingElements != null) {
4189
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4190
							for (int i = 0; i < missingElements.length; i++) {
4191
								subProposals[i] =
4192
									createRequiredTypeProposal(
4193
											missingElements[i],
4194
											missingElementsStarts[i],
4195
											missingElementsEnds[i],
4196
											relevance);
4197
							}
4198
							proposal.setRequiredProposals(subProposals);
4199
						}
4200
						proposal.setCompletion(completion);
4201
						proposal.setFlags(Flags.AccPublic);
4202
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4203
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4204
						proposal.setRelevance(relevance);
4205
						this.requestor.accept(proposal);
4206
						if(DEBUG) {
4207
							this.printDebug(proposal);
4208
						}
4209
					}
4210
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
4211
				} else {
4212
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
4213
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
4214
						proposal.setDeclarationSignature(getSignature(receiverType));
4215
						proposal.setSignature(
4216
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
4217
										createMethodSignature(
4218
												CharOperation.NO_CHAR_CHAR,
4219
												CharOperation.NO_CHAR_CHAR,
4220
												getSignature(receiverType)) :
4221
										createMethodSignature(
4222
												CharOperation.NO_CHAR_CHAR,
4223
												CharOperation.NO_CHAR_CHAR,
4224
												CharOperation.concatWith(JAVA_LANG, '.'),
4225
												OBJECT));
4226
						proposal.setReceiverSignature(getSignature(receiverType));
4227
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4228
						proposal.setTypeName(OBJECT);
4229
						proposal.setName(cloneMethod);
4230
						if (missingElements != null) {
4231
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4232
							for (int i = 0; i < missingElements.length; i++) {
4233
								subProposals[i] =
4234
									createRequiredTypeProposal(
4235
											missingElements[i],
4236
											missingElementsStarts[i],
4237
											missingElementsEnds[i],
4238
											relevance);
4239
							}
4240
							proposal.setRequiredProposals(subProposals);
4241
						}
4242
						proposal.setCompletion(completion);
4243
						proposal.setFlags(Flags.AccPublic);
4244
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4245
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
4246
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4247
						proposal.setRelevance(relevance);
4248
						this.requestor.accept(proposal);
4249
						if(DEBUG) {
4250
							this.printDebug(proposal);
4251
						}
4252
					}
4253
				}
3860
				}
3861
				proposal.setRequiredProposals(subProposals);
3862
			}
3863
			proposal.setCompletion(completionName);
3864
			proposal.setFlags(refBinding.modifiers);
3865
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3866
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3867
			proposal.setRelevance(relevance);
3868
			this.requestor.accept(proposal);
3869
			if(DEBUG) {
3870
				this.printDebug(proposal);
4254
			}
3871
			}
4255
4256
			receiverType = scope.getJavaLangObject();
4257
		}
3872
		}
4258
3873
4259
		if(proposeField) {
3874
		// Create javadoc text proposal if necessary
4260
			findFields(
3875
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
4261
				token,
3876
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
4262
				(ReferenceBinding) receiverType,
3877
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
4263
				scope,
3878
			proposal.nameLookup = this.nameEnvironment.nameLookup;
4264
				fieldsFound,
3879
			proposal.completionEngine = this;
4265
				new ObjectVector(),
3880
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
4266
				false,
3881
			proposal.setSignature(getCompletedTypeSignature(refBinding));
4267
				invocationSite,
3882
			proposal.setPackageName(refBinding.qualifiedPackageName());
4268
				invocationScope,
3883
			proposal.setTypeName(typeName);
4269
				implicitCall,
3884
			proposal.setCompletion(javadocCompletion);
4270
				false,
3885
			proposal.setFlags(refBinding.modifiers);
4271
				missingElements,
3886
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4272
				missingElementsStarts,
3887
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4273
				missingElementsEnds,
3888
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4274
				missingElementsHaveProblems,
3889
			proposal.setRelevance(relevance+R_INLINE_TAG);
4275
				castedReceiver,
3890
			this.requestor.accept(proposal);
4276
				receiverStart,
3891
			if(DEBUG) {
4277
				receiverEnd);
3892
				this.printDebug(proposal);
3893
			}
4278
		}
3894
		}
3895
	}
3896
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
3897
		completion.append(typeVariable.sourceName);
4279
3898
4280
		if(proposeMethod) {
3899
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
4281
			findMethods(
3900
		    completion.append(' ');
4282
				token,
3901
		    completion.append(EXTENDS);
4283
				null,
3902
		    completion.append(' ');
4284
				null,
3903
		    createType(typeVariable.superclass, scope, completion);
4285
				(ReferenceBinding) receiverType,
3904
		}
4286
				scope,
3905
		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
4287
				methodsFound,
3906
		   if (typeVariable.firstBound != typeVariable.superclass) {
4288
				false,
3907
			   completion.append(' ');
4289
				false,
3908
			   completion.append(EXTENDS);
4290
				false,
3909
			   completion.append(' ');
4291
				invocationSite,
3910
		   }
4292
				invocationScope,
3911
		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
4293
				implicitCall,
3912
			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
4294
				superCall,
3913
				   completion.append(' ');
4295
				false,
3914
				   completion.append(EXTENDS);
4296
				missingElements,
3915
				   completion.append(' ');
4297
				missingElementsStarts,
3916
			   }
4298
				missingElementsEnds,
3917
			   createType(typeVariable.superInterfaces[i], scope, completion);
4299
				missingElementsHaveProblems,
3918
		   }
4300
				castedReceiver,
3919
		}
4301
				receiverStart,
3920
	}
4302
				receiverEnd);
3921
	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
3922
		if (type.isArrayType()) {
3923
			createType(type.leafComponentType(), scope, completion);
3924
			int dim = type.dimensions() - 1;
3925
			for (int i = 0; i < dim; i++) {
3926
				completion.append('[');
3927
				completion.append(']');
3928
			}
3929
			completion.append(VARARGS);
3930
		} else {
3931
			createType(type, scope, completion);
4303
		}
3932
		}
4304
	}
3933
	}
3934
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
3935
		MethodBinding[] methods = annotation.availableMethods();
3936
		nextAttribute: for (int i = 0; i < methods.length; i++) {
3937
			MethodBinding method = methods[i];
4305
3938
4306
	private void findFieldsAndMethodsFromFavorites(
3939
			if(!CharOperation.prefixEquals(token, method.selector, false)
4307
			char[] token,
3940
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
4308
			Scope scope,
4309
			InvocationSite invocationSite,
4310
			Scope invocationScope,
4311
			ObjectVector localsFound,
4312
			ObjectVector fieldsFound,
4313
			ObjectVector methodsFound) {
4314
4315
		ObjectVector methodsFoundFromFavorites = new ObjectVector();
4316
3941
4317
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
3942
			int length = attributesFound == null ? 0 : attributesFound.length;
3943
			for (int j = 0; j < length; j++) {
3944
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
3945
			}
4318
3946
4319
		if (favoriteBindings != null && favoriteBindings.length > 0) {
3947
			int relevance = computeBaseRelevance();
4320
			for (int i = 0; i < favoriteBindings.length; i++) {
3948
			relevance += computeRelevanceForResolution();
4321
				ImportBinding favoriteBinding = favoriteBindings[i];
3949
			relevance += computeRelevanceForInterestingProposal(method);
4322
				switch (favoriteBinding.resolvedImport.kind()) {
3950
			relevance += computeRelevanceForCaseMatching(token, method.selector);
4323
					case Binding.FIELD:
3951
			relevance += computeRelevanceForQualification(false);
4324
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
3952
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4325
						findFieldsFromFavorites(
4326
								token,
4327
								new FieldBinding[]{fieldBinding},
4328
								scope,
4329
								fieldsFound,
4330
								localsFound,
4331
								fieldBinding.declaringClass,
4332
								invocationSite,
4333
								invocationScope);
4334
						break;
4335
					case Binding.METHOD:
4336
						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
4337
						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
4338
						long range;
4339
						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
4340
							int start = (int) range, end = (int) (range >> 32);
4341
							int length = end - start + 1;
4342
							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
4343
						} else {
4344
							methods = Binding.NO_METHODS;
4345
						}
4346
						findLocalMethodsFromFavorites(
4347
								token,
4348
								methods,
4349
								scope,
4350
								methodsFound,
4351
								methodsFoundFromFavorites,
4352
								methodBinding.declaringClass,
4353
								invocationSite,
4354
								invocationScope);
4355
						break;
4356
					case Binding.TYPE:
4357
						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
4358
						if(favoriteBinding.onDemand) {
4359
							findFieldsFromFavorites(
4360
									token,
4361
									referenceBinding.availableFields(),
4362
									scope,
4363
									fieldsFound,
4364
									localsFound,
4365
									referenceBinding,
4366
									invocationSite,
4367
									invocationScope);
4368
3953
4369
							findLocalMethodsFromFavorites(
3954
			this.noProposal = false;
4370
									token,
3955
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
4371
									referenceBinding.availableMethods(),
3956
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
4372
									scope,
3957
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
4373
									methodsFound,
3958
				proposal.setSignature(getSignature(method.returnType));
4374
									methodsFoundFromFavorites,
3959
				proposal.setName(method.selector);
4375
									referenceBinding,
3960
				proposal.setCompletion(method.selector);
4376
									invocationSite,
3961
				proposal.setFlags(method.modifiers);
4377
									invocationScope);
3962
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4378
						}
3963
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4379
						break;
3964
				proposal.setRelevance(relevance);
3965
				this.requestor.accept(proposal);
3966
				if(DEBUG) {
3967
					this.printDebug(proposal);
4380
				}
3968
				}
4381
			}
3969
			}
4382
		}
3970
		}
4383
4384
		methodsFound.addAll(methodsFoundFromFavorites);
4385
	}
3971
	}
4386
3972
	private void findAnonymousType(
4387
	private boolean findFieldsAndMethodsFromMissingFieldType(
3973
		ReferenceBinding currentType,
4388
		char[] token,
3974
		TypeBinding[] argTypes,
4389
		Scope scope,
3975
		Scope scope,
4390
		InvocationSite invocationSite,
3976
		InvocationSite invocationSite) {
4391
		boolean insideTypeAnnotation) {
4392
4393
		boolean foundSomeFields = false;
4394
3977
4395
		boolean staticsOnly = false;
3978
		if (currentType.isInterface()) {
4396
		Scope currentScope = scope;
3979
			char[] completion = CharOperation.NO_CHAR;
3980
			int relevance = computeBaseRelevance();
3981
			relevance += computeRelevanceForResolution();
3982
			relevance += computeRelevanceForInterestingProposal();
3983
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4397
3984
4398
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
3985
			this.noProposal = false;
3986
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
3987
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
3988
				proposal.setDeclarationSignature(getSignature(currentType));
3989
				proposal.setDeclarationKey(currentType.computeUniqueKey());
3990
				proposal.setSignature(
3991
						createMethodSignature(
3992
								CharOperation.NO_CHAR_CHAR,
3993
								CharOperation.NO_CHAR_CHAR,
3994
								CharOperation.NO_CHAR,
3995
								CharOperation.NO_CHAR));
3996
				//proposal.setOriginalSignature(null);
3997
				//proposal.setUniqueKey(null);
3998
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3999
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4000
				//proposal.setParameterPackageNames(null);
4001
				//proposal.setParameterTypeNames(null);
4002
				//proposal.setPackageName(null);
4003
				//proposal.setTypeName(null);
4004
				proposal.setCompletion(completion);
4005
				proposal.setFlags(Flags.AccPublic);
4006
				proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
4007
				proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
4008
				proposal.setRelevance(relevance);
4009
				this.requestor.accept(proposal);
4010
				if(DEBUG) {
4011
					this.printDebug(proposal);
4012
				}
4013
			}
4014
		} else {
4015
			findConstructors(
4016
				currentType,
4017
				argTypes,
4018
				scope,
4019
				invocationSite,
4020
				true);
4021
		}
4022
	}
4023
	private void findClassField(
4024
			char[] token,
4025
			TypeBinding receiverType,
4026
			Scope scope,
4027
			Binding[] missingElements,
4028
			int[] missingElementsStarts,
4029
			int[] missingElementsEnds,
4030
			boolean missingElementsHaveProblems) {
4399
4031
4400
			switch (currentScope.kind) {
4032
		if (token == null) return;
4401
4033
4402
				case Scope.METHOD_SCOPE :
4034
		if (token.length <= classField.length
4403
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4035
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
4404
					MethodScope methodScope = (MethodScope) currentScope;
4036
		)) {
4405
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4037
			int relevance = computeBaseRelevance();
4406
					break;
4038
			relevance += computeRelevanceForResolution();
4407
				case Scope.CLASS_SCOPE :
4039
			relevance += computeRelevanceForInterestingProposal();
4408
					ClassScope classScope = (ClassScope) currentScope;
4040
			relevance += computeRelevanceForCaseMatching(token, classField);
4409
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4041
			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
4410
					if(!insideTypeAnnotation) {
4042
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
4043
			relevance += R_NON_INHERITED;
4411
4044
4412
						FieldDeclaration[] fields = classScope.referenceContext.fields;
4045
			if (missingElements != null) {
4046
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4047
			}
4413
4048
4414
						int fieldsCount = fields == null ? 0 : fields.length;
4049
			this.noProposal = false;
4415
						for (int i = 0; i < fieldsCount; i++) {
4050
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
4416
							FieldDeclaration fieldDeclaration = fields[i];
4051
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4417
							if (CharOperation.equals(fieldDeclaration.name, token)) {
4052
				//proposal.setDeclarationSignature(null);
4418
								FieldBinding fieldBinding = fieldDeclaration.binding;
4053
				char[] signature =
4419
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
4054
					createNonGenericTypeSignature(
4420
									foundSomeFields = true;
4055
						CharOperation.concatWith(JAVA_LANG, '.'),
4421
									findFieldsAndMethodsFromMissingType(
4056
						CLASS);
4422
											fieldDeclaration.type,
4057
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
4423
											currentScope,
4058
					// add type argument
4424
											invocationSite,
4059
					char[] typeArgument = getTypeSignature(receiverType);
4425
											scope);
4060
					int oldLength = signature.length;
4426
								}
4061
					int argumentLength = typeArgument.length;
4427
								break done;
4062
					int newLength = oldLength + argumentLength + 2;
4428
							}
4063
					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
4429
						}
4064
					signature[oldLength - 1] = '<';
4065
					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
4066
					signature[newLength - 2] = '>';
4067
					signature[newLength - 1] = ';';
4068
				}
4069
				proposal.setSignature(signature);
4070
				//proposal.setDeclarationPackageName(null);
4071
				//proposal.setDeclarationTypeName(null);
4072
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4073
				proposal.setTypeName(CLASS);
4074
				proposal.setName(classField);
4075
				if (missingElements != null) {
4076
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4077
					for (int i = 0; i < missingElements.length; i++) {
4078
						subProposals[i] =
4079
							createRequiredTypeProposal(
4080
									missingElements[i],
4081
									missingElementsStarts[i],
4082
									missingElementsEnds[i],
4083
									relevance);
4430
					}
4084
					}
4431
					staticsOnly |= enclosingType.isStatic();
4085
					proposal.setRequiredProposals(subProposals);
4432
					insideTypeAnnotation = false;
4086
				}
4433
					break;
4087
				proposal.setCompletion(classField);
4434
				case Scope.COMPILATION_UNIT_SCOPE :
4088
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
4435
					break done;
4089
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4090
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4091
				proposal.setRelevance(relevance);
4092
				this.requestor.accept(proposal);
4093
				if(DEBUG) {
4094
					this.printDebug(proposal);
4095
				}
4436
			}
4096
			}
4437
			currentScope = currentScope.parent;
4438
		}
4097
		}
4439
		return foundSomeFields;
4440
	}
4098
	}
4441
4099
	private void findConstructors(
4442
	private void findFieldsAndMethodsFromMissingReturnType(
4100
		ReferenceBinding currentType,
4443
		char[] token,
4101
		TypeBinding[] argTypes,
4444
		TypeBinding[] arguments,
4445
		Scope scope,
4102
		Scope scope,
4446
		InvocationSite invocationSite,
4103
		InvocationSite invocationSite,
4447
		boolean insideTypeAnnotation) {
4104
		boolean forAnonymousType) {
4448
4105
4449
		boolean staticsOnly = false;
4106
		// No visibility checks can be performed without the scope & invocationSite
4450
		Scope currentScope = scope;
4107
		MethodBinding[] methods = currentType.availableMethods();
4108
		if(methods != null) {
4109
			int minArgLength = argTypes == null ? 0 : argTypes.length;
4110
			next : for (int f = methods.length; --f >= 0;) {
4111
				MethodBinding constructor = methods[f];
4112
				if (constructor.isConstructor()) {
4451
4113
4452
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4114
					if (constructor.isSynthetic()) continue next;
4453
4115
4454
			switch (currentScope.kind) {
4116
					if (this.options.checkDeprecation &&
4117
							constructor.isViewedAsDeprecated() &&
4118
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4119
						continue next;
4455
4120
4456
				case Scope.METHOD_SCOPE :
4121
					if (this.options.checkVisibility
4457
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4122
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
4458
					MethodScope methodScope = (MethodScope) currentScope;
4123
						if(!forAnonymousType || !constructor.isProtected())
4459
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4124
							continue next;
4460
					break;
4125
					}
4461
				case Scope.CLASS_SCOPE :
4462
					ClassScope classScope = (ClassScope) currentScope;
4463
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4464
					if(!insideTypeAnnotation) {
4465
4126
4466
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
4127
					TypeBinding[] parameters = constructor.parameters;
4128
					int paramLength = parameters.length;
4129
					if (minArgLength > paramLength)
4130
						continue next;
4131
					for (int a = minArgLength; --a >= 0;)
4132
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
4133
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
4134
								continue next;
4135
						}
4467
4136
4468
						int methodsCount = methods == null ? 0 : methods.length;
4137
					char[][] parameterPackageNames = new char[paramLength][];
4469
						for (int i = 0; i < methodsCount; i++) {
4138
					char[][] parameterTypeNames = new char[paramLength][];
4470
							AbstractMethodDeclaration methodDeclaration = methods[i];
4139
					for (int i = 0; i < paramLength; i++) {
4471
							if (methodDeclaration instanceof MethodDeclaration &&
4140
						TypeBinding type = parameters[i];
4472
									CharOperation.equals(methodDeclaration.selector, token)) {
4141
						parameterPackageNames[i] = type.qualifiedPackageName();
4473
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
4142
						parameterTypeNames[i] = type.qualifiedSourceName();
4474
								MethodBinding methodBinding = method.binding;
4143
					}
4475
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
4144
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4476
									Argument[] parameters = method.arguments;
4477
									int parametersLength = parameters == null ? 0 : parameters.length;
4478
									int argumentsLength = arguments == null ? 0 : arguments.length;
4479
4145
4480
									if (parametersLength == 0) {
4146
					char[] completion = CharOperation.NO_CHAR;
4481
										if (argumentsLength == 0) {
4147
					if(forAnonymousType){
4482
											findFieldsAndMethodsFromMissingType(
4148
						int relevance = computeBaseRelevance();
4483
													method.returnType,
4149
						relevance += computeRelevanceForResolution();
4484
													currentScope,
4150
						relevance += computeRelevanceForInterestingProposal();
4485
													invocationSite,
4151
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4486
													scope);
4152
4487
											break done;
4153
						this.noProposal = false;
4488
										}
4154
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
4489
									} else {
4155
							InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
4490
										TypeBinding[] parametersBindings;
4156
							proposal.setDeclarationSignature(getSignature(currentType));
4491
										if (methodBinding == null) { // since no binding, extra types from type references
4157
							proposal.setDeclarationKey(currentType.computeUniqueKey());
4492
											parametersBindings = new TypeBinding[parametersLength];
4158
							proposal.setSignature(getSignature(constructor));
4493
											for (int j = 0; j < parametersLength; j++) {
4159
							MethodBinding original = constructor.original();
4494
												TypeBinding parameterType = parameters[j].type.resolvedType;
4160
							if(original != constructor) {
4495
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
4161
								proposal.setOriginalSignature(getSignature(original));
4496
													parameterType = parameterType.closestMatch();
4162
							}
4497
												}
4163
							proposal.setKey(constructor.computeUniqueKey());
4498
												parametersBindings[j] = parameterType;
4164
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4499
											}
4165
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4166
							proposal.setParameterPackageNames(parameterPackageNames);
4167
							proposal.setParameterTypeNames(parameterTypeNames);
4168
							//proposal.setPackageName(null);
4169
							//proposal.setTypeName(null);
4170
							proposal.setCompletion(completion);
4171
							proposal.setFlags(constructor.modifiers);
4172
							proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
4173
							proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
4174
							proposal.setRelevance(relevance);
4175
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4176
							this.requestor.accept(proposal);
4177
							if(DEBUG) {
4178
								this.printDebug(proposal);
4179
							}
4180
						}
4181
					} else {
4182
						int relevance = computeBaseRelevance();
4183
						relevance += computeRelevanceForResolution();
4184
						relevance += computeRelevanceForInterestingProposal();
4185
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4186
4187
						// Special case for completion in javadoc
4188
						if (this.assistNodeInJavadoc > 0) {
4189
							Expression receiver = null;
4190
							char[] selector = null;
4191
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
4192
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
4193
								receiver = alloc.type;
4194
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4195
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4196
								receiver = fieldRef.receiver;
4197
							}
4198
							if (receiver != null) {
4199
								StringBuffer javadocCompletion = new StringBuffer();
4200
								if (receiver.isThis()) {
4201
									selector = (((JavadocImplicitTypeReference)receiver).token);
4202
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4203
										javadocCompletion.append('#');
4204
									}
4205
								} else if (receiver instanceof JavadocSingleTypeReference) {
4206
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
4207
									selector = typeRef.token;
4208
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4209
										javadocCompletion.append(typeRef.token);
4210
										javadocCompletion.append('#');
4211
									}
4212
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
4213
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
4214
									selector = typeRef.tokens[typeRef.tokens.length-1];
4215
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4216
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
4217
										javadocCompletion.append('#');
4218
									}
4219
								}
4220
								// Append parameters types
4221
								javadocCompletion.append(selector);
4222
								javadocCompletion.append('(');
4223
								if (constructor.parameters != null) {
4224
									boolean isVarargs = constructor.isVarargs();
4225
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
4226
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
4227
										TypeBinding argTypeBinding = constructor.parameters[p];
4228
										if (isVarargs && p == ln - 1)  {
4229
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
4500
										} else {
4230
										} else {
4501
											parametersBindings = methodBinding.parameters;
4231
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
4502
										}
4503
										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
4504
											findFieldsAndMethodsFromMissingType(
4505
													method.returnType,
4506
													currentScope,
4507
													invocationSite,
4508
													scope);
4509
											break done;
4510
										}
4232
										}
4511
									}
4233
									}
4512
								}
4234
								}
4235
								javadocCompletion.append(')');
4236
								completion = javadocCompletion.toString().toCharArray();
4237
							}
4238
						}
4239
4240
						// Create standard proposal
4241
						this.noProposal = false;
4242
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4243
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4244
							proposal.setDeclarationSignature(getSignature(currentType));
4245
							proposal.setSignature(getSignature(constructor));
4246
							MethodBinding original = constructor.original();
4247
							if(original != constructor) {
4248
								proposal.setOriginalSignature(getSignature(original));
4249
							}
4250
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4251
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4252
							proposal.setParameterPackageNames(parameterPackageNames);
4253
							proposal.setParameterTypeNames(parameterTypeNames);
4254
							//proposal.setPackageName(null);
4255
							//proposal.setTypeName(null);
4256
							proposal.setName(currentType.sourceName());
4257
							proposal.setIsContructor(true);
4258
							proposal.setCompletion(completion);
4259
							proposal.setFlags(constructor.modifiers);
4260
							int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
4261
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4262
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4263
							proposal.setRelevance(relevance);
4264
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4265
							this.requestor.accept(proposal);
4266
							if(DEBUG) {
4267
								this.printDebug(proposal);
4268
							}
4269
						}
4270
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
4271
							char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
4272
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
4273
							proposal.setDeclarationSignature(getSignature(currentType));
4274
							proposal.setSignature(getSignature(constructor));
4275
							MethodBinding original = constructor.original();
4276
							if(original != constructor) {
4277
								proposal.setOriginalSignature(getSignature(original));
4278
							}
4279
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4280
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4281
							proposal.setParameterPackageNames(parameterPackageNames);
4282
							proposal.setParameterTypeNames(parameterTypeNames);
4283
							//proposal.setPackageName(null);
4284
							//proposal.setTypeName(null);
4285
							proposal.setName(currentType.sourceName());
4286
							proposal.setIsContructor(true);
4287
							proposal.setCompletion(javadocCompletion);
4288
							proposal.setFlags(constructor.modifiers);
4289
							int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4290
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4291
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4292
							proposal.setRelevance(relevance+R_INLINE_TAG);
4293
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4294
							this.requestor.accept(proposal);
4295
							if(DEBUG) {
4296
								this.printDebug(proposal);
4297
							}
4298
						}
4299
					}
4300
				}
4301
			}
4302
		}
4303
	}
4304
	private char[][] findEnclosingTypeNames(Scope scope){
4305
		char[][] excludedNames = new char[10][];
4306
		int excludedNameCount = 0;
4307
4308
		Scope currentScope = scope;
4309
		while(currentScope != null) {
4310
			switch (currentScope.kind) {
4311
				case Scope.CLASS_SCOPE :
4312
					ClassScope classScope = (ClassScope) currentScope;
4313
4314
					TypeDeclaration typeDeclaration = classScope.referenceContext;
4315
4316
					if(excludedNameCount == excludedNames.length) {
4317
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4318
					}
4319
					excludedNames[excludedNameCount++] = typeDeclaration.name;
4513
4320
4321
					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
4322
					if(classTypeParameters != null) {
4323
						for (int i = 0; i < classTypeParameters.length; i++) {
4324
							TypeParameter typeParameter = classTypeParameters[i];
4325
							if(excludedNameCount == excludedNames.length) {
4326
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4327
							}
4328
							excludedNames[excludedNameCount++] = typeParameter.name;
4329
						}
4330
					}
4331
					break;
4332
				case Scope.METHOD_SCOPE :
4333
					MethodScope methodScope = (MethodScope) currentScope;
4334
					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
4335
						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
4336
						if(methodTypeParameters != null) {
4337
							for (int i = 0; i < methodTypeParameters.length; i++) {
4338
								TypeParameter typeParameter = methodTypeParameters[i];
4339
								if(excludedNameCount == excludedNames.length) {
4340
									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4341
								}
4342
								excludedNames[excludedNameCount++] = typeParameter.name;
4514
							}
4343
							}
4515
						}
4344
						}
4516
					}
4345
					}
4517
					staticsOnly |= enclosingType.isStatic();
4518
					insideTypeAnnotation = false;
4519
					break;
4346
					break;
4520
				case Scope.COMPILATION_UNIT_SCOPE :
4521
					break done;
4522
			}
4347
			}
4348
4523
			currentScope = currentScope.parent;
4349
			currentScope = currentScope.parent;
4524
		}
4350
		}
4525
	}
4526
4527
	private void findFieldsAndMethodsFromMissingType(
4528
			TypeReference typeRef,
4529
			final Scope scope,
4530
			final InvocationSite invocationSite,
4531
			final Scope invocationScope) {
4532
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
4533
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
4534
			new MissingTypesGuesser.GuessedTypeRequestor() {
4535
				public void accept(
4536
						TypeBinding guessedType,
4537
						Binding[] missingElements,
4538
						int[] missingElementsStarts,
4539
						int[] missingElementsEnds,
4540
						boolean hasProblems) {
4541
					findFieldsAndMethods(
4542
						CompletionEngine.this.completionToken,
4543
						guessedType,
4544
						scope,
4545
						new ObjectVector(),
4546
						new ObjectVector(),
4547
						invocationSite,
4548
						invocationScope,
4549
						false,
4550
						false,
4551
						missingElements,
4552
						missingElementsStarts,
4553
						missingElementsEnds,
4554
						hasProblems,
4555
						null,
4556
						-1,
4557
						-1);
4558
4351
4559
				}
4352
		if(excludedNameCount == 0) {
4560
			};
4353
			return CharOperation.NO_CHAR_CHAR;
4561
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
4354
		}
4355
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
4356
		return excludedNames;
4562
	}
4357
	}
4563
4358
	private void findEnumConstants(
4564
	private void findFieldsFromFavorites(
4359
			char[] enumConstantName,
4565
			char[] fieldName,
4360
			ReferenceBinding enumType,
4566
			FieldBinding[] fields,
4361
			Scope invocationScope,
4567
			Scope scope,
4568
			ObjectVector fieldsFound,
4362
			ObjectVector fieldsFound,
4569
			ObjectVector localsFound,
4363
			char[][] alreadyUsedConstants,
4570
			ReferenceBinding receiverType,
4364
			int alreadyUsedConstantCount,
4571
			InvocationSite invocationSite,
4365
			boolean needQualification) {
4572
			Scope invocationScope) {
4573
4366
4574
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
4367
		FieldBinding[] fields = enumType.fields();
4575
4368
4576
		int fieldLength = fieldName.length;
4369
		int enumConstantLength = enumConstantName.length;
4577
		next : for (int f = fields.length; --f >= 0;) {
4370
		next : for (int f = fields.length; --f >= 0;) {
4578
			FieldBinding field = fields[f];
4371
			FieldBinding field = fields[f];
4579
4372
4580
			if (field.isSynthetic())	continue next;
4373
			if (field.isSynthetic()) continue next;
4581
4374
4582
			// only static fields must be proposed
4375
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
4583
			if (!field.isStatic()) continue next;
4584
4376
4585
			if (fieldLength > field.name.length) continue next;
4377
			if (enumConstantLength > field.name.length) continue next;
4586
4378
4587
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4379
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
4588
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4380
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
4381
4382
			char[] fieldName = field.name;
4383
4384
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
4385
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
4386
			}
4387
4388
			int relevance = computeBaseRelevance();
4389
			relevance += computeRelevanceForResolution();
4390
			relevance += computeRelevanceForInterestingProposal(field);
4391
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
4392
			relevance += computeRelevanceForExpectingType(field.type);
4393
			relevance += computeRelevanceForEnumConstant(field.type);
4394
			relevance += computeRelevanceForQualification(needQualification);
4395
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4396
4397
			this.noProposal = false;
4398
			if (!needQualification) {
4399
				char[] completion = fieldName;
4400
4401
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4402
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4403
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4404
					proposal.setSignature(getSignature(field.type));
4405
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4406
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4407
					proposal.setPackageName(field.type.qualifiedPackageName());
4408
					proposal.setTypeName(field.type.qualifiedSourceName());
4409
					proposal.setName(field.name);
4410
					proposal.setCompletion(completion);
4411
					proposal.setFlags(field.modifiers);
4412
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4413
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4414
					proposal.setRelevance(relevance);
4415
					this.requestor.accept(proposal);
4416
					if(DEBUG) {
4417
						this.printDebug(proposal);
4418
					}
4419
				}
4420
4421
			} else {
4422
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
4423
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
4424
4425
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
4426
4427
				if (!needImport) {
4428
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4429
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4430
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4431
						proposal.setSignature(getSignature(field.type));
4432
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4433
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4434
						proposal.setPackageName(field.type.qualifiedPackageName());
4435
						proposal.setTypeName(field.type.qualifiedSourceName());
4436
						proposal.setName(field.name);
4437
						proposal.setCompletion(completion);
4438
						proposal.setFlags(field.modifiers);
4439
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4440
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4441
						proposal.setRelevance(relevance);
4442
						this.requestor.accept(proposal);
4443
						if(DEBUG) {
4444
							this.printDebug(proposal);
4445
						}
4446
					}
4447
				} else {
4448
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4449
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4450
						int importStart = cu.types[0].declarationSourceStart;
4451
						int importEnd = importStart;
4452
4453
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
4454
4455
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4456
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4457
						proposal.setSignature(getSignature(field.type));
4458
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4459
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4460
						proposal.setPackageName(field.type.qualifiedPackageName());
4461
						proposal.setTypeName(field.type.qualifiedSourceName());
4462
						proposal.setName(field.name);
4463
						proposal.setCompletion(completion);
4464
						proposal.setFlags(field.modifiers);
4465
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4466
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4467
						proposal.setRelevance(relevance);
4468
4469
						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
4470
4471
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4472
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4473
						typeImportProposal.completionEngine = this;
4474
						char[] packageName = fieldType.qualifiedPackageName();
4475
						typeImportProposal.setDeclarationSignature(packageName);
4476
						typeImportProposal.setSignature(getSignature(fieldType));
4477
						typeImportProposal.setPackageName(packageName);
4478
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
4479
						typeImportProposal.setCompletion(typeImportCompletion);
4480
						typeImportProposal.setFlags(fieldType.modifiers);
4481
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4482
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4483
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4484
						typeImportProposal.setRelevance(relevance);
4485
4486
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4487
4488
						this.requestor.accept(proposal);
4489
						if(DEBUG) {
4490
							this.printDebug(proposal);
4491
						}
4492
					}
4493
				}
4494
			}
4495
		}
4496
	}
4497
	private void findEnumConstantsFromExpectedTypes(
4498
			char[] token,
4499
			Scope invocationScope,
4500
			ObjectVector fieldsFound) {
4501
		int length = this.expectedTypesPtr + 1;
4502
		for (int i = 0; i < length; i++) {
4503
			if (this.expectedTypes[i].isEnum()) {
4504
				findEnumConstants(
4505
						token,
4506
						(ReferenceBinding)this.expectedTypes[i],
4507
						invocationScope,
4508
						fieldsFound,
4509
						CharOperation.NO_CHAR_CHAR,
4510
						0,
4511
						true);
4512
			}
4513
		}
4514
4515
	}
4516
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
4517
		TypeBinding expressionType = switchStatement.expression.resolvedType;
4518
		if(expressionType != null && expressionType.isEnum()) {
4519
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
4589
4520
4590
			if (this.options.checkDeprecation &&
4521
			CaseStatement[] cases = switchStatement.cases;
4591
					field.isViewedAsDeprecated() &&
4592
					!scope.isDefinedInSameUnit(field.declaringClass))
4593
				continue next;
4594
4522
4595
			if (this.options.checkVisibility
4523
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
4596
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4524
			int alreadyUsedConstantCount = 0;
4525
			for (int i = 0; i < switchStatement.caseCount; i++) {
4526
				Expression caseExpression = cases[i].constantExpression;
4527
				if((caseExpression instanceof SingleNameReference)
4528
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
4529
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
4530
				}
4531
			}
4597
4532
4598
			for (int i = fieldsFound.size; --i >= 0;) {
4533
			findEnumConstants(
4599
				Object[] other = (Object[])fieldsFound.elementAt(i);
4534
					enumConstantName,
4600
				FieldBinding otherField = (FieldBinding) other[0];
4535
					enumType,
4536
					null /* doesn't need invocation scope */,
4537
					new ObjectVector(),
4538
					alreadyUsedConstants,
4539
					alreadyUsedConstantCount,
4540
					false);
4541
		}
4542
	}
4543
	private void findExceptionFromTryStatement(
4544
			char[] typeName,
4545
			ReferenceBinding exceptionType,
4546
			ReferenceBinding receiverType,
4547
			SourceTypeBinding invocationType,
4548
			BlockScope scope,
4549
			ObjectVector typesFound,
4550
			boolean searchSuperClasses) {
4601
4551
4602
				if (field == otherField) continue next;
4552
		if (searchSuperClasses) {
4553
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
4554
			if (exceptionType != javaLangThrowable) {
4555
				ReferenceBinding superClass = exceptionType.superclass();
4556
				while(superClass != null && superClass != javaLangThrowable) {
4557
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
4558
					superClass = superClass.superclass();
4559
				}
4603
			}
4560
			}
4561
		}
4604
4562
4605
			fieldsFound.add(new Object[]{field, receiverType});
4563
		if (typeName.length > exceptionType.sourceName.length)
4564
			return;
4606
4565
4607
			int relevance = computeBaseRelevance();
4566
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
4608
			relevance += computeRelevanceForResolution();
4567
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
4609
			relevance += computeRelevanceForInterestingProposal(field);
4568
			return;
4610
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4611
			relevance += computeRelevanceForExpectingType(field.type);
4612
			relevance += computeRelevanceForEnumConstant(field.type);
4613
			relevance += computeRelevanceForStatic(true, true);
4614
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4615
4569
4616
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4570
		if (this.options.checkDeprecation &&
4617
			int importStart = cu.types[0].declarationSourceStart;
4571
				exceptionType.isViewedAsDeprecated() &&
4618
			int importEnd = importStart;
4572
				!scope.isDefinedInSameUnit(exceptionType))
4573
			return;
4619
4574
4620
			this.noProposal = false;
4575
		if (this.options.checkVisibility) {
4576
			if (invocationType != null) {
4577
				if (receiverType != null) {
4578
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
4579
				} else {
4580
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
4581
				}
4582
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
4583
				return;
4584
			}
4585
		}
4621
4586
4622
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
4587
		for (int j = typesFound.size; --j >= 0;) {
4623
					!this.options.suggestStaticImport) {
4588
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
4624
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4625
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
4626
4589
4627
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4590
			if (exceptionType == otherType)
4628
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4591
				return;
4629
					proposal.setSignature(getSignature(field.type));
4630
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4631
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4632
					proposal.setPackageName(field.type.qualifiedPackageName());
4633
					proposal.setTypeName(field.type.qualifiedSourceName());
4634
					proposal.setName(field.name);
4635
					proposal.setCompletion(completion);
4636
					proposal.setFlags(field.modifiers);
4637
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4638
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4639
					proposal.setRelevance(relevance);
4640
4592
4641
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
4593
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
4642
4594
4643
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4595
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
4644
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4596
					return;
4645
					typeImportProposal.completionEngine = this;
4646
					char[] packageName = receiverType.qualifiedPackageName();
4647
					typeImportProposal.setDeclarationSignature(packageName);
4648
					typeImportProposal.setSignature(getSignature(receiverType));
4649
					typeImportProposal.setPackageName(packageName);
4650
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
4651
					typeImportProposal.setCompletion(typeImportCompletion);
4652
					typeImportProposal.setFlags(receiverType.modifiers);
4653
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4654
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4655
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4656
					typeImportProposal.setRelevance(relevance);
4657
4597
4658
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4598
				if (otherType.enclosingType().isInterface())
4599
					if (exceptionType.enclosingType()
4600
						.implementsInterface(otherType.enclosingType(), true))
4601
						return;
4659
4602
4660
					this.requestor.accept(proposal);
4603
				if (exceptionType.enclosingType().isInterface())
4661
					if(DEBUG) {
4604
					if (otherType.enclosingType()
4662
						this.printDebug(proposal);
4605
						.implementsInterface(exceptionType.enclosingType(), true))
4663
					}
4606
						return;
4664
				}
4607
			}
4665
			} else {
4608
		}
4666
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
4667
					char[] completion = field.name;
4668
4609
4669
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4610
		typesFound.add(exceptionType);
4670
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4671
					proposal.setSignature(getSignature(field.type));
4672
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4673
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4674
					proposal.setPackageName(field.type.qualifiedPackageName());
4675
					proposal.setTypeName(field.type.qualifiedSourceName());
4676
					proposal.setName(field.name);
4677
					proposal.setCompletion(completion);
4678
					proposal.setFlags(field.modifiers);
4679
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4680
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4681
					proposal.setRelevance(relevance);
4682
4611
4683
					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
4612
		char[] completionName = exceptionType.sourceName();
4684
4613
4685
					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
4614
		boolean isQualified = false;
4686
					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
4687
					fieldImportProposal.setSignature(getSignature(field.type));
4688
					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4689
					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4690
					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
4691
					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
4692
					fieldImportProposal.setName(field.name);
4693
					fieldImportProposal.setCompletion(fieldImportCompletion);
4694
					fieldImportProposal.setFlags(field.modifiers);
4695
					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
4696
					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4697
					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4698
					fieldImportProposal.setRelevance(relevance);
4699
4615
4700
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
4616
		if(!this.insideQualifiedReference) {
4617
			isQualified = true;
4701
4618
4702
					this.requestor.accept(proposal);
4619
			char[] memberPackageName = exceptionType.qualifiedPackageName();
4703
					if(DEBUG) {
4620
			char[] memberTypeName = exceptionType.sourceName();
4704
						this.printDebug(proposal);
4621
			char[] memberEnclosingTypeNames = null;
4705
					}
4706
				}
4707
			}
4708
		}
4709
	}
4710
4622
4711
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
4623
			ReferenceBinding enclosingType = exceptionType.enclosingType();
4712
		char[][] tokens = importReference.tokens;
4624
			if (enclosingType != null) {
4625
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
4626
			}
4713
4627
4714
		char[] importName = CharOperation.concatWith(tokens, '.');
4628
			Scope currentScope = scope;
4629
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
4715
4630
4716
		if (importName.length == 0)
4631
				switch (currentScope.kind) {
4717
			return;
4718
4632
4719
		char[] lastToken = tokens[tokens.length - 1];
4633
					case Scope.METHOD_SCOPE :
4720
		if(lastToken != null && lastToken.length == 0)
4634
					case Scope.BLOCK_SCOPE :
4721
			importName = CharOperation.concat(importName, new char[]{'.'});
4635
						BlockScope blockScope = (BlockScope) currentScope;
4722
4636
4723
		this.resolvingImports = true;
4637
						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
4724
		this.resolvingStaticImports = importReference.isStatic();
4725
4638
4726
		this.completionToken =  lastToken;
4639
							if (blockScope.subscopes[j] instanceof ClassScope) {
4727
		this.qualifiedCompletionToken = importName;
4640
								SourceTypeBinding localType =
4641
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
4728
4642
4729
		// want to replace the existing .*;
4643
								if (localType == exceptionType) {
4730
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
4644
									isQualified = false;
4731
			int oldStart = this.startPosition;
4645
									break done;
4732
			int oldEnd = this.endPosition;
4646
								}
4733
			setSourceRange(
4647
							}
4734
				importReference.sourceStart,
4648
						}
4735
				importReference.declarationSourceEnd);
4649
						break;
4736
			this.nameEnvironment.findPackages(importName, this);
4737
			setSourceRange(
4738
				oldStart,
4739
				oldEnd - 1,
4740
				false);
4741
		}
4742
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4743
			this.nameEnvironment.findTypes(
4744
					importName,
4745
					findMembers,
4746
					this.options.camelCaseMatch,
4747
					IJavaSearchConstants.TYPE,
4748
					this);
4749
			acceptTypes(null);
4750
		}
4751
	}
4752
4650
4753
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
4651
					case Scope.CLASS_SCOPE :
4754
		ReferenceBinding[] memberTypes = ref.memberTypes();
4652
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
4653
						ReferenceBinding[] memberTypes = type.memberTypes();
4654
						if (memberTypes != null) {
4655
							for (int j = 0; j < memberTypes.length; j++) {
4656
								if (memberTypes[j] == exceptionType) {
4657
									isQualified = false;
4658
									break done;
4659
								}
4660
							}
4661
						}
4755
4662
4756
		int typeLength = typeName.length;
4757
		next : for (int m = memberTypes.length; --m >= 0;) {
4758
			ReferenceBinding memberType = memberTypes[m];
4759
			//		if (!wantClasses && memberType.isClass()) continue next;
4760
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
4761
4663
4762
			if (onlyStatic && !memberType.isStatic())
4664
						break;
4763
				continue next;
4764
4665
4765
			if (typeLength > memberType.sourceName.length)
4666
					case Scope.COMPILATION_UNIT_SCOPE :
4766
				continue next;
4667
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
4668
						if (types != null) {
4669
							for (int j = 0; j < types.length; j++) {
4670
								if (types[j] == exceptionType) {
4671
									isQualified = false;
4672
									break done;
4673
								}
4674
							}
4675
						}
4676
						break done;
4677
				}
4678
				currentScope = currentScope.parent;
4679
			}
4767
4680
4768
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
4681
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
4769
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
4682
				if (memberPackageName == null || memberPackageName.length == 0)
4770
				continue next;
4683
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
4684
						return; // ignore types from the default package from outside it
4685
			} else {
4686
				isQualified = false;
4687
			}
4771
4688
4772
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
4689
			if (isQualified) {
4690
				completionName =
4691
					CharOperation.concat(
4692
							memberPackageName,
4693
							CharOperation.concat(
4694
									memberEnclosingTypeNames,
4695
									memberTypeName,
4696
									'.'),
4697
							'.');
4698
			}
4699
		}
4773
4700
4774
			if (this.options.checkVisibility
4701
		int relevance = computeBaseRelevance();
4775
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
4702
		relevance += computeRelevanceForResolution();
4776
				continue next;
4703
		relevance += computeRelevanceForInterestingProposal();
4704
		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
4705
		relevance += computeRelevanceForExpectingType(exceptionType);
4706
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4707
		if(!this.insideQualifiedReference) {
4708
			relevance += computeRelevanceForQualification(isQualified);
4709
		}
4710
		relevance += computeRelevanceForClass();
4711
		relevance += computeRelevanceForException();
4777
4712
4778
			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
4713
		this.noProposal = false;
4714
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4715
			createTypeProposal(
4716
					exceptionType,
4717
					exceptionType.qualifiedSourceName(),
4718
					IAccessRule.K_ACCESSIBLE,
4719
					completionName,
4720
					relevance,
4721
					null,
4722
					null,
4723
					null,
4724
					false);
4725
		}
4726
	}
4727
	private void findExceptionFromTryStatement(
4728
			char[] typeName,
4729
			ReferenceBinding receiverType,
4730
			SourceTypeBinding invocationType,
4731
			BlockScope scope,
4732
			ObjectVector typesFound) {
4779
4733
4780
			int relevance = computeBaseRelevance();
4734
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
4781
			relevance += computeRelevanceForResolution();
4735
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
4782
			relevance += computeRelevanceForInterestingProposal();
4783
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
4784
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4785
4736
4786
			if (memberType.isClass()) {
4737
			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
4787
				relevance += computeRelevanceForClass();
4788
			} else if(memberType.isEnum()) {
4789
				relevance += computeRelevanceForEnum();
4790
			} else if (memberType.isInterface()) {
4791
				relevance += computeRelevanceForInterface();
4792
			}
4793
			this.noProposal = false;
4794
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4795
				createTypeProposal(
4796
						memberType,
4797
						memberType.qualifiedSourceName(),
4798
						IAccessRule.K_ACCESSIBLE,
4799
						completionName,
4800
						relevance,
4801
						null,
4802
						null,
4803
						null,
4804
						false);
4805
			}
4806
		}
4738
		}
4807
	}
4739
	}
4740
	private void findExplicitConstructors(
4741
		char[] name,
4742
		ReferenceBinding currentType,
4743
		MethodScope scope,
4744
		InvocationSite invocationSite) {
4808
4745
4809
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
4746
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
4810
		FieldBinding[] fields = ref.availableFields();
4747
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
4811
4812
		int fieldLength = fieldName.length;
4813
		next : for (int m = fields.length; --m >= 0;) {
4814
			FieldBinding field = fields[m];
4815
4748
4816
			if (fieldLength > field.name.length)
4749
		// No visibility checks can be performed without the scope & invocationSite
4817
				continue next;
4750
		MethodBinding[] methods = currentType.availableMethods();
4751
		if(methods != null) {
4752
			next : for (int f = methods.length; --f >= 0;) {
4753
				MethodBinding constructor = methods[f];
4754
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
4818
4755
4819
			if (field.isSynthetic())
4756
					if (constructor.isSynthetic()) continue next;
4820
				continue next;
4821
4757
4822
			if (!field.isStatic())
4758
					if (this.options.checkDeprecation &&
4823
				continue next;
4759
							constructor.isViewedAsDeprecated() &&
4760
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4761
						continue next;
4824
4762
4825
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
4763
					if (this.options.checkVisibility
4826
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
4764
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
4827
				continue next;
4828
4765
4829
			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
4766
					TypeBinding[] parameters = constructor.parameters;
4767
					int paramLength = parameters.length;
4830
4768
4831
			if (this.options.checkVisibility
4769
					char[][] parameterPackageNames = new char[paramLength][];
4832
				&& !field.canBeSeenBy(this.unitScope.fPackage))
4770
					char[][] parameterTypeNames = new char[paramLength][];
4833
				continue next;
4771
					for (int i = 0; i < paramLength; i++) {
4772
						TypeBinding type = parameters[i];
4773
						parameterPackageNames[i] = type.qualifiedPackageName();
4774
						parameterTypeNames[i] = type.qualifiedSourceName();
4775
					}
4776
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4834
4777
4835
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
4778
					char[] completion = CharOperation.NO_CHAR;
4779
					if (this.source != null
4780
						&& this.source.length > this.endPosition
4781
						&& this.source[this.endPosition] == '(')
4782
						completion = name;
4783
					else
4784
						completion = CharOperation.concat(name, new char[] { '(', ')' });
4836
4785
4837
			int relevance = computeBaseRelevance();
4786
					int relevance = computeBaseRelevance();
4838
			relevance += computeRelevanceForResolution();
4787
					relevance += computeRelevanceForResolution();
4839
			relevance += computeRelevanceForInterestingProposal();
4788
					relevance += computeRelevanceForInterestingProposal();
4840
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4789
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
4841
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4790
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4842
4791
4843
			this.noProposal = false;
4792
					this.noProposal = false;
4844
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4793
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
4845
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4794
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4846
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
4795
						proposal.setDeclarationSignature(getSignature(currentType));
4847
				proposal.setSignature(getSignature(field.type));
4796
						proposal.setSignature(getSignature(constructor));
4848
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4797
						MethodBinding original = constructor.original();
4849
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4798
						if(original != constructor) {
4850
				proposal.setPackageName(field.type.qualifiedPackageName());
4799
							proposal.setOriginalSignature(getSignature(original));
4851
				proposal.setTypeName(field.type.qualifiedSourceName());
4800
						}
4852
				proposal.setName(field.name);
4801
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4853
				proposal.setCompletion(completionName);
4802
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4854
				proposal.setFlags(field.modifiers);
4803
						proposal.setParameterPackageNames(parameterPackageNames);
4855
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4804
						proposal.setParameterTypeNames(parameterTypeNames);
4856
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4805
						//proposal.setPackageName(null);
4857
				proposal.setRelevance(relevance);
4806
						//proposal.setTypeName(null);
4858
				this.requestor.accept(proposal);
4807
						proposal.setName(name);
4859
				if(DEBUG) {
4808
						proposal.setIsContructor(true);
4860
					this.printDebug(proposal);
4809
						proposal.setCompletion(completion);
4810
						proposal.setFlags(constructor.modifiers);
4811
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4812
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4813
						proposal.setRelevance(relevance);
4814
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
4815
						this.requestor.accept(proposal);
4816
						if(DEBUG) {
4817
							this.printDebug(proposal);
4818
						}
4819
					}
4861
				}
4820
				}
4862
			}
4821
			}
4863
		}
4822
		}
4864
	}
4823
	}
4824
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
4825
	private void findFields(
4826
		char[] fieldName,
4827
		FieldBinding[] fields,
4828
		Scope scope,
4829
		ObjectVector fieldsFound,
4830
		ObjectVector localsFound,
4831
		boolean onlyStaticFields,
4832
		ReferenceBinding receiverType,
4833
		InvocationSite invocationSite,
4834
		Scope invocationScope,
4835
		boolean implicitCall,
4836
		boolean canBePrefixed,
4837
		Binding[] missingElements,
4838
		int[] missingElementsStarts,
4839
		int[] missingElementsEnds,
4840
		boolean missingElementsHaveProblems,
4841
		char[] castedReceiver,
4842
		int receiverStart,
4843
		int receiverEnd) {
4865
4844
4866
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
4845
		ObjectVector newFieldsFound = new ObjectVector();
4867
		MethodBinding[] methods = ref.availableMethods();
4846
		// Inherited fields which are hidden by subclasses are filtered out
4847
		// No visibility checks can be performed without the scope & invocationSite
4868
4848
4869
		int methodLength = methodName.length;
4849
		int fieldLength = fieldName.length;
4870
		next : for (int m = methods.length; --m >= 0;) {
4850
		next : for (int f = fields.length; --f >= 0;) {
4871
			MethodBinding method = methods[m];
4851
			FieldBinding field = fields[f];
4872
4852
4873
			if (method.isSynthetic()) continue next;
4853
			if (field.isSynthetic())	continue next;
4874
4854
4875
			if (method.isDefaultAbstract())	continue next;
4855
			if (onlyStaticFields && !field.isStatic()) continue next;
4876
4856
4877
			if (method.isConstructor()) continue next;
4857
			if (fieldLength > field.name.length) continue next;
4878
4858
4879
			if (!method.isStatic()) continue next;
4859
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4860
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4880
4861
4881
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
4862
			if (this.options.checkDeprecation &&
4863
					field.isViewedAsDeprecated() &&
4864
					!scope.isDefinedInSameUnit(field.declaringClass))
4865
				continue next;
4882
4866
4883
			if (this.options.checkVisibility
4867
			if (this.options.checkVisibility
4884
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
4868
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4885
4869
4886
			if (methodLength > method.selector.length)
4870
			boolean prefixRequired = false;
4887
				continue next;
4888
4871
4889
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
4872
			for (int i = fieldsFound.size; --i >= 0;) {
4890
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
4873
				Object[] other = (Object[])fieldsFound.elementAt(i);
4891
				continue next;
4874
				FieldBinding otherField = (FieldBinding) other[0];
4875
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
4876
				if (field == otherField && receiverType == otherReceiverType)
4877
					continue next;
4878
				if (CharOperation.equals(field.name, otherField.name, true)) {
4879
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
4880
						continue next;
4881
					if (otherField.declaringClass.isInterface()) {
4882
						if (field.declaringClass == scope.getJavaLangObject())
4883
							continue next;
4884
						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
4885
							continue next;
4886
					}
4887
					if (field.declaringClass.isInterface())
4888
						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
4889
							continue next;
4890
					if(canBePrefixed) {
4891
						prefixRequired = true;
4892
					} else {
4893
						continue next;
4894
					}
4895
				}
4896
			}
4892
4897
4893
			int length = method.parameters.length;
4898
			for (int l = localsFound.size; --l >= 0;) {
4894
			char[][] parameterPackageNames = new char[length][];
4899
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
4895
			char[][] parameterTypeNames = new char[length][];
4896
4900
4897
			for (int i = 0; i < length; i++) {
4901
				if (CharOperation.equals(field.name, local.name, true)) {
4898
				TypeBinding type = method.original().parameters[i];
4902
					SourceTypeBinding declarationType = scope.enclosingSourceType();
4899
				parameterPackageNames[i] = type.qualifiedPackageName();
4903
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
4900
				parameterTypeNames[i] = type.qualifiedSourceName();
4904
						continue next;
4905
					}
4906
					if(canBePrefixed) {
4907
						prefixRequired = true;
4908
					} else {
4909
						continue next;
4910
					}
4911
					break;
4912
				}
4901
			}
4913
			}
4902
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
4903
4914
4904
			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
4915
			newFieldsFound.add(new Object[]{field, receiverType});
4905
4916
4906
			int relevance = computeBaseRelevance();
4917
			char[] completion = field.name;
4907
			relevance += computeRelevanceForResolution();
4908
			relevance += computeRelevanceForInterestingProposal();
4909
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
4910
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4911
4918
4912
			this.noProposal = false;
4919
			if(prefixRequired || this.options.forceImplicitQualification){
4913
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
4920
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
4914
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
4921
				completion = CharOperation.concat(prefix,completion,'.');
4915
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
4916
				proposal.setSignature(getSignature(method));
4917
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
4918
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
4919
				proposal.setParameterPackageNames(parameterPackageNames);
4920
				proposal.setParameterTypeNames(parameterTypeNames);
4921
				proposal.setPackageName(method.returnType.qualifiedPackageName());
4922
				proposal.setTypeName(method.returnType.qualifiedSourceName());
4923
				proposal.setName(method.selector);
4924
				proposal.setCompletion(completionName);
4925
				proposal.setFlags(method.modifiers);
4926
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4927
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4928
				proposal.setRelevance(relevance);
4929
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
4930
				this.requestor.accept(proposal);
4931
				if(DEBUG) {
4932
					this.printDebug(proposal);
4933
				}
4934
			}
4922
			}
4935
		}
4936
	}
4937
4923
4938
	/*
4939
	 * Find javadoc block tags for a given completion javadoc tag node
4940
	 */
4941
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
4942
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
4943
		if (possibleTags == null) return;
4944
		int length = possibleTags.length;
4945
		for (int i=0; i<length; i++) {
4946
			int relevance = computeBaseRelevance();
4947
			relevance += computeRelevanceForInterestingProposal();
4948
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4949
4924
4950
			this.noProposal = false;
4925
			if (castedReceiver != null) {
4951
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
4926
				completion = CharOperation.concat(castedReceiver, completion);
4952
				char[] possibleTag = possibleTags[i];
4927
			}
4953
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
4928
4954
				proposal.setName(possibleTag);
4929
			// Special case for javadoc completion
4955
				int tagLength = possibleTag.length;
4930
			if (this.assistNodeInJavadoc > 0) {
4956
				char[] completion = new char[1+tagLength];
4931
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4957
				completion[0] = '@';
4932
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4958
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
4933
					if (fieldRef.receiver.isThis()) {
4959
				proposal.setCompletion(completion);
4934
						if (fieldRef.completeInText()) {
4960
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4935
							completion = CharOperation.concat(new char[] { '#' }, field.name);
4961
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4936
						}
4962
				proposal.setRelevance(relevance);
4937
					} else if (fieldRef.completeInText()) {
4963
				this.requestor.accept(proposal);
4938
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
4964
				if (DEBUG) {
4939
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
4965
					this.printDebug(proposal);
4940
							completion = CharOperation.concat(typeRef.token, field.name, '#');
4941
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
4942
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
4943
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
4944
						}
4945
					}
4966
				}
4946
				}
4967
			}
4947
			}
4968
		}
4969
	}
4970
4948
4971
	/*
4972
	 * Find javadoc inline tags for a given completion javadoc tag node
4973
	 */
4974
	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
4975
		char[][] possibleTags = javadocTag.getPossibleInlineTags();
4976
		if (possibleTags == null) return;
4977
		int length = possibleTags.length;
4978
		for (int i=0; i<length; i++) {
4979
			int relevance = computeBaseRelevance();
4949
			int relevance = computeBaseRelevance();
4980
			relevance += computeRelevanceForInterestingProposal();
4950
			relevance += computeRelevanceForResolution();
4981
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4951
			relevance += computeRelevanceForInterestingProposal(field);
4952
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4953
			relevance += computeRelevanceForExpectingType(field.type);
4954
			relevance += computeRelevanceForEnumConstant(field.type);
4955
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
4956
			relevance += computeRelevanceForQualification(prefixRequired);
4957
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4958
			if (onlyStaticFields && this.insideQualifiedReference) {
4959
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
4960
			}
4961
			if (missingElements != null) {
4962
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4963
			}
4982
4964
4983
			this.noProposal = false;
4965
			this.noProposal = false;
4984
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
4966
			if (castedReceiver == null) {
4985
				char[] possibleTag = possibleTags[i];
4967
				// Standard proposal
4986
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
4968
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4987
				proposal.setName(possibleTag);
4969
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4988
				int tagLength = possibleTag.length;
4970
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4989
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
4971
					proposal.setSignature(getSignature(field.type));
4990
				char[] completion = new char[2+tagLength+1];
4972
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4991
				completion[0] = '{';
4973
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4992
				completion[1] = '@';
4974
					proposal.setPackageName(field.type.qualifiedPackageName());
4993
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
4975
					proposal.setTypeName(field.type.qualifiedSourceName());
4994
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
4976
					proposal.setName(field.name);
4995
				//completion[tagLength+2] = ' ';
4977
					if (missingElements != null) {
4996
				completion[tagLength+2] = '}';
4978
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4997
				proposal.setCompletion(completion);
4979
						for (int i = 0; i < missingElements.length; i++) {
4998
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4980
							subProposals[i] =
4999
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4981
								createRequiredTypeProposal(
5000
				proposal.setRelevance(relevance);
4982
										missingElements[i],
5001
				this.requestor.accept(proposal);
4983
										missingElementsStarts[i],
5002
				if (DEBUG) {
4984
										missingElementsEnds[i],
5003
					this.printDebug(proposal);
4985
										relevance);
4986
						}
4987
						proposal.setRequiredProposals(subProposals);
4988
					}
4989
					proposal.setCompletion(completion);
4990
					proposal.setFlags(field.modifiers);
4991
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4992
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4993
					proposal.setRelevance(relevance);
4994
					this.requestor.accept(proposal);
4995
					if(DEBUG) {
4996
						this.printDebug(proposal);
4997
					}
5004
				}
4998
				}
5005
			}
5006
		}
5007
	}
5008
5009
	// what about onDemand types? Ignore them since it does not happen!
5010
	// import p1.p2.A.*;
5011
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
5012
		if(choices == null || choices.length == 0) return;
5013
5014
		int length = keyword.length;
5015
		if (canCompleteEmptyToken || length > 0)
5016
			for (int i = 0; i < choices.length; i++)
5017
				if (length <= choices[i].length
5018
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
5019
				)){
5020
					int relevance = computeBaseRelevance();
5021
					relevance += computeRelevanceForResolution();
5022
					relevance += computeRelevanceForInterestingProposal();
5023
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
5024
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
5025
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
5026
4999
5027
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
5000
				// Javadoc completions
5028
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
5001
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
5029
						relevance += computeRelevanceForQualification(false);
5002
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
5003
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
5004
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
5005
					proposal.setSignature(getSignature(field.type));
5006
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5007
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5008
					proposal.setPackageName(field.type.qualifiedPackageName());
5009
					proposal.setTypeName(field.type.qualifiedSourceName());
5010
					proposal.setName(field.name);
5011
					proposal.setCompletion(javadocCompletion);
5012
					proposal.setFlags(field.modifiers);
5013
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
5014
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
5015
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5016
					proposal.setRelevance(relevance+R_INLINE_TAG);
5017
					this.requestor.accept(proposal);
5018
					if(DEBUG) {
5019
						this.printDebug(proposal);
5030
					}
5020
					}
5031
					this.noProposal = false;
5021
					// Javadoc value completion for static fields
5032
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5022
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
5033
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5023
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
5034
						proposal.setName(choices[i]);
5024
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
5035
						proposal.setCompletion(choices[i]);
5025
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
5036
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5026
						valueProposal.setSignature(getSignature(field.type));
5037
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5027
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5038
						proposal.setRelevance(relevance);
5028
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5039
						this.requestor.accept(proposal);
5029
						valueProposal.setPackageName(field.type.qualifiedPackageName());
5030
						valueProposal.setTypeName(field.type.qualifiedSourceName());
5031
						valueProposal.setName(field.name);
5032
						valueProposal.setCompletion(javadocCompletion);
5033
						valueProposal.setFlags(field.modifiers);
5034
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
5035
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5036
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
5037
						this.requestor.accept(valueProposal);
5040
						if(DEBUG) {
5038
						if(DEBUG) {
5041
							this.printDebug(proposal);
5039
							this.printDebug(valueProposal);
5042
						}
5040
						}
5043
					}
5041
					}
5044
				}
5042
				}
5045
	}
5043
			} else {
5046
	private void findTrueOrFalseKeywords(char[][] choices) {
5044
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5047
		if(choices == null || choices.length == 0) return;
5045
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5048
5046
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
5049
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
5047
					proposal.setSignature(getSignature(field.type));
5050
5048
					proposal.setReceiverSignature(getSignature(receiverType));
5051
		for (int i = 0; i < choices.length; i++) {
5049
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5052
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
5050
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5053
					CharOperation.equals(choices[i], Keywords.FALSE)
5051
					proposal.setPackageName(field.type.qualifiedPackageName());
5054
			){
5052
					proposal.setTypeName(field.type.qualifiedSourceName());
5055
				int relevance = computeBaseRelevance();
5053
					proposal.setName(field.name);
5056
				relevance += computeRelevanceForResolution();
5054
					if (missingElements != null) {
5057
				relevance += computeRelevanceForInterestingProposal();
5055
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5058
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
5056
						for (int i = 0; i < missingElements.length; i++) {
5059
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
5057
							subProposals[i] =
5060
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
5058
								createRequiredTypeProposal(
5061
				relevance += computeRelevanceForQualification(false);
5059
										missingElements[i],
5062
				relevance += R_TRUE_OR_FALSE;
5060
										missingElementsStarts[i],
5063
5061
										missingElementsEnds[i],
5064
				this.noProposal = false;
5062
										relevance);
5065
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5063
						}
5066
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5064
						proposal.setRequiredProposals(subProposals);
5067
					proposal.setName(choices[i]);
5065
					}
5068
					proposal.setCompletion(choices[i]);
5066
					proposal.setCompletion(completion);
5067
					proposal.setFlags(field.modifiers);
5069
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5068
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5069
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5070
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5070
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5071
					proposal.setRelevance(relevance);
5071
					proposal.setRelevance(relevance);
5072
					this.requestor.accept(proposal);
5072
					this.requestor.accept(proposal);
Lines 5076-6635 Link Here
5076
				}
5076
				}
5077
			}
5077
			}
5078
		}
5078
		}
5079
	}
5080
5081
	private void findKeywordsForMember(char[] token, int modifiers) {
5082
		char[][] keywords = new char[Keywords.COUNT][];
5083
		int count = 0;
5084
5085
		// visibility
5086
		if((modifiers & ClassFileConstants.AccPrivate) == 0
5087
			&& (modifiers & ClassFileConstants.AccProtected) == 0
5088
			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
5089
			keywords[count++] = Keywords.PROTECTED;
5090
			keywords[count++] = Keywords.PUBLIC;
5091
			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
5092
				keywords[count++] = Keywords.PRIVATE;
5093
			}
5094
		}
5095
5096
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
5097
			// abtract
5098
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
5099
				keywords[count++] = Keywords.ABSTRACT;
5100
			}
5101
5102
			// final
5103
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
5104
				keywords[count++] = Keywords.FINAL;
5105
			}
5106
5107
			// static
5108
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
5109
				keywords[count++] = Keywords.STATIC;
5110
			}
5111
5112
			boolean canBeField = true;
5113
			boolean canBeMethod = true;
5114
			boolean canBeType = true;
5115
			if((modifiers & ClassFileConstants.AccNative) != 0
5116
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
5117
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
5118
				canBeField = false;
5119
				canBeType = false;
5120
			}
5121
5122
			if((modifiers & ClassFileConstants.AccTransient) != 0
5123
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
5124
				canBeMethod = false;
5125
				canBeType = false;
5126
			}
5127
5128
			if(canBeField) {
5129
				// transient
5130
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
5131
					keywords[count++] = Keywords.TRANSIENT;
5132
				}
5133
5134
				// volatile
5135
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
5136
					keywords[count++] = Keywords.VOLATILE;
5137
				}
5138
			}
5139
5140
			if(canBeMethod) {
5141
				// native
5142
				if((modifiers & ClassFileConstants.AccNative) == 0) {
5143
					keywords[count++] = Keywords.NATIVE;
5144
				}
5145
5146
				// strictfp
5147
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
5148
					keywords[count++] = Keywords.STRICTFP;
5149
				}
5150
5151
				// synchronized
5152
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
5153
					keywords[count++] = Keywords.SYNCHRONIZED;
5154
				}
5155
			}
5156
5157
			if(canBeType) {
5158
				keywords[count++] = Keywords.CLASS;
5159
				keywords[count++] = Keywords.INTERFACE;
5160
5161
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
5162
					keywords[count++] = Keywords.ENUM;
5163
				}
5164
			}
5165
		} else {
5166
			// class
5167
			keywords[count++] = Keywords.CLASS;
5168
			keywords[count++] = Keywords.INTERFACE;
5169
		}
5170
		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
5171
5079
5172
		findKeywords(token, keywords, false, false);
5080
		fieldsFound.addAll(newFieldsFound);
5173
	}
5081
	}
5082
	private void findFields(
5083
		char[] fieldName,
5084
		ReferenceBinding receiverType,
5085
		Scope scope,
5086
		ObjectVector fieldsFound,
5087
		ObjectVector localsFound,
5088
		boolean onlyStaticFields,
5089
		InvocationSite invocationSite,
5090
		Scope invocationScope,
5091
		boolean implicitCall,
5092
		boolean canBePrefixed,
5093
		Binding[] missingElements,
5094
		int[] missingElementsStarts,
5095
		int[] missingElementsEnds,
5096
		boolean missingElementsHaveProblems,
5097
		char[] castedReceiver,
5098
		int receiverStart,
5099
		int receiverEnd) {
5174
5100
5175
	protected void findMembers(
5101
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
5176
			char[] token,
5102
		if (fieldName == null && notInJavadoc)
5177
			ReferenceBinding receiverType,
5103
			return;
5178
			Scope scope,
5179
			InvocationSite invocationSite,
5180
			boolean isInsideAnnotationAttribute,
5181
			Binding[] missingElements,
5182
			int[] missingElementsStarts,
5183
			int[] missingElementsEnds,
5184
			boolean missingElementsHaveProblems) {
5185
5104
5186
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
5105
		ReferenceBinding currentType = receiverType;
5187
			findMemberTypes(
5106
		ReferenceBinding[] interfacesToVisit = null;
5188
					token,
5107
		int nextPosition = 0;
5189
					receiverType,
5108
		do {
5190
					scope,
5109
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5191
					scope.enclosingSourceType(),
5110
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5192
					false,
5111
				if (interfacesToVisit == null) {
5193
					true,
5112
					interfacesToVisit = itsInterfaces;
5194
					new ObjectVector(),
5113
					nextPosition = interfacesToVisit.length;
5195
					missingElements,
5114
				} else {
5196
					missingElementsStarts,
5115
					int itsLength = itsInterfaces.length;
5197
					missingElementsEnds,
5116
					if (nextPosition + itsLength >= interfacesToVisit.length)
5198
					missingElementsHaveProblems);
5117
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5199
		}
5118
					nextInterface : for (int a = 0; a < itsLength; a++) {
5200
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
5119
						ReferenceBinding next = itsInterfaces[a];
5201
			findClassField(
5120
						for (int b = 0; b < nextPosition; b++)
5202
					token,
5121
							if (next == interfacesToVisit[b]) continue nextInterface;
5203
					receiverType,
5122
						interfacesToVisit[nextPosition++] = next;
5123
					}
5124
				}
5125
			}
5126
5127
			FieldBinding[] fields = currentType.availableFields();
5128
			if(fields != null && fields.length > 0) {
5129
				findFields(
5130
					fieldName,
5131
					fields,
5204
					scope,
5132
					scope,
5133
					fieldsFound,
5134
					localsFound,
5135
					onlyStaticFields,
5136
					receiverType,
5137
					invocationSite,
5138
					invocationScope,
5139
					implicitCall,
5140
					canBePrefixed,
5205
					missingElements,
5141
					missingElements,
5206
					missingElementsStarts,
5142
					missingElementsStarts,
5207
					missingElementsEnds,
5143
					missingElementsEnds,
5208
					missingElementsHaveProblems);
5144
					missingElementsHaveProblems,
5209
		}
5145
					castedReceiver,
5146
					receiverStart,
5147
					receiverEnd);
5148
			}
5149
			currentType = currentType.superclass();
5150
		} while (notInJavadoc && currentType != null);
5210
5151
5211
		MethodScope methodScope = null;
5152
		if (notInJavadoc && interfacesToVisit != null) {
5212
		if (!isInsideAnnotationAttribute &&
5153
			for (int i = 0; i < nextPosition; i++) {
5213
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
5154
				ReferenceBinding anInterface = interfacesToVisit[i];
5214
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
5155
				FieldBinding[] fields = anInterface.availableFields();
5215
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
5156
				if(fields !=  null) {
5216
			if (token.length > 0) {
5157
					findFields(
5217
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
5158
						fieldName,
5218
			} else {
5159
						fields,
5219
				int relevance = computeBaseRelevance();
5160
						scope,
5220
				relevance += computeRelevanceForResolution();
5161
						fieldsFound,
5221
				relevance += computeRelevanceForInterestingProposal();
5162
						localsFound,
5222
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
5163
						onlyStaticFields,
5223
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
5164
						receiverType,
5224
				relevance += R_NON_INHERITED;
5165
						invocationSite,
5166
						invocationScope,
5167
						implicitCall,
5168
						canBePrefixed,
5169
						missingElements,
5170
						missingElementsStarts,
5171
						missingElementsEnds,
5172
						missingElementsHaveProblems,
5173
						castedReceiver,
5174
						receiverStart,
5175
						receiverEnd);
5176
				}
5225
5177
5226
				this.noProposal = false;
5178
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5227
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5179
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
5228
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5180
					int itsLength = itsInterfaces.length;
5229
					proposal.setName(Keywords.THIS);
5181
					if (nextPosition + itsLength >= interfacesToVisit.length)
5230
					proposal.setCompletion(Keywords.THIS);
5182
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5231
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5183
					nextInterface : for (int a = 0; a < itsLength; a++) {
5232
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5184
						ReferenceBinding next = itsInterfaces[a];
5233
					proposal.setRelevance(relevance);
5185
						for (int b = 0; b < nextPosition; b++)
5234
					this.requestor.accept(proposal);
5186
							if (next == interfacesToVisit[b]) continue nextInterface;
5235
					if (DEBUG) {
5187
						interfacesToVisit[nextPosition++] = next;
5236
						this.printDebug(proposal);
5237
					}
5188
					}
5238
				}
5189
				}
5239
			}
5190
			}
5240
		}
5191
		}
5241
5242
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
5243
			findFields(
5244
				token,
5245
				receiverType,
5246
				scope,
5247
				new ObjectVector(),
5248
				new ObjectVector(),
5249
				true,
5250
				invocationSite,
5251
				scope,
5252
				false,
5253
				false,
5254
				missingElements,
5255
				missingElementsStarts,
5256
				missingElementsEnds,
5257
				missingElementsHaveProblems,
5258
				null,
5259
				-1,
5260
				-1);
5261
		}
5262
5263
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
5264
			findMethods(
5265
				token,
5266
				null,
5267
				null,
5268
				receiverType,
5269
				scope,
5270
				new ObjectVector(),
5271
				true,
5272
				false,
5273
				false,
5274
				invocationSite,
5275
				scope,
5276
				false,
5277
				false,
5278
				false,
5279
				missingElements,
5280
				missingElementsStarts,
5281
				missingElementsEnds,
5282
				missingElementsHaveProblems,
5283
				null,
5284
				-1,
5285
				-1);
5286
		}
5287
	}
5288
5289
	private void findMembersFromMissingType(
5290
			final char[] token,
5291
			final long pos,
5292
			TypeBinding resolveType,
5293
			final Scope scope,
5294
			final InvocationSite invocationSite,
5295
			final boolean isInsideAnnotationAttribute) {
5296
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5297
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5298
			new MissingTypesGuesser.GuessedTypeRequestor() {
5299
				public void accept(
5300
						TypeBinding guessedType,
5301
						Binding[] missingElements,
5302
						int[] missingElementsStarts,
5303
						int[] missingElementsEnds,
5304
						boolean hasProblems) {
5305
					if (guessedType instanceof ReferenceBinding) {
5306
						findMembers(
5307
								CompletionEngine.this.completionToken,
5308
								(ReferenceBinding)guessedType,
5309
								scope,
5310
								invocationSite,
5311
								isInsideAnnotationAttribute,
5312
								missingElements,
5313
								missingElementsStarts,
5314
								missingElementsEnds,
5315
								hasProblems);
5316
					}
5317
				}
5318
			};
5319
		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
5320
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
5321
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5322
	}
5192
	}
5323
5193
5324
	// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
5194
	protected void findFieldsAndMethods(
5325
	private void findMemberTypes(
5195
		char[] token,
5326
		char[] typeName,
5196
		TypeBinding receiverType,
5327
		ReferenceBinding[] memberTypes,
5328
		ObjectVector typesFound,
5329
		ReferenceBinding receiverType,
5330
		SourceTypeBinding invocationType,
5331
		boolean staticOnly,
5332
		boolean staticFieldsAndMethodOnly,
5333
		boolean fromStaticImport,
5334
		boolean checkQualification,
5335
		Scope scope,
5197
		Scope scope,
5198
		ObjectVector fieldsFound,
5199
		ObjectVector methodsFound,
5200
		InvocationSite invocationSite,
5201
		Scope invocationScope,
5202
		boolean implicitCall,
5203
		boolean superCall,
5336
		Binding[] missingElements,
5204
		Binding[] missingElements,
5337
		int[] missingElementsStarts,
5205
		int[] missingElementsStarts,
5338
		int[] missingElementsEnds,
5206
		int[] missingElementsEnds,
5339
		boolean missingElementsHaveProblems) {
5207
		boolean missingElementsHaveProblems,
5340
5208
		char[] castedReceiver,
5341
		// Inherited member types which are hidden by subclasses are filtered out
5209
		int receiverStart,
5342
		// No visibility checks can be performed without the scope & invocationSite
5210
		int receiverEnd) {
5343
		int typeLength = typeName.length;
5344
		next : for (int m = memberTypes.length; --m >= 0;) {
5345
			ReferenceBinding memberType = memberTypes[m];
5346
			//		if (!wantClasses && memberType.isClass()) continue next;
5347
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
5348
5211
5349
			if (staticOnly && !memberType.isStatic()) continue next;
5212
		if (token == null)
5213
			return;
5350
5214
5351
			if (isForbidden(memberType)) continue next;
5215
		if (receiverType.isBaseType())
5216
			return; // nothing else is possible with base types
5352
5217
5353
			if (typeLength > memberType.sourceName.length)
5218
		boolean proposeField =
5354
				continue next;
5219
			castedReceiver == null ?
5220
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
5221
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
5222
		boolean proposeMethod =
5223
			castedReceiver == null ?
5224
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
5225
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
5355
5226
5356
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
5227
		if (receiverType.isArrayType()) {
5357
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
5228
			if (proposeField
5358
				continue next;
5229
				&& token.length <= lengthField.length
5230
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
5231
			)) {
5359
5232
5360
			if (this.options.checkDeprecation &&
5233
				int relevance = computeBaseRelevance();
5361
					memberType.isViewedAsDeprecated() &&
5234
				relevance += computeRelevanceForResolution();
5362
					!scope.isDefinedInSameUnit(memberType))
5235
				relevance += computeRelevanceForInterestingProposal();
5363
				continue next;
5236
				relevance += computeRelevanceForCaseMatching(token,lengthField);
5237
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
5238
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
5239
				if (missingElements != null) {
5240
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5241
				}
5242
				this.noProposal = false;
5243
				if (castedReceiver == null) {
5244
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
5245
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
5246
						proposal.setDeclarationSignature(getSignature(receiverType));
5247
						proposal.setSignature(INT_SIGNATURE);
5248
						proposal.setTypeName(INT);
5249
						proposal.setName(lengthField);
5250
						if (missingElements != null) {
5251
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5252
							for (int i = 0; i < missingElements.length; i++) {
5253
								subProposals[i] =
5254
									createRequiredTypeProposal(
5255
											missingElements[i],
5256
											missingElementsStarts[i],
5257
											missingElementsEnds[i],
5258
											relevance);
5259
							}
5260
							proposal.setRequiredProposals(subProposals);
5261
						}
5262
						proposal.setCompletion(lengthField);
5263
						proposal.setFlags(Flags.AccPublic);
5264
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5265
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5266
						proposal.setRelevance(relevance);
5267
						this.requestor.accept(proposal);
5268
						if(DEBUG) {
5269
							this.printDebug(proposal);
5270
						}
5271
					}
5272
				} else {
5273
					char[] completion = CharOperation.concat(castedReceiver, lengthField);
5364
5274
5365
			if (this.options.checkVisibility) {
5275
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5366
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
5276
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5367
					continue next;
5277
						proposal.setDeclarationSignature(getSignature(receiverType));
5368
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
5278
						proposal.setSignature(INT_SIGNATURE);
5369
					continue next;
5279
						proposal.setReceiverSignature(getSignature(receiverType));
5280
						proposal.setTypeName(INT);
5281
						proposal.setName(lengthField);
5282
						if (missingElements != null) {
5283
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5284
							for (int i = 0; i < missingElements.length; i++) {
5285
								subProposals[i] =
5286
									createRequiredTypeProposal(
5287
											missingElements[i],
5288
											missingElementsStarts[i],
5289
											missingElementsEnds[i],
5290
											relevance);
5291
							}
5292
							proposal.setRequiredProposals(subProposals);
5293
						}
5294
						proposal.setCompletion(completion);
5295
						proposal.setFlags(Flags.AccPublic);
5296
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5297
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5298
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5299
						proposal.setRelevance(relevance);
5300
						this.requestor.accept(proposal);
5301
						if(DEBUG) {
5302
							this.printDebug(proposal);
5303
						}
5304
					}
5370
				}
5305
				}
5371
			}
5306
			}
5307
			if (proposeMethod
5308
				&& token.length <= cloneMethod.length
5309
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
5310
			) {
5311
				ReferenceBinding objectRef = scope.getJavaLangObject();
5372
5312
5373
			if (this.insideQualifiedReference &&
5313
				int relevance = computeBaseRelevance();
5374
					receiverType.isParameterizedType() &&
5314
				relevance += computeRelevanceForResolution();
5375
					memberType.isStatic()) {
5315
				relevance += computeRelevanceForInterestingProposal();
5376
				continue next;
5316
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
5377
			}
5317
				relevance += computeRelevanceForExpectingType(objectRef);
5378
5318
				relevance += computeRelevanceForStatic(false, false);
5379
			for (int i = typesFound.size; --i >= 0;) {
5319
				relevance += computeRelevanceForQualification(false);
5380
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
5320
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
5381
5321
				if (missingElements != null) {
5382
				if (memberType == otherType)
5322
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5383
					continue next;
5384
5385
				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
5386
5387
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
5388
						continue next;
5389
5390
					if (otherType.enclosingType().isInterface())
5391
						if (memberType.enclosingType()
5392
							.implementsInterface(otherType.enclosingType(), true))
5393
							continue next;
5394
5395
					if (memberType.enclosingType().isInterface())
5396
						if (otherType.enclosingType()
5397
							.implementsInterface(memberType.enclosingType(), true))
5398
							continue next;
5399
				}
5323
				}
5400
			}
5324
				char[] completion;
5401
5325
				if (this.source != null
5402
			typesFound.add(memberType);
5326
					&& this.source.length > this.endPosition
5403
5327
					&& this.source[this.endPosition] == '(') {
5404
			if(!this.insideQualifiedReference) {
5328
					completion = cloneMethod;
5405
				if(this.assistNodeIsClass) {
5329
					} else {
5406
					if(!memberType.isClass()) continue next;
5330
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
5407
				} else if(this.assistNodeIsInterface) {
5408
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
5409
				} else if (this.assistNodeIsAnnotation) {
5410
					if(!memberType.isAnnotationType()) continue next;
5411
				}
5331
				}
5412
			}
5413
5414
			char[] completionName = memberType.sourceName();
5415
5332
5416
			boolean isQualified = false;
5333
				if (castedReceiver != null) {
5417
			if(checkQualification && !fromStaticImport) {
5334
					completion = CharOperation.concat(castedReceiver, completion);
5418
				char[] memberPackageName = memberType.qualifiedPackageName();
5419
				char[] memberTypeName = memberType.sourceName();
5420
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
5421
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
5422
					if (memberPackageName == null || memberPackageName.length == 0)
5423
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
5424
							break next; // ignore types from the default package from outside it
5425
					isQualified = true;
5426
					completionName =
5427
						CharOperation.concat(
5428
								memberPackageName,
5429
								CharOperation.concat(
5430
										memberEnclosingTypeNames,
5431
										memberTypeName,
5432
										'.'),
5433
								'.');
5434
				}
5335
				}
5435
			}
5436
5336
5437
			int relevance = computeBaseRelevance();
5337
				this.noProposal = false;
5438
			relevance += computeRelevanceForResolution();
5338
				if (castedReceiver == null) {
5439
			relevance += computeRelevanceForInterestingProposal();
5339
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
5440
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
5340
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5441
			relevance += computeRelevanceForExpectingType(memberType);
5341
						proposal.setDeclarationSignature(getSignature(receiverType));
5442
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5342
						proposal.setSignature(
5443
			if(!this.insideQualifiedReference) {
5343
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5444
				relevance += computeRelevanceForQualification(isQualified);
5344
										createMethodSignature(
5445
			}
5345
												CharOperation.NO_CHAR_CHAR,
5446
			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.
5346
												CharOperation.NO_CHAR_CHAR,
5447
5347
												getSignature(receiverType)) :
5448
			if (memberType.isAnnotationType()) {
5348
										createMethodSignature(
5449
				relevance += computeRelevanceForAnnotation();
5349
												CharOperation.NO_CHAR_CHAR,
5450
				relevance += computeRelevanceForAnnotationTarget(memberType);
5350
												CharOperation.NO_CHAR_CHAR,
5451
			} else if (memberType.isClass()) {
5351
												CharOperation.concatWith(JAVA_LANG, '.'),
5452
				relevance += computeRelevanceForClass();
5352
												OBJECT));
5453
				relevance += computeRelevanceForException(memberType.sourceName);
5353
						//proposal.setOriginalSignature(null);
5454
			} else if(memberType.isEnum()) {
5354
						//proposal.setDeclarationPackageName(null);
5455
				relevance += computeRelevanceForEnum();
5355
						//proposal.setDeclarationTypeName(null);
5456
			} else if(memberType.isInterface()) {
5356
						//proposal.setParameterPackageNames(null);
5457
				relevance += computeRelevanceForInterface();
5357
						//proposal.setParameterTypeNames(null);
5458
			}
5358
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5459
5359
						proposal.setTypeName(OBJECT);
5460
			if (missingElements != null) {
5360
						proposal.setName(cloneMethod);
5461
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5361
						if (missingElements != null) {
5462
			}
5362
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5463
5363
							for (int i = 0; i < missingElements.length; i++) {
5464
			this.noProposal = false;
5364
								subProposals[i] =
5465
			createTypeProposal(
5365
									createRequiredTypeProposal(
5466
					memberType,
5366
											missingElements[i],
5467
					memberType.qualifiedSourceName(),
5367
											missingElementsStarts[i],
5468
					IAccessRule.K_ACCESSIBLE,
5368
											missingElementsEnds[i],
5469
					completionName,
5369
											relevance);
5470
					relevance,
5370
							}
5471
					missingElements,
5371
							proposal.setRequiredProposals(subProposals);
5472
					missingElementsStarts,
5372
						}
5473
					missingElementsEnds,
5373
						proposal.setCompletion(completion);
5474
					missingElementsHaveProblems);
5374
						proposal.setFlags(Flags.AccPublic);
5375
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5376
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5377
						proposal.setRelevance(relevance);
5378
						this.requestor.accept(proposal);
5379
						if(DEBUG) {
5380
							this.printDebug(proposal);
5381
						}
5382
					}
5383
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
5384
				} else {
5385
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5386
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5387
						proposal.setDeclarationSignature(getSignature(receiverType));
5388
						proposal.setSignature(
5389
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5390
										createMethodSignature(
5391
												CharOperation.NO_CHAR_CHAR,
5392
												CharOperation.NO_CHAR_CHAR,
5393
												getSignature(receiverType)) :
5394
										createMethodSignature(
5395
												CharOperation.NO_CHAR_CHAR,
5396
												CharOperation.NO_CHAR_CHAR,
5397
												CharOperation.concatWith(JAVA_LANG, '.'),
5398
												OBJECT));
5399
						proposal.setReceiverSignature(getSignature(receiverType));
5400
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5401
						proposal.setTypeName(OBJECT);
5402
						proposal.setName(cloneMethod);
5403
						if (missingElements != null) {
5404
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5405
							for (int i = 0; i < missingElements.length; i++) {
5406
								subProposals[i] =
5407
									createRequiredTypeProposal(
5408
											missingElements[i],
5409
											missingElementsStarts[i],
5410
											missingElementsEnds[i],
5411
											relevance);
5412
							}
5413
							proposal.setRequiredProposals(subProposals);
5414
						}
5415
						proposal.setCompletion(completion);
5416
						proposal.setFlags(Flags.AccPublic);
5417
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5418
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5419
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5420
						proposal.setRelevance(relevance);
5421
						this.requestor.accept(proposal);
5422
						if(DEBUG) {
5423
							this.printDebug(proposal);
5424
						}
5425
					}
5426
				}
5427
			}
5428
5429
			receiverType = scope.getJavaLangObject();
5430
		}
5431
		
5432
		checkTimeout();
5433
		
5434
		if(proposeField) {
5435
			findFields(
5436
				token,
5437
				(ReferenceBinding) receiverType,
5438
				scope,
5439
				fieldsFound,
5440
				new ObjectVector(),
5441
				false,
5442
				invocationSite,
5443
				invocationScope,
5444
				implicitCall,
5445
				false,
5446
				missingElements,
5447
				missingElementsStarts,
5448
				missingElementsEnds,
5449
				missingElementsHaveProblems,
5450
				castedReceiver,
5451
				receiverStart,
5452
				receiverEnd);
5475
		}
5453
		}
5476
	}
5477
5454
5478
	protected void findMemberTypes(
5455
		if(proposeMethod) {
5479
		char[] typeName,
5456
			findMethods(
5480
		ReferenceBinding receiverType,
5457
				token,
5481
		Scope scope,
5458
				null,
5482
		SourceTypeBinding typeInvocation,
5459
				null,
5483
		boolean staticOnly,
5460
				(ReferenceBinding) receiverType,
5484
		boolean staticFieldsAndMethodOnly,
5485
		ObjectVector typesFound,
5486
		Binding[] missingElements,
5487
		int[] missingElementsStarts,
5488
		int[] missingElementsEnds,
5489
		boolean missingElementsHaveProblems)  {
5490
		findMemberTypes(
5491
				typeName,
5492
				receiverType,
5493
				scope,
5461
				scope,
5494
				typeInvocation,
5462
				methodsFound,
5495
				staticOnly,
5496
				staticFieldsAndMethodOnly,
5497
				false,
5463
				false,
5498
				false,
5464
				false,
5465
				invocationSite,
5466
				invocationScope,
5467
				implicitCall,
5468
				superCall,
5499
				false,
5469
				false,
5500
				null,
5501
				typesFound,
5502
				missingElements,
5470
				missingElements,
5503
				missingElementsStarts,
5471
				missingElementsStarts,
5504
				missingElementsEnds,
5472
				missingElementsEnds,
5505
				missingElementsHaveProblems);
5473
				missingElementsHaveProblems,
5474
				castedReceiver,
5475
				receiverStart,
5476
				receiverEnd);
5477
		}
5506
	}
5478
	}
5507
	private void findMemberTypes(
5508
		char[] typeName,
5509
		ReferenceBinding receiverType,
5510
		Scope scope,
5511
		SourceTypeBinding typeInvocation,
5512
		boolean staticOnly,
5513
		boolean staticFieldsAndMethodOnly,
5514
		boolean fromStaticImport,
5515
		boolean checkQualification,
5516
		boolean proposeAllMemberTypes,
5517
		SourceTypeBinding typeToIgnore,
5518
		ObjectVector typesFound,
5519
		Binding[] missingElements,
5520
		int[] missingElementsStarts,
5521
		int[] missingElementsEnds,
5522
		boolean missingElementsHaveProblems) {
5523
5479
5524
		ReferenceBinding currentType = receiverType;
5480
	protected void findFieldsAndMethodsFromAnotherReceiver(
5525
		if (typeName == null)
5481
			char[] token,
5526
			return;
5482
			TypeReference receiverType,
5483
			Scope scope,
5484
			ObjectVector fieldsFound,
5485
			ObjectVector methodsFound,
5486
			InvocationSite invocationSite,
5487
			Scope invocationScope,
5488
			boolean implicitCall,
5489
			boolean superCall,
5490
			Binding[] missingElements,
5491
			int[] missingElementsStarts,
5492
			int[] missingElementsEnds,
5493
			boolean missingElementsHaveProblems,
5494
			char[][] receiverName,
5495
			int receiverStart,
5496
			int receiverEnd) {
5527
5497
5528
		if (this.insideQualifiedReference
5498
		if (receiverType.resolvedType == null) return;
5529
			|| typeName.length == 0) { // do not search up the hierarchy
5530
5499
5531
			findMemberTypes(
5500
		TypeBinding receiverTypeBinding = receiverType.resolvedType;
5532
				typeName,
5501
		char[] castedReceiver = null;
5533
				currentType.memberTypes(),
5502
5534
				typesFound,
5503
		char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
5535
				receiverType,
5504
		if(this.source != null) {
5536
				typeInvocation,
5505
			int memberRefStart = this.startPosition;
5537
				staticOnly,
5506
5538
				staticFieldsAndMethodOnly,
5507
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5539
				fromStaticImport,
5508
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
5540
				checkQualification,
5509
5541
				scope,
5510
			castedReceiver =
5542
				missingElements,
5511
				CharOperation.concat(
5543
				missingElementsStarts,
5512
					CharOperation.concat(
5544
				missingElementsEnds,
5513
						'(',
5545
				missingElementsHaveProblems);
5514
						CharOperation.concat(
5546
			return;
5515
							CharOperation.concat('(', castedTypeChars, ')'),
5516
							receiverChars),
5517
						')'),
5518
					dotChars);
5519
		} else {
5520
			castedReceiver =
5521
				CharOperation.concat(
5522
					CharOperation.concat(
5523
						'(',
5524
						CharOperation.concat(
5525
							CharOperation.concat('(', castedTypeChars, ')'),
5526
							CharOperation.concatWith(receiverName, '.')),
5527
						')'),
5528
					DOT);
5547
		}
5529
		}
5548
5530
5549
		ReferenceBinding[] interfacesToVisit = null;
5531
		if (castedReceiver == null) return;
5550
		int nextPosition = 0;
5551
5532
5552
		do {
5533
		int oldStartPosition = this.startPosition;
5553
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5534
		this.startPosition = receiverStart;
5554
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5555
				if (interfacesToVisit == null) {
5556
					interfacesToVisit = itsInterfaces;
5557
					nextPosition = interfacesToVisit.length;
5558
				} else {
5559
					int itsLength = itsInterfaces.length;
5560
					if (nextPosition + itsLength >= interfacesToVisit.length)
5561
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5562
					nextInterface : for (int a = 0; a < itsLength; a++) {
5563
						ReferenceBinding next = itsInterfaces[a];
5564
						for (int b = 0; b < nextPosition; b++)
5565
							if (next == interfacesToVisit[b]) continue nextInterface;
5566
						interfacesToVisit[nextPosition++] = next;
5567
					}
5568
				}
5569
			}
5570
5535
5571
			findMemberTypes(
5536
		findFieldsAndMethods(
5572
				typeName,
5537
				token,
5573
				currentType.memberTypes(),
5538
				receiverTypeBinding,
5574
				typesFound,
5575
				receiverType,
5576
				typeInvocation,
5577
				staticOnly,
5578
				staticFieldsAndMethodOnly,
5579
				fromStaticImport,
5580
				checkQualification,
5581
				scope,
5539
				scope,
5540
				fieldsFound,
5541
				methodsFound,
5542
				invocationSite,
5543
				invocationScope,
5544
				implicitCall,
5545
				superCall,
5582
				missingElements,
5546
				missingElements,
5583
				missingElementsStarts,
5547
				missingElementsStarts,
5584
				missingElementsEnds,
5548
				missingElementsEnds,
5585
				missingElementsHaveProblems);
5549
				missingElementsHaveProblems,
5550
				castedReceiver,
5551
				receiverStart,
5552
				receiverEnd);
5586
5553
5587
			currentType = currentType.superclass();
5554
		this.startPosition = oldStartPosition;
5588
		} while (currentType != null);
5555
	}
5556
	private void findFieldsAndMethodsFromCastedReceiver(
5557
			ASTNode enclosingNode,
5558
			Binding qualifiedBinding,
5559
			Scope scope,
5560
			ObjectVector fieldsFound,
5561
			ObjectVector methodsFound,
5562
			InvocationSite invocationSite,
5563
			Scope invocationScope,
5564
			Expression receiver) {
5589
5565
5590
		if(proposeAllMemberTypes) {
5566
		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
5591
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
5592
			for (int i = 0; i < memberTypes.length; i++) {
5593
				if(memberTypes[i] != typeToIgnore) {
5594
					findSubMemberTypes(
5595
						typeName,
5596
						memberTypes[i],
5597
						scope,
5598
						typeInvocation,
5599
						staticOnly,
5600
						staticFieldsAndMethodOnly,
5601
						fromStaticImport,
5602
						typesFound);
5603
				}
5604
			}
5605
		}
5606
5567
5607
		if (interfacesToVisit != null) {
5568
		IfStatement ifStatement = (IfStatement)enclosingNode;
5608
			for (int i = 0; i < nextPosition; i++) {
5569
5609
				ReferenceBinding anInterface = interfacesToVisit[i];
5570
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
5610
				findMemberTypes(
5571
5611
					typeName,
5572
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
5612
					anInterface.memberTypes(),
5573
5613
					typesFound,
5574
		TypeReference instanceOfType = instanceOfExpression.type;
5614
					receiverType,
5575
5615
					typeInvocation,
5576
		if (instanceOfType.resolvedType == null) return;
5616
					staticOnly,
5577
5617
					staticFieldsAndMethodOnly,
5578
		boolean findFromAnotherReceiver = false;
5618
					fromStaticImport,
5579
5619
					checkQualification,
5580
		char[][] receiverName = null;
5620
					scope,
5581
		int receiverStart = -1;
5621
					missingElements,
5582
		int receiverEnd = -1;
5622
					missingElementsStarts,
5583
5623
					missingElementsEnds,
5584
		if (receiver instanceof QualifiedNameReference) {
5624
					missingElementsHaveProblems);
5585
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
5625
5586
5626
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5587
			receiverName = qualifiedNameReference.tokens;
5627
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5588
5628
					int itsLength = itsInterfaces.length;
5589
			if (receiverName.length != 1) return;
5629
					if (nextPosition + itsLength >= interfacesToVisit.length)
5590
5630
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5591
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
5631
					nextInterface : for (int a = 0; a < itsLength; a++) {
5592
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
5632
						ReferenceBinding next = itsInterfaces[a];
5593
5633
						for (int b = 0; b < nextPosition; b++)
5594
			// if (local instanceof X) local.|
5634
							if (next == interfacesToVisit[b]) continue nextInterface;
5595
			// if (field instanceof X) field.|
5635
						interfacesToVisit[nextPosition++] = next;
5596
			if (instanceOfExpression.expression instanceof SingleNameReference &&
5636
					}
5597
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
5637
				}
5598
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
5599
				findFromAnotherReceiver = true;
5638
			}
5600
			}
5639
		}
5640
	}
5641
5601
5642
	private void findMemberTypesFromMissingType(
5602
			// if (this.field instanceof X) field.|
5643
			char[] typeName,
5603
			if (instanceOfExpression.expression instanceof FieldReference) {
5644
			final long pos,
5604
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
5645
			final Scope scope)  {
5646
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5647
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5648
			new MissingTypesGuesser.GuessedTypeRequestor() {
5649
				public void accept(
5650
						TypeBinding guessedType,
5651
						Binding[] missingElements,
5652
						int[] missingElementsStarts,
5653
						int[] missingElementsEnds,
5654
						boolean hasProblems) {
5655
					if (guessedType instanceof ReferenceBinding) {
5656
						findMemberTypes(
5657
								CompletionEngine.this.completionToken,
5658
								(ReferenceBinding)guessedType,
5659
								scope,
5660
								scope.enclosingSourceType(),
5661
								false,
5662
								false,
5663
								new ObjectVector(),
5664
								missingElements,
5665
								missingElementsStarts,
5666
								missingElementsEnds,
5667
								hasProblems);
5668
					}
5669
				}
5670
			};
5671
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
5672
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
5673
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5674
	}
5675
5605
5676
	private void findMemberTypesFromMissingType(
5606
				if (fieldReference.receiver instanceof ThisReference &&
5677
			TypeReference typeRef,
5607
						qualifiedBinding instanceof FieldBinding &&
5678
			final long pos,
5608
						fieldReference.binding == qualifiedBinding) {
5679
			final Scope scope)  {
5609
							findFromAnotherReceiver = true;
5680
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5681
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5682
			new MissingTypesGuesser.GuessedTypeRequestor() {
5683
				public void accept(
5684
						TypeBinding guessedType,
5685
						Binding[] missingElements,
5686
						int[] missingElementsStarts,
5687
						int[] missingElementsEnds,
5688
						boolean hasProblems) {
5689
					if (guessedType instanceof ReferenceBinding) {
5690
						findMemberTypes(
5691
								CompletionEngine.this.completionToken,
5692
								(ReferenceBinding)guessedType,
5693
								scope,
5694
								scope.enclosingSourceType(),
5695
								false,
5696
								false,
5697
								new ObjectVector(),
5698
								missingElements,
5699
								missingElementsStarts,
5700
								missingElementsEnds,
5701
								hasProblems);
5702
					}
5703
				}
5610
				}
5704
			};
5611
			}
5705
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5612
		} else if (receiver instanceof FieldReference) {
5706
	}
5613
			FieldReference fieldReference1 = (FieldReference) receiver;
5707
5614
5708
	/*
5615
			receiverStart = fieldReference1.sourceStart;
5709
	 * Find javadoc parameter names.
5616
			receiverEnd = fieldReference1.sourceEnd + 1;
5710
	 */
5711
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
5712
5617
5713
		if (missingParams == null) return;
5618
			if (fieldReference1.receiver instanceof ThisReference) {
5714
5619
5715
		// Get relevance
5620
				receiverName = new char[][] {THIS, fieldReference1.token};
5716
		int relevance = computeBaseRelevance();
5717
		relevance += computeRelevanceForInterestingProposal();
5718
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
5719
		if (!isTypeParam) relevance += R_INTERESTING;
5720
5621
5721
		// Propose missing param
5622
				// if (field instanceof X) this.field.|
5722
		int length = missingParams.length;
5623
				if (instanceOfExpression.expression instanceof SingleNameReference &&
5723
		relevance += length;
5624
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
5724
		for (int i=0; i<length; i++) {
5625
					findFromAnotherReceiver = true;
5725
			char[] argName = missingParams[i];
5626
				}
5726
			if (token == null || CharOperation.prefixEquals(token, argName)) {
5727
5627
5728
				this.noProposal = false;
5628
				// if (this.field instanceof X) this.field.|
5729
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
5629
				if (instanceOfExpression.expression instanceof FieldReference) {
5730
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
5630
					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
5731
					proposal.setName(argName);
5631
5732
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
5632
					if (fieldReference2.receiver instanceof ThisReference &&
5733
					proposal.setCompletion(completion);
5633
							fieldReference2.binding == fieldReference1.binding) {
5734
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5634
								findFromAnotherReceiver = true;
5735
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5736
					proposal.setRelevance(--relevance);
5737
					this.requestor.accept(proposal);
5738
					if (DEBUG) {
5739
						this.printDebug(proposal);
5740
					}
5635
					}
5741
				}
5636
				}
5742
			}
5637
			}
5743
		}
5638
		}
5744
	}
5745
5746
	private void findSubMemberTypes(
5747
		char[] typeName,
5748
		ReferenceBinding receiverType,
5749
		Scope scope,
5750
		SourceTypeBinding typeInvocation,
5751
		boolean staticOnly,
5752
		boolean staticFieldsAndMethodOnly,
5753
		boolean fromStaticImport,
5754
		ObjectVector typesFound) {
5755
5639
5756
		ReferenceBinding currentType = receiverType;
5640
		if (findFromAnotherReceiver) {
5757
		if (typeName == null || typeName.length == 0)
5641
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
5758
			return;
5642
			char[] castedReceiver = null;
5759
5643
5760
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
5644
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
5645
			if(this.source != null) {
5646
				int memberRefStart = this.startPosition;
5761
5647
5762
		findMemberTypes(
5648
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5763
				typeName,
5649
				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
5764
				currentType.memberTypes(),
5765
				typesFound,
5766
				receiverType,
5767
				typeInvocation,
5768
				staticOnly,
5769
				staticFieldsAndMethodOnly,
5770
				fromStaticImport,
5771
				true,
5772
				scope,
5773
				null,
5774
				null,
5775
				null,
5776
				false);
5777
5650
5778
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
5651
				castedReceiver =
5779
		next : for (int i = 0; i < memberTypes.length; i++) {
5652
					CharOperation.concat(
5780
			if (this.options.checkVisibility) {
5653
						CharOperation.concat(
5781
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
5654
							'(',
5782
					continue next;
5655
							CharOperation.concat(
5783
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
5656
								CharOperation.concat('(', castedTypeChars, ')'),
5784
					continue next;
5657
								receiverChars),
5785
				}
5658
							')'),
5659
						dotChars);
5660
			} else {
5661
				castedReceiver =
5662
					CharOperation.concat(
5663
						CharOperation.concat(
5664
							'(',
5665
							CharOperation.concat(
5666
								CharOperation.concat('(', castedTypeChars, ')'),
5667
								CharOperation.concatWith(receiverName, '.')),
5668
							')'),
5669
						DOT);
5786
			}
5670
			}
5787
			findSubMemberTypes(
5788
				typeName,
5789
				memberTypes[i],
5790
				scope,
5791
				typeInvocation,
5792
				staticOnly,
5793
				staticFieldsAndMethodOnly,
5794
				fromStaticImport,
5795
				typesFound);
5796
		}
5797
	}
5798
5671
5799
	private void findInterfacesMethods(
5672
			if (castedReceiver == null) return;
5800
		char[] selector,
5673
5801
		TypeBinding[] typeArgTypes,
5674
			int oldStartPosition = this.startPosition;
5802
		TypeBinding[] argTypes,
5675
			this.startPosition = receiverStart;
5803
		ReferenceBinding receiverType,
5676
5804
		ReferenceBinding[] itsInterfaces,
5677
			findFieldsAndMethods(
5805
		Scope scope,
5678
					this.completionToken,
5806
		ObjectVector methodsFound,
5679
					receiverTypeBinding,
5807
		boolean onlyStaticMethods,
5680
					scope,
5808
		boolean exactMatch,
5681
					fieldsFound,
5809
		boolean isCompletingDeclaration,
5682
					methodsFound,
5810
		InvocationSite invocationSite,
5683
					invocationSite,
5811
		Scope invocationScope,
5684
					invocationScope,
5812
		boolean implicitCall,
5685
					false,
5813
		boolean superCall,
5686
					false,
5814
		boolean canBePrefixed,
5687
					null,
5815
		Binding[] missingElements,
5688
					null,
5816
		int[] missingElementssStarts,
5689
					null,
5817
		int[] missingElementsEnds,
5690
					false,
5818
		boolean missingElementsHaveProblems,
5691
					castedReceiver,
5819
		char[] castedReceiver,
5692
					receiverStart,
5820
		int receiverStart,
5693
					receiverEnd);
5821
		int receiverEnd) {
5822
5694
5823
		if (selector == null)
5695
			this.startPosition = oldStartPosition;
5824
			return;
5696
		}
5697
	}
5698
	private void findFieldsAndMethodsFromFavorites(
5699
			char[] token,
5700
			Scope scope,
5701
			InvocationSite invocationSite,
5702
			Scope invocationScope,
5703
			ObjectVector localsFound,
5704
			ObjectVector fieldsFound,
5705
			ObjectVector methodsFound) {
5825
5706
5826
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
5707
		ObjectVector methodsFoundFromFavorites = new ObjectVector();
5827
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
5828
			int nextPosition = interfacesToVisit.length;
5829
5708
5830
			for (int i = 0; i < nextPosition; i++) {
5709
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
5831
				ReferenceBinding currentType = interfacesToVisit[i];
5832
				MethodBinding[] methods = currentType.availableMethods();
5833
				if(methods != null) {
5834
					if(isCompletingDeclaration) {
5835
						findLocalMethodDeclarations(
5836
							selector,
5837
							methods,
5838
							scope,
5839
							methodsFound,
5840
							exactMatch,
5841
							receiverType);
5842
					} else {
5843
						findLocalMethods(
5844
							selector,
5845
							typeArgTypes,
5846
							argTypes,
5847
							methods,
5848
							scope,
5849
							methodsFound,
5850
							onlyStaticMethods,
5851
							exactMatch,
5852
							receiverType,
5853
							invocationSite,
5854
							invocationScope,
5855
							implicitCall,
5856
							superCall,
5857
							canBePrefixed,
5858
							missingElements,
5859
							missingElementssStarts,
5860
							missingElementsEnds,
5861
							missingElementsHaveProblems,
5862
							castedReceiver,
5863
							receiverStart,
5864
							receiverEnd);
5865
					}
5866
				}
5867
5710
5868
				itsInterfaces = currentType.superInterfaces();
5711
		if (favoriteBindings != null && favoriteBindings.length > 0) {
5869
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5712
			for (int i = 0; i < favoriteBindings.length; i++) {
5870
					int itsLength = itsInterfaces.length;
5713
				ImportBinding favoriteBinding = favoriteBindings[i];
5871
					if (nextPosition + itsLength >= interfacesToVisit.length)
5714
				switch (favoriteBinding.resolvedImport.kind()) {
5872
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5715
					case Binding.FIELD:
5873
					nextInterface : for (int a = 0; a < itsLength; a++) {
5716
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
5874
						ReferenceBinding next = itsInterfaces[a];
5717
						findFieldsFromFavorites(
5875
						for (int b = 0; b < nextPosition; b++)
5718
								token,
5876
							if (next == interfacesToVisit[b]) continue nextInterface;
5719
								new FieldBinding[]{fieldBinding},
5877
						interfacesToVisit[nextPosition++] = next;
5720
								scope,
5878
					}
5721
								fieldsFound,
5722
								localsFound,
5723
								fieldBinding.declaringClass,
5724
								invocationSite,
5725
								invocationScope);
5726
						break;
5727
					case Binding.METHOD:
5728
						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
5729
						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
5730
						long range;
5731
						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
5732
							int start = (int) range, end = (int) (range >> 32);
5733
							int length = end - start + 1;
5734
							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
5735
						} else {
5736
							methods = Binding.NO_METHODS;
5737
						}
5738
						findLocalMethodsFromFavorites(
5739
								token,
5740
								methods,
5741
								scope,
5742
								methodsFound,
5743
								methodsFoundFromFavorites,
5744
								methodBinding.declaringClass,
5745
								invocationSite,
5746
								invocationScope);
5747
						break;
5748
					case Binding.TYPE:
5749
						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
5750
						if(favoriteBinding.onDemand) {
5751
							findFieldsFromFavorites(
5752
									token,
5753
									referenceBinding.availableFields(),
5754
									scope,
5755
									fieldsFound,
5756
									localsFound,
5757
									referenceBinding,
5758
									invocationSite,
5759
									invocationScope);
5760
5761
							findLocalMethodsFromFavorites(
5762
									token,
5763
									referenceBinding.availableMethods(),
5764
									scope,
5765
									methodsFound,
5766
									methodsFoundFromFavorites,
5767
									referenceBinding,
5768
									invocationSite,
5769
									invocationScope);
5770
						}
5771
						break;
5879
				}
5772
				}
5880
			}
5773
			}
5881
		}
5774
		}
5775
5776
		methodsFound.addAll(methodsFoundFromFavorites);
5882
	}
5777
	}
5883
5778
5884
	private void findImplicitMessageSends(
5779
	private boolean findFieldsAndMethodsFromMissingFieldType(
5885
		char[] token,
5780
		char[] token,
5886
		TypeBinding[] argTypes,
5887
		Scope scope,
5781
		Scope scope,
5888
		InvocationSite invocationSite,
5782
		InvocationSite invocationSite,
5889
		Scope invocationScope,
5783
		boolean insideTypeAnnotation) {
5890
		ObjectVector methodsFound) {
5891
5784
5892
		if (token == null)
5785
		boolean foundSomeFields = false;
5893
			return;
5894
5786
5895
		boolean staticsOnly = false;
5787
		boolean staticsOnly = false;
5896
		// need to know if we're in a static context (or inside a constructor)
5788
		Scope currentScope = scope;
5897
5789
5898
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5790
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5899
5791
5900
			switch (scope.kind) {
5792
			switch (currentScope.kind) {
5901
5793
5902
				case Scope.METHOD_SCOPE :
5794
				case Scope.METHOD_SCOPE :
5903
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5795
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5904
					MethodScope methodScope = (MethodScope) scope;
5796
					MethodScope methodScope = (MethodScope) currentScope;
5905
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5797
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5906
					break;
5798
					break;
5907
5908
				case Scope.CLASS_SCOPE :
5799
				case Scope.CLASS_SCOPE :
5909
					ClassScope classScope = (ClassScope) scope;
5800
					ClassScope classScope = (ClassScope) currentScope;
5910
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5801
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5911
					findMethods(
5802
					if(!insideTypeAnnotation) {
5912
						token,
5803
5913
						null,
5804
						FieldDeclaration[] fields = classScope.referenceContext.fields;
5914
						argTypes,
5805
5915
						enclosingType,
5806
						int fieldsCount = fields == null ? 0 : fields.length;
5916
						classScope,
5807
						for (int i = 0; i < fieldsCount; i++) {
5917
						methodsFound,
5808
							FieldDeclaration fieldDeclaration = fields[i];
5918
						staticsOnly,
5809
							if (CharOperation.equals(fieldDeclaration.name, token)) {
5919
						true,
5810
								FieldBinding fieldBinding = fieldDeclaration.binding;
5920
						false,
5811
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
5921
						invocationSite,
5812
									foundSomeFields = true;
5922
						invocationScope,
5813
									findFieldsAndMethodsFromMissingType(
5923
						true,
5814
											fieldDeclaration.type,
5924
						false,
5815
											currentScope,
5925
						true,
5816
											invocationSite,
5926
						null,
5817
											scope);
5927
						null,
5818
								}
5928
						null,
5819
								break done;
5929
						false,
5820
							}
5930
						null,
5821
						}
5931
						-1,
5822
					}
5932
						-1);
5933
					staticsOnly |= enclosingType.isStatic();
5823
					staticsOnly |= enclosingType.isStatic();
5824
					insideTypeAnnotation = false;
5934
					break;
5825
					break;
5935
5936
				case Scope.COMPILATION_UNIT_SCOPE :
5826
				case Scope.COMPILATION_UNIT_SCOPE :
5937
					break done;
5827
					break done;
5938
			}
5828
			}
5939
			scope = scope.parent;
5829
			currentScope = currentScope.parent;
5940
		}
5830
		}
5831
		return foundSomeFields;
5941
	}
5832
	}
5942
5833
5943
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
5834
	private void findFieldsAndMethodsFromMissingReturnType(
5944
	private void findLocalMethods(
5835
		char[] token,
5945
		char[] methodName,
5836
		TypeBinding[] arguments,
5946
		TypeBinding[] typeArgTypes,
5947
		TypeBinding[] argTypes,
5948
		MethodBinding[] methods,
5949
		Scope scope,
5837
		Scope scope,
5950
		ObjectVector methodsFound,
5838
		InvocationSite invocationSite,
5951
		boolean onlyStaticMethods,
5839
		boolean insideTypeAnnotation) {
5952
		boolean exactMatch,
5953
		ReferenceBinding receiverType,
5954
		InvocationSite invocationSite,
5955
		Scope invocationScope,
5956
		boolean implicitCall,
5957
		boolean superCall,
5958
		boolean canBePrefixed,
5959
		Binding[] missingElements,
5960
		int[] missingElementsStarts,
5961
		int[] missingElementsEnds,
5962
		boolean missingElementsHaveProblems,
5963
		char[] castedReceiver,
5964
		int receiverStart,
5965
		int receiverEnd) {
5966
5967
		ObjectVector newMethodsFound =  new ObjectVector();
5968
		// Inherited methods which are hidden by subclasses are filtered out
5969
		// No visibility checks can be performed without the scope & invocationSite
5970
5971
		int methodLength = methodName.length;
5972
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
5973
		int minArgLength = argTypes == null ? 0 : argTypes.length;
5974
5975
		next : for (int f = methods.length; --f >= 0;) {
5976
			MethodBinding method = methods[f];
5977
5978
			if (method.isSynthetic()) continue next;
5979
5980
			if (method.isDefaultAbstract())	continue next;
5981
5982
			if (method.isConstructor()) continue next;
5983
5984
			if (this.options.checkDeprecation &&
5985
					method.isViewedAsDeprecated() &&
5986
					!scope.isDefinedInSameUnit(method.declaringClass))
5987
				continue next;
5988
5989
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
5990
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
5991
5992
			if (onlyStaticMethods && !method.isStatic()) continue next;
5993
5994
			if (this.options.checkVisibility
5995
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
5996
5997
			if(superCall && method.isAbstract()) {
5998
				methodsFound.add(new Object[]{method, receiverType});
5999
				continue next;
6000
			}
6001
6002
			if (exactMatch) {
6003
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
6004
					continue next;
6005
				}
6006
			} else {
6007
				if (methodLength > method.selector.length) continue next;
6008
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6009
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6010
					continue next;
6011
				}
6012
			}
6013
6014
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
6015
				continue next;
6016
5840
6017
			if (minTypeArgLength != 0) {
5841
		boolean staticsOnly = false;
6018
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
5842
		Scope currentScope = scope;
6019
			}
6020
5843
6021
			if (minArgLength > method.parameters.length)
5844
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
6022
				continue next;
6023
5845
6024
			for (int a = minArgLength; --a >= 0;){
5846
			switch (currentScope.kind) {
6025
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
6026
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
6027
						continue next;
6028
					}
6029
				}
6030
			}
6031
5847
6032
			boolean prefixRequired = false;
5848
				case Scope.METHOD_SCOPE :
5849
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5850
					MethodScope methodScope = (MethodScope) currentScope;
5851
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5852
					break;
5853
				case Scope.CLASS_SCOPE :
5854
					ClassScope classScope = (ClassScope) currentScope;
5855
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5856
					if(!insideTypeAnnotation) {
6033
5857
6034
			for (int i = methodsFound.size; --i >= 0;) {
5858
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
6035
				Object[] other = (Object[]) methodsFound.elementAt(i);
6036
				MethodBinding otherMethod = (MethodBinding) other[0];
6037
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6038
				if (method == otherMethod && receiverType == otherReceiverType)
6039
					continue next;
6040
5859
6041
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
5860
						int methodsCount = methods == null ? 0 : methods.length;
6042
					if (receiverType == otherReceiverType) {
5861
						for (int i = 0; i < methodsCount; i++) {
6043
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
5862
							AbstractMethodDeclaration methodDeclaration = methods[i];
6044
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
5863
							if (methodDeclaration instanceof MethodDeclaration &&
6045
								continue next;
5864
									CharOperation.equals(methodDeclaration.selector, token)) {
6046
							}
5865
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
6047
						}
5866
								MethodBinding methodBinding = method.binding;
6048
					} else {
5867
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
6049
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
5868
									Argument[] parameters = method.arguments;
6050
							if(receiverType.isAnonymousType()) continue next;
5869
									int parametersLength = parameters == null ? 0 : parameters.length;
5870
									int argumentsLength = arguments == null ? 0 : arguments.length;
6051
5871
6052
							if(!superCall) {
5872
									if (parametersLength == 0) {
6053
								if(!canBePrefixed) continue next;
5873
										if (argumentsLength == 0) {
5874
											findFieldsAndMethodsFromMissingType(
5875
													method.returnType,
5876
													currentScope,
5877
													invocationSite,
5878
													scope);
5879
											break done;
5880
										}
5881
									} else {
5882
										TypeBinding[] parametersBindings;
5883
										if (methodBinding == null) { // since no binding, extra types from type references
5884
											parametersBindings = new TypeBinding[parametersLength];
5885
											for (int j = 0; j < parametersLength; j++) {
5886
												TypeBinding parameterType = parameters[j].type.resolvedType;
5887
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
5888
													parameterType = parameterType.closestMatch();
5889
												}
5890
												parametersBindings[j] = parameterType;
5891
											}
5892
										} else {
5893
											parametersBindings = methodBinding.parameters;
5894
										}
5895
										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
5896
											findFieldsAndMethodsFromMissingType(
5897
													method.returnType,
5898
													currentScope,
5899
													invocationSite,
5900
													scope);
5901
											break done;
5902
										}
5903
									}
5904
								}
6054
5905
6055
								prefixRequired = true;
6056
							}
5906
							}
6057
						}
5907
						}
6058
					}
5908
					}
6059
				}
5909
					staticsOnly |= enclosingType.isStatic();
5910
					insideTypeAnnotation = false;
5911
					break;
5912
				case Scope.COMPILATION_UNIT_SCOPE :
5913
					break done;
6060
			}
5914
			}
5915
			currentScope = currentScope.parent;
5916
		}
5917
	}
6061
5918
6062
			newMethodsFound.add(new Object[]{method, receiverType});
5919
	private void findFieldsAndMethodsFromMissingType(
5920
			TypeReference typeRef,
5921
			final Scope scope,
5922
			final InvocationSite invocationSite,
5923
			final Scope invocationScope) {
5924
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5925
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5926
			new MissingTypesGuesser.GuessedTypeRequestor() {
5927
				public void accept(
5928
						TypeBinding guessedType,
5929
						Binding[] missingElements,
5930
						int[] missingElementsStarts,
5931
						int[] missingElementsEnds,
5932
						boolean hasProblems) {
5933
					findFieldsAndMethods(
5934
						CompletionEngine.this.completionToken,
5935
						guessedType,
5936
						scope,
5937
						new ObjectVector(),
5938
						new ObjectVector(),
5939
						invocationSite,
5940
						invocationScope,
5941
						false,
5942
						false,
5943
						missingElements,
5944
						missingElementsStarts,
5945
						missingElementsEnds,
5946
						hasProblems,
5947
						null,
5948
						-1,
5949
						-1);
6063
5950
6064
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6065
			if (method.declaringClass != superTypeWithSameErasure) {
6066
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6067
				for (int i = 0; i < otherMethods.length; i++) {
6068
					if(otherMethods[i].original() == method.original()) {
6069
						method = otherMethods[i];
6070
					}
6071
				}
5951
				}
6072
			}
5952
			};
6073
5953
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
6074
			int length = method.parameters.length;
5954
	}
6075
			char[][] parameterPackageNames = new char[length][];
6076
			char[][] parameterTypeNames = new char[length][];
6077
6078
			for (int i = 0; i < length; i++) {
6079
				TypeBinding type = method.original().parameters[i];
6080
				parameterPackageNames[i] = type.qualifiedPackageName();
6081
				parameterTypeNames[i] = type.qualifiedSourceName();
6082
			}
6083
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6084
6085
			char[] completion = CharOperation.NO_CHAR;
6086
6087
			int previousStartPosition = this.startPosition;
6088
			int previousTokenStart = this.tokenStart;
6089
5955
6090
			// Special case for completion in javadoc
5956
	private void findFieldsAndMethodsFromStaticImports(
6091
			if (this.assistNodeInJavadoc > 0) {
5957
			char[] token,
6092
				Expression receiver = null;
5958
			Scope scope,
6093
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
5959
			InvocationSite invocationSite,
6094
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
5960
			Scope invocationScope,
6095
					receiver = msg.receiver;
5961
			boolean exactMatch,
6096
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
5962
			boolean insideAnnotationAttribute,
6097
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
5963
			ObjectVector localsFound,
6098
					receiver = fieldRef.receiver;
5964
			ObjectVector fieldsFound,
6099
				}
5965
			ObjectVector methodsFound,
6100
				if (receiver != null) {
5966
			boolean proposeField,
6101
					StringBuffer javadocCompletion = new StringBuffer();
5967
			boolean proposeMethod) {
6102
					if (receiver.isThis()) {
5968
		// search in static import
6103
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
5969
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
6104
							javadocCompletion.append('#');
5970
		for (int i = 0; i < importBindings.length; i++) {
6105
						}
5971
			ImportBinding importBinding = importBindings[i];
6106
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
5972
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
6107
						if (receiver instanceof JavadocSingleTypeReference) {
5973
				Binding binding = importBinding.resolvedImport;
6108
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
5974
				if(binding != null && binding.isValidBinding()) {
6109
							javadocCompletion.append(typeRef.token);
5975
					if(importBinding.onDemand) {
6110
							javadocCompletion.append('#');
5976
						if((binding.kind() & Binding.TYPE) != 0) {
6111
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
5977
							if(proposeField) {
6112
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
5978
								findFields(
6113
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
5979
									token,
6114
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
5980
									(ReferenceBinding)binding,
6115
								if (t>0) javadocCompletion.append('.');
5981
									scope,
6116
								javadocCompletion.append(typeRef.tokens[t]);
5982
									fieldsFound,
5983
									localsFound,
5984
									true,
5985
									invocationSite,
5986
									invocationScope,
5987
									true,
5988
									false,
5989
									null,
5990
									null,
5991
									null,
5992
									false,
5993
									null,
5994
									-1,
5995
									-1);
6117
							}
5996
							}
6118
							javadocCompletion.append('#');
5997
							if(proposeMethod && !insideAnnotationAttribute) {
6119
						}
5998
								findMethods(
6120
					}
5999
									token,
6121
					javadocCompletion.append(method.selector);
6000
									null,
6122
					// Append parameters types
6001
									null,
6123
					javadocCompletion.append('(');
6002
									(ReferenceBinding)binding,
6124
					if (method.parameters != null) {
6003
									scope,
6125
						boolean isVarargs = method.isVarargs();
6004
									methodsFound,
6126
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
6005
									true,
6127
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
6006
									exactMatch,
6128
							TypeBinding argTypeBinding = method.parameters[p];
6007
									invocationSite,
6129
							if (isVarargs && p == ln - 1)  {
6008
									invocationScope,
6130
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
6009
									true,
6131
							} else {
6010
									false,
6132
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
6011
									false,
6012
									null,
6013
									null,
6014
									null,
6015
									false,
6016
									null,
6017
									-1,
6018
									-1);
6133
							}
6019
							}
6134
						}
6020
						}
6135
					}
6136
					javadocCompletion.append(')');
6137
					completion = javadocCompletion.toString().toCharArray();
6138
				}
6139
			} else {
6140
				// nothing to insert - do not want to replace the existing selector & arguments
6141
				if (!exactMatch) {
6142
					if (this.source != null
6143
						&& this.source.length > this.endPosition
6144
						&& this.source[this.endPosition] == '(')
6145
						completion = method.selector;
6146
					else
6147
						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6148
6149
					if (castedReceiver != null) {
6150
						completion = CharOperation.concat(castedReceiver, completion);
6151
					}
6152
				} else {
6153
					if(prefixRequired && (this.source != null)) {
6154
						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
6155
					} else {
6021
					} else {
6156
						this.startPosition = this.endPosition;
6022
						if ((binding.kind() & Binding.FIELD) != 0) {
6157
					}
6023
							if(proposeField) {
6158
					this.tokenStart = this.tokenEnd;
6024
									findFields(
6159
				}
6025
											token,
6160
6026
											new FieldBinding[]{(FieldBinding)binding},
6161
				if(prefixRequired || this.options.forceImplicitQualification){
6027
											scope,
6162
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
6028
											fieldsFound,
6163
					completion = CharOperation.concat(prefix,completion,'.');
6029
											localsFound,
6164
				}
6030
											true,
6165
			}
6031
											((FieldBinding)binding).declaringClass,
6166
6032
											invocationSite,
6167
			int relevance = computeBaseRelevance();
6033
											invocationScope,
6168
			relevance += computeRelevanceForResolution();
6034
											true,
6169
			relevance += computeRelevanceForInterestingProposal();
6035
											false,
6170
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6036
											null,
6171
			relevance += computeRelevanceForExpectingType(method.returnType);
6037
											null,
6172
			relevance += computeRelevanceForEnumConstant(method.returnType);
6038
											null,
6173
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
6039
											false,
6174
			relevance += computeRelevanceForQualification(prefixRequired);
6040
											null,
6175
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6041
											-1,
6176
			if (onlyStaticMethods && this.insideQualifiedReference) {
6042
											-1);
6177
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
6043
							}
6178
			}
6044
						} else if ((binding.kind() & Binding.METHOD) != 0) {
6179
			if (missingElements != null) {
6045
							if(proposeMethod && !insideAnnotationAttribute) {
6180
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
6046
								MethodBinding methodBinding = (MethodBinding)binding;
6181
			}
6047
								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
6182
6048
										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
6183
			this.noProposal = false;
6184
6185
			if (castedReceiver == null) {
6186
				// Standard proposal
6187
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
6188
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6189
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6190
					proposal.setSignature(getSignature(method));
6191
					MethodBinding original = method.original();
6192
					if(original != method) {
6193
						proposal.setOriginalSignature(getSignature(original));
6194
					}
6195
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6196
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6197
					proposal.setParameterPackageNames(parameterPackageNames);
6198
					proposal.setParameterTypeNames(parameterTypeNames);
6199
					proposal.setPackageName(method.returnType.qualifiedPackageName());
6200
					proposal.setTypeName(method.returnType.qualifiedSourceName());
6201
					proposal.setName(method.selector);
6202
					if (missingElements != null) {
6203
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
6204
						for (int i = 0; i < missingElements.length; i++) {
6205
							subProposals[i] =
6206
								createRequiredTypeProposal(
6207
										missingElements[i],
6208
										missingElementsStarts[i],
6209
										missingElementsEnds[i],
6210
										relevance);
6211
						}
6212
						proposal.setRequiredProposals(subProposals);
6213
					}
6214
					proposal.setCompletion(completion);
6215
					proposal.setFlags(method.modifiers);
6216
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6217
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6218
					proposal.setRelevance(relevance);
6219
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
6220
					this.requestor.accept(proposal);
6221
					if(DEBUG) {
6222
						this.printDebug(proposal);
6223
					}
6224
				}
6225
6049
6226
				// Javadoc proposal
6050
									findLocalMethodsFromStaticImports(
6227
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
6051
											methodBinding.selector,
6228
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
6052
											methodBinding.declaringClass.methods(),
6229
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
6053
											scope,
6230
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6054
											exactMatch,
6231
					proposal.setSignature(getSignature(method));
6055
											methodsFound,
6232
					MethodBinding original = method.original();
6056
											methodBinding.declaringClass,
6233
					if(original != method) {
6057
											invocationSite);
6234
						proposal.setOriginalSignature(getSignature(original));
6058
								}
6235
					}
6059
							}
6236
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6237
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6238
					proposal.setParameterPackageNames(parameterPackageNames);
6239
					proposal.setParameterTypeNames(parameterTypeNames);
6240
					proposal.setPackageName(method.returnType.qualifiedPackageName());
6241
					proposal.setTypeName(method.returnType.qualifiedSourceName());
6242
					proposal.setName(method.selector);
6243
					proposal.setCompletion(javadocCompletion);
6244
					proposal.setFlags(method.modifiers);
6245
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
6246
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
6247
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6248
					proposal.setRelevance(relevance+R_INLINE_TAG);
6249
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
6250
					this.requestor.accept(proposal);
6251
					if(DEBUG) {
6252
						this.printDebug(proposal);
6253
					}
6254
				}
6255
			} else {
6256
				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
6257
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
6258
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6259
					proposal.setSignature(getSignature(method));
6260
					MethodBinding original = method.original();
6261
					if(original != method) {
6262
						proposal.setOriginalSignature(getSignature(original));
6263
					}
6264
					proposal.setReceiverSignature(getSignature(receiverType));
6265
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6266
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6267
					proposal.setParameterPackageNames(parameterPackageNames);
6268
					proposal.setParameterTypeNames(parameterTypeNames);
6269
					proposal.setPackageName(method.returnType.qualifiedPackageName());
6270
					proposal.setTypeName(method.returnType.qualifiedSourceName());
6271
					proposal.setName(method.selector);
6272
					if (missingElements != null) {
6273
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
6274
						for (int i = 0; i < missingElements.length; i++) {
6275
							subProposals[i] =
6276
								createRequiredTypeProposal(
6277
										missingElements[i],
6278
										missingElementsStarts[i],
6279
										missingElementsEnds[i],
6280
										relevance);
6281
						}
6060
						}
6282
						proposal.setRequiredProposals(subProposals);
6283
					}
6284
					proposal.setCompletion(completion);
6285
					proposal.setFlags(method.modifiers);
6286
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6287
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
6288
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6289
					proposal.setRelevance(relevance);
6290
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
6291
					this.requestor.accept(proposal);
6292
					if(DEBUG) {
6293
						this.printDebug(proposal);
6294
					}
6061
					}
6295
				}
6062
				}
6296
			}
6063
			}
6297
			this.startPosition = previousStartPosition;
6298
			this.tokenStart = previousTokenStart;
6299
		}
6064
		}
6300
6301
		methodsFound.addAll(newMethodsFound);
6302
	}
6065
	}
6303
6066
6304
	private void findLocalMethodsFromFavorites(
6067
	private void findFieldsFromFavorites(
6305
			char[] methodName,
6068
			char[] fieldName,
6306
			MethodBinding[] methods,
6069
			FieldBinding[] fields,
6307
			Scope scope,
6070
			Scope scope,
6308
			ObjectVector methodsFound,
6071
			ObjectVector fieldsFound,
6309
			ObjectVector methodsFoundFromFavorites,
6072
			ObjectVector localsFound,
6310
			ReferenceBinding receiverType,
6073
			ReferenceBinding receiverType,
6311
			InvocationSite invocationSite,
6074
			InvocationSite invocationSite,
6312
			Scope invocationScope) {
6075
			Scope invocationScope) {
6313
6076
6314
			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
6077
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
6315
6078
6316
			int methodLength = methodName.length;
6079
		int fieldLength = fieldName.length;
6080
		next : for (int f = fields.length; --f >= 0;) {
6081
			FieldBinding field = fields[f];
6317
6082
6318
			next : for (int f = methods.length; --f >= 0;) {
6083
			if (field.isSynthetic())	continue next;
6319
				MethodBinding method = methods[f];
6084
6085
			// only static fields must be proposed
6086
			if (!field.isStatic()) continue next;
6087
6088
			if (fieldLength > field.name.length) continue next;
6089
6090
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
6091
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
6092
6093
			if (this.options.checkDeprecation &&
6094
					field.isViewedAsDeprecated() &&
6095
					!scope.isDefinedInSameUnit(field.declaringClass))
6096
				continue next;
6097
6098
			if (this.options.checkVisibility
6099
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
6100
6101
			for (int i = fieldsFound.size; --i >= 0;) {
6102
				Object[] other = (Object[])fieldsFound.elementAt(i);
6103
				FieldBinding otherField = (FieldBinding) other[0];
6104
6105
				if (field == otherField) continue next;
6106
			}
6107
6108
			fieldsFound.add(new Object[]{field, receiverType});
6109
6110
			int relevance = computeBaseRelevance();
6111
			relevance += computeRelevanceForResolution();
6112
			relevance += computeRelevanceForInterestingProposal(field);
6113
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6114
			relevance += computeRelevanceForExpectingType(field.type);
6115
			relevance += computeRelevanceForEnumConstant(field.type);
6116
			relevance += computeRelevanceForStatic(true, true);
6117
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6320
6118
6321
				if (method.isSynthetic()) continue next;
6119
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6120
			int importStart = cu.types[0].declarationSourceStart;
6121
			int importEnd = importStart;
6322
6122
6323
				if (method.isDefaultAbstract())	continue next;
6123
			this.noProposal = false;
6324
6124
6325
				if (method.isConstructor()) continue next;
6125
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
6126
					!this.options.suggestStaticImport) {
6127
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
6128
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
6326
6129
6327
				if (this.options.checkDeprecation &&
6130
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6328
						method.isViewedAsDeprecated() &&
6131
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6329
						!scope.isDefinedInSameUnit(method.declaringClass))
6132
					proposal.setSignature(getSignature(field.type));
6330
					continue next;
6133
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6134
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6135
					proposal.setPackageName(field.type.qualifiedPackageName());
6136
					proposal.setTypeName(field.type.qualifiedSourceName());
6137
					proposal.setName(field.name);
6138
					proposal.setCompletion(completion);
6139
					proposal.setFlags(field.modifiers);
6140
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6141
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6142
					proposal.setRelevance(relevance);
6331
6143
6332
				if (!method.isStatic()) continue next;
6144
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
6333
6145
6334
				if (this.options.checkVisibility
6146
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
6335
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
6147
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
6148
					typeImportProposal.completionEngine = this;
6149
					char[] packageName = receiverType.qualifiedPackageName();
6150
					typeImportProposal.setDeclarationSignature(packageName);
6151
					typeImportProposal.setSignature(getSignature(receiverType));
6152
					typeImportProposal.setPackageName(packageName);
6153
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
6154
					typeImportProposal.setCompletion(typeImportCompletion);
6155
					typeImportProposal.setFlags(receiverType.modifiers);
6156
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
6157
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6158
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6159
					typeImportProposal.setRelevance(relevance);
6336
6160
6337
				if (methodLength > method.selector.length) continue next;
6161
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
6338
6162
6339
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6163
					this.requestor.accept(proposal);
6340
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6164
					if(DEBUG) {
6341
					continue next;
6165
						this.printDebug(proposal);
6166
					}
6342
				}
6167
				}
6168
			} else {
6169
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
6170
					char[] completion = field.name;
6343
6171
6344
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
6172
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6345
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
6173
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6346
					MethodBinding otherMethod = (MethodBinding) other[0];
6174
					proposal.setSignature(getSignature(field.type));
6175
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6176
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6177
					proposal.setPackageName(field.type.qualifiedPackageName());
6178
					proposal.setTypeName(field.type.qualifiedSourceName());
6179
					proposal.setName(field.name);
6180
					proposal.setCompletion(completion);
6181
					proposal.setFlags(field.modifiers);
6182
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6183
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6184
					proposal.setRelevance(relevance);
6347
6185
6348
					if (method == otherMethod) continue next;
6186
					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
6349
6187
6350
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6188
					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
6351
						if (otherMethod.declaringClass == method.declaringClass &&
6189
					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
6352
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6190
					fieldImportProposal.setSignature(getSignature(field.type));
6353
							continue next;
6191
					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6354
						}
6192
					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6193
					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
6194
					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
6195
					fieldImportProposal.setName(field.name);
6196
					fieldImportProposal.setCompletion(fieldImportCompletion);
6197
					fieldImportProposal.setFlags(field.modifiers);
6198
					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
6199
					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6200
					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6201
					fieldImportProposal.setRelevance(relevance);
6202
6203
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
6204
6205
					this.requestor.accept(proposal);
6206
					if(DEBUG) {
6207
						this.printDebug(proposal);
6355
					}
6208
					}
6356
				}
6209
				}
6210
			}
6211
		}
6212
	}
6213
	private void findImplicitMessageSends(
6214
		char[] token,
6215
		TypeBinding[] argTypes,
6216
		Scope scope,
6217
		InvocationSite invocationSite,
6218
		Scope invocationScope,
6219
		ObjectVector methodsFound) {
6357
6220
6358
				for (int i = methodsFound.size; --i >= 0;) {
6221
		if (token == null)
6359
					Object[] other = (Object[]) methodsFound.elementAt(i);
6222
			return;
6360
					MethodBinding otherMethod = (MethodBinding) other[0];
6361
6223
6362
					if (method == otherMethod) continue next;
6224
		boolean staticsOnly = false;
6225
		// need to know if we're in a static context (or inside a constructor)
6363
6226
6364
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6227
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
6365
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6366
							continue next;
6367
						}
6368
					}
6369
				}
6370
6228
6371
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
6229
			switch (scope.kind) {
6372
					this.options.suggestStaticImport;
6373
6230
6374
				boolean isAlreadyImported = false;
6231
				case Scope.METHOD_SCOPE :
6375
				if (!proposeStaticImport) {
6232
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
6376
					if(!this.importCachesInitialized) {
6233
					MethodScope methodScope = (MethodScope) scope;
6377
						initializeImportCaches();
6234
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
6378
					}
6235
					break;
6379
					for (int j = 0; j < this.importCacheCount; j++) {
6380
						char[][] importName = this.importsCache[j];
6381
						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
6382
							if (!CharOperation.equals(typeName, importName[1])) {
6383
								continue next;
6384
							} else {
6385
								isAlreadyImported = true;
6386
							}
6387
						}
6388
					}
6389
				}
6390
6236
6391
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
6237
				case Scope.CLASS_SCOPE :
6238
					ClassScope classScope = (ClassScope) scope;
6239
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
6240
					findMethods(
6241
						token,
6242
						null,
6243
						argTypes,
6244
						enclosingType,
6245
						classScope,
6246
						methodsFound,
6247
						staticsOnly,
6248
						true,
6249
						invocationSite,
6250
						invocationScope,
6251
						true,
6252
						false,
6253
						true,
6254
						null,
6255
						null,
6256
						null,
6257
						false,
6258
						null,
6259
						-1,
6260
						-1);
6261
					staticsOnly |= enclosingType.isStatic();
6262
					break;
6392
6263
6393
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6264
				case Scope.COMPILATION_UNIT_SCOPE :
6394
				if (method.declaringClass != superTypeWithSameErasure) {
6265
					break done;
6395
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6266
			}
6396
					for (int i = 0; i < otherMethods.length; i++) {
6267
			scope = scope.parent;
6397
						if(otherMethods[i].original() == method.original()) {
6268
		}
6398
							method = otherMethods[i];
6269
	}
6399
						}
6270
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
6400
					}
6271
		char[][] tokens = importReference.tokens;
6401
				}
6402
6272
6403
				int length = method.parameters.length;
6273
		char[] importName = CharOperation.concatWith(tokens, '.');
6404
				char[][] parameterPackageNames = new char[length][];
6405
				char[][] parameterTypeNames = new char[length][];
6406
6274
6407
				for (int i = 0; i < length; i++) {
6275
		if (importName.length == 0)
6408
					TypeBinding type = method.original().parameters[i];
6276
			return;
6409
					parameterPackageNames[i] = type.qualifiedPackageName();
6410
					parameterTypeNames[i] = type.qualifiedSourceName();
6411
				}
6412
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6413
6277
6414
				char[] completion = CharOperation.NO_CHAR;
6278
		char[] lastToken = tokens[tokens.length - 1];
6279
		if(lastToken != null && lastToken.length == 0)
6280
			importName = CharOperation.concat(importName, new char[]{'.'});
6415
6281
6416
				int previousStartPosition = this.startPosition;
6282
		this.resolvingImports = true;
6417
				int previousTokenStart = this.tokenStart;
6283
		this.resolvingStaticImports = importReference.isStatic();
6418
6284
6419
				if (this.source != null
6285
		this.completionToken =  lastToken;
6420
					&& this.source.length > this.endPosition
6286
		this.qualifiedCompletionToken = importName;
6421
					&& this.source[this.endPosition] == '(') {
6422
					completion = method.selector;
6423
				} else {
6424
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6425
				}
6426
6287
6427
				int relevance = computeBaseRelevance();
6288
		// want to replace the existing .*;
6428
				relevance += computeRelevanceForResolution();
6289
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
6429
				relevance += computeRelevanceForInterestingProposal();
6290
			int oldStart = this.startPosition;
6430
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6291
			int oldEnd = this.endPosition;
6431
				relevance += computeRelevanceForExpectingType(method.returnType);
6292
			setSourceRange(
6432
				relevance += computeRelevanceForEnumConstant(method.returnType);
6293
				importReference.sourceStart,
6433
				relevance += computeRelevanceForStatic(true, method.isStatic());
6294
				importReference.declarationSourceEnd);
6434
				relevance += computeRelevanceForQualification(true);
6295
			this.nameEnvironment.findPackages(importName, this);
6435
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6296
			setSourceRange(
6297
				oldStart,
6298
				oldEnd - 1,
6299
				false);
6300
		}
6301
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6302
			this.nameEnvironment.findTypes(
6303
					importName,
6304
					findMembers,
6305
					this.options.camelCaseMatch,
6306
					IJavaSearchConstants.TYPE,
6307
					this);
6308
			acceptTypes(null);
6309
		}
6310
	}
6436
6311
6437
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6312
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
6438
				int importStart = cu.types[0].declarationSourceStart;
6313
		ReferenceBinding[] memberTypes = ref.memberTypes();
6439
				int importEnd = importStart;
6440
6314
6441
				this.noProposal = false;
6315
		int typeLength = typeName.length;
6316
		next : for (int m = memberTypes.length; --m >= 0;) {
6317
			ReferenceBinding memberType = memberTypes[m];
6318
			//		if (!wantClasses && memberType.isClass()) continue next;
6319
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
6442
6320
6443
				if (!proposeStaticImport) {
6321
			if (onlyStatic && !memberType.isStatic())
6444
					if (isAlreadyImported) {
6322
				continue next;
6445
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
6446
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6447
6323
6448
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6324
			if (typeLength > memberType.sourceName.length)
6449
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
6325
				continue next;
6450
							proposal.setSignature(getSignature(method));
6451
							MethodBinding original = method.original();
6452
							if(original != method) {
6453
								proposal.setOriginalSignature(getSignature(original));
6454
							}
6455
							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6456
							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6457
							proposal.setParameterPackageNames(parameterPackageNames);
6458
							proposal.setParameterTypeNames(parameterTypeNames);
6459
							proposal.setPackageName(method.returnType.qualifiedPackageName());
6460
							proposal.setTypeName(method.returnType.qualifiedSourceName());
6461
							proposal.setName(method.selector);
6462
							proposal.setCompletion(completion);
6463
							proposal.setFlags(method.modifiers);
6464
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6465
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6466
							proposal.setRelevance(relevance);
6467
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
6468
6326
6469
							this.requestor.accept(proposal);
6327
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
6470
							if(DEBUG) {
6328
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
6471
								this.printDebug(proposal);
6329
				continue next;
6472
							}
6473
						}
6474
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
6475
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6476
6330
6477
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6331
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
6478
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6479
						proposal.setSignature(getSignature(method));
6480
						MethodBinding original = method.original();
6481
						if(original != method) {
6482
							proposal.setOriginalSignature(getSignature(original));
6483
						}
6484
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6485
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6486
						proposal.setParameterPackageNames(parameterPackageNames);
6487
						proposal.setParameterTypeNames(parameterTypeNames);
6488
						proposal.setPackageName(method.returnType.qualifiedPackageName());
6489
						proposal.setTypeName(method.returnType.qualifiedSourceName());
6490
						proposal.setName(method.selector);
6491
						proposal.setCompletion(completion);
6492
						proposal.setFlags(method.modifiers);
6493
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6494
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6495
						proposal.setRelevance(relevance);
6496
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
6497
6332
6498
						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
6333
			if (this.options.checkVisibility
6334
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
6335
				continue next;
6499
6336
6500
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
6337
			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
6501
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
6502
						typeImportProposal.completionEngine = this;
6503
						char[] packageName = receiverType.qualifiedPackageName();
6504
						typeImportProposal.setDeclarationSignature(packageName);
6505
						typeImportProposal.setSignature(getSignature(receiverType));
6506
						typeImportProposal.setPackageName(packageName);
6507
						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
6508
						typeImportProposal.setCompletion(typeImportCompletion);
6509
						typeImportProposal.setFlags(receiverType.modifiers);
6510
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
6511
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6512
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6513
						typeImportProposal.setRelevance(relevance);
6514
6338
6515
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
6339
			int relevance = computeBaseRelevance();
6340
			relevance += computeRelevanceForResolution();
6341
			relevance += computeRelevanceForInterestingProposal();
6342
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
6343
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6516
6344
6517
						this.requestor.accept(proposal);
6345
			if (memberType.isClass()) {
6518
						if(DEBUG) {
6346
				relevance += computeRelevanceForClass();
6519
							this.printDebug(proposal);
6347
			} else if(memberType.isEnum()) {
6520
						}
6348
				relevance += computeRelevanceForEnum();
6521
					}
6349
			} else if (memberType.isInterface()) {
6522
				} else {
6350
				relevance += computeRelevanceForInterface();
6523
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
6351
			}
6524
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6352
			this.noProposal = false;
6525
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6353
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6526
						proposal.setSignature(getSignature(method));
6354
				createTypeProposal(
6527
						MethodBinding original = method.original();
6355
						memberType,
6528
						if(original != method) {
6356
						memberType.qualifiedSourceName(),
6529
							proposal.setOriginalSignature(getSignature(original));
6357
						IAccessRule.K_ACCESSIBLE,
6530
						}
6358
						completionName,
6531
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6359
						relevance,
6532
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6360
						null,
6533
						proposal.setParameterPackageNames(parameterPackageNames);
6361
						null,
6534
						proposal.setParameterTypeNames(parameterTypeNames);
6362
						null,
6535
						proposal.setPackageName(method.returnType.qualifiedPackageName());
6363
						false);
6536
						proposal.setTypeName(method.returnType.qualifiedSourceName());
6364
			}
6537
						proposal.setName(method.selector);
6365
		}
6538
						proposal.setCompletion(completion);
6366
	}
6539
						proposal.setFlags(method.modifiers);
6540
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6541
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6542
						proposal.setRelevance(relevance);
6543
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
6544
6367
6545
						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
6368
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
6369
		FieldBinding[] fields = ref.availableFields();
6546
6370
6547
						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
6371
		int fieldLength = fieldName.length;
6548
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
6372
		next : for (int m = fields.length; --m >= 0;) {
6549
						methodImportProposal.setSignature(getSignature(method));
6373
			FieldBinding field = fields[m];
6550
						if(original != method) {
6551
							proposal.setOriginalSignature(getSignature(original));
6552
						}
6553
						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6554
						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6555
						methodImportProposal.setParameterPackageNames(parameterPackageNames);
6556
						methodImportProposal.setParameterTypeNames(parameterTypeNames);
6557
						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
6558
						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
6559
						methodImportProposal.setName(method.selector);
6560
						methodImportProposal.setCompletion(methodImportCompletion);
6561
						methodImportProposal.setFlags(method.modifiers);
6562
						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
6563
						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6564
						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6565
						methodImportProposal.setRelevance(relevance);
6566
						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
6567
6374
6568
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
6375
			if (fieldLength > field.name.length)
6376
				continue next;
6569
6377
6570
						this.requestor.accept(proposal);
6378
			if (field.isSynthetic())
6571
						if(DEBUG) {
6379
				continue next;
6572
							this.printDebug(proposal);
6573
						}
6574
					}
6575
				}
6576
6380
6577
				this.startPosition = previousStartPosition;
6381
			if (!field.isStatic())
6578
				this.tokenStart = previousTokenStart;
6382
				continue next;
6579
			}
6580
		}
6581
6383
6582
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
6384
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
6583
		InternalCompletionProposal proposal = null;
6385
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
6584
		if (binding instanceof ReferenceBinding) {
6386
				continue next;
6585
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
6586
6387
6587
			char[] packageName = typeBinding.qualifiedPackageName();
6388
			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
6588
			char[] typeName = typeBinding.qualifiedSourceName();
6589
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
6590
6389
6591
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
6390
			if (this.options.checkVisibility
6592
			proposal.nameLookup = this.nameEnvironment.nameLookup;
6391
				&& !field.canBeSeenBy(this.unitScope.fPackage))
6593
			proposal.completionEngine = this;
6392
				continue next;
6594
			proposal.setDeclarationSignature(packageName);
6595
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
6596
			proposal.setPackageName(packageName);
6597
			proposal.setTypeName(typeName);
6598
			proposal.setCompletion(fullyQualifiedName);
6599
			proposal.setFlags(typeBinding.modifiers);
6600
			proposal.setReplaceRange(start - this.offset, end - this.offset);
6601
			proposal.setTokenRange(start - this.offset, end - this.offset);
6602
			proposal.setRelevance(relevance);
6603
		} else if (binding instanceof PackageBinding) {
6604
			PackageBinding packageBinding = (PackageBinding) binding;
6605
6393
6606
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
6394
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
6607
6395
6608
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
6396
			int relevance = computeBaseRelevance();
6609
			proposal.setDeclarationSignature(packageName);
6397
			relevance += computeRelevanceForResolution();
6610
			proposal.setPackageName(packageName);
6398
			relevance += computeRelevanceForInterestingProposal();
6611
			proposal.setCompletion(packageName);
6399
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6612
			proposal.setReplaceRange(start - this.offset, end - this.offset);
6400
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6613
			proposal.setTokenRange(start - this.offset, end - this.offset);
6614
			proposal.setRelevance(relevance);
6615
		}
6616
		return proposal;
6617
	}
6618
6401
6619
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6402
			this.noProposal = false;
6620
	private void findLocalMethodsFromStaticImports(
6403
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
6621
		char[] methodName,
6404
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6622
		MethodBinding[] methods,
6405
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
6623
		Scope scope,
6406
				proposal.setSignature(getSignature(field.type));
6624
		boolean exactMatch,
6407
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6625
		ObjectVector methodsFound,
6408
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6626
		ReferenceBinding receiverType,
6409
				proposal.setPackageName(field.type.qualifiedPackageName());
6627
		InvocationSite invocationSite) {
6410
				proposal.setTypeName(field.type.qualifiedSourceName());
6411
				proposal.setName(field.name);
6412
				proposal.setCompletion(completionName);
6413
				proposal.setFlags(field.modifiers);
6414
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6415
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6416
				proposal.setRelevance(relevance);
6417
				this.requestor.accept(proposal);
6418
				if(DEBUG) {
6419
					this.printDebug(proposal);
6420
				}
6421
			}
6422
		}
6423
	}
6628
6424
6629
		ObjectVector newMethodsFound =  new ObjectVector();
6425
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
6426
		MethodBinding[] methods = ref.availableMethods();
6630
6427
6631
		next : for (int f = methods.length; --f >= 0;) {
6428
		int methodLength = methodName.length;
6632
			MethodBinding method = methods[f];
6429
		next : for (int m = methods.length; --m >= 0;) {
6430
			MethodBinding method = methods[m];
6633
6431
6634
			if (method.isSynthetic()) continue next;
6432
			if (method.isSynthetic()) continue next;
6635
6433
Lines 6639-6671 Link Here
6639
6437
6640
			if (!method.isStatic()) continue next;
6438
			if (!method.isStatic()) continue next;
6641
6439
6642
			if (this.options.checkDeprecation &&
6440
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
6643
					method.isViewedAsDeprecated() &&
6644
					!scope.isDefinedInSameUnit(method.declaringClass))
6645
				continue next;
6646
6441
6647
			if (this.options.checkVisibility
6442
			if (this.options.checkVisibility
6648
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
6443
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
6649
6444
6650
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
6445
			if (methodLength > method.selector.length)
6651
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6652
				continue next;
6446
				continue next;
6653
6447
6654
			for (int i = methodsFound.size; --i >= 0;) {
6448
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
6655
				Object[] other = (Object[]) methodsFound.elementAt(i);
6449
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6656
				MethodBinding otherMethod = (MethodBinding) other[0];
6450
				continue next;
6657
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6658
				if (method == otherMethod && receiverType == otherReceiverType)
6659
					continue next;
6660
6661
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6662
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6663
						continue next;
6664
					}
6665
				}
6666
			}
6667
6668
			newMethodsFound.add(new Object[]{method, receiverType});
6669
6451
6670
			int length = method.parameters.length;
6452
			int length = method.parameters.length;
6671
			char[][] parameterPackageNames = new char[length][];
6453
			char[][] parameterPackageNames = new char[length][];
Lines 6678-6720 Link Here
6678
			}
6460
			}
6679
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6461
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6680
6462
6681
			char[] completion = CharOperation.NO_CHAR;
6463
			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
6682
6683
			int previousStartPosition = this.startPosition;
6684
			int previousTokenStart = this.tokenStart;
6685
6686
			if (!exactMatch) {
6687
				if (this.source != null
6688
					&& this.source.length > this.endPosition
6689
					&& this.source[this.endPosition] == '(') {
6690
					completion = method.selector;
6691
				} else {
6692
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6693
				}
6694
			} else {
6695
				this.startPosition = this.endPosition;
6696
				this.tokenStart = this.tokenEnd;
6697
			}
6698
6464
6699
			int relevance = computeBaseRelevance();
6465
			int relevance = computeBaseRelevance();
6700
			relevance += computeRelevanceForResolution();
6466
			relevance += computeRelevanceForResolution();
6701
			relevance += computeRelevanceForInterestingProposal();
6467
			relevance += computeRelevanceForInterestingProposal();
6702
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6468
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6703
			relevance += computeRelevanceForExpectingType(method.returnType);
6704
			relevance += computeRelevanceForEnumConstant(method.returnType);
6705
			relevance += computeRelevanceForStatic(true, method.isStatic());
6706
			relevance += computeRelevanceForQualification(false);
6707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6469
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6708
6470
6709
			this.noProposal = false;
6471
			this.noProposal = false;
6710
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
6472
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
6711
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6473
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
6712
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6474
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6713
				proposal.setSignature(getSignature(method));
6475
				proposal.setSignature(getSignature(method));
6714
				MethodBinding original = method.original();
6715
				if(original != method) {
6716
					proposal.setOriginalSignature(getSignature(original));
6717
				}
6718
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6476
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6719
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6477
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6720
				proposal.setParameterPackageNames(parameterPackageNames);
6478
				proposal.setParameterPackageNames(parameterPackageNames);
Lines 6722-6728 Link Here
6722
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6480
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6723
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6481
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6724
				proposal.setName(method.selector);
6482
				proposal.setName(method.selector);
6725
				proposal.setCompletion(completion);
6483
				proposal.setCompletion(completionName);
6726
				proposal.setFlags(method.modifiers);
6484
				proposal.setFlags(method.modifiers);
6727
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6485
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6728
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6486
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
Lines 6733-6927 Link Here
6733
					this.printDebug(proposal);
6491
					this.printDebug(proposal);
6734
				}
6492
				}
6735
			}
6493
			}
6736
			this.startPosition = previousStartPosition;
6737
			this.tokenStart = previousTokenStart;
6738
		}
6739
6740
		methodsFound.addAll(newMethodsFound);
6741
	}
6742
	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
6743
		if (this.options.camelCaseMatch) {
6744
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
6745
				return R_CASE + R_EXACT_NAME;
6746
			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
6747
				return R_CASE;
6748
			} else if (CharOperation.camelCaseMatch(token, proposalName)){
6749
				return R_CAMEL_CASE;
6750
			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
6751
				return R_EXACT_NAME;
6752
			}
6753
		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
6754
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
6755
				return R_CASE + R_EXACT_NAME;
6756
			} else {
6757
				return R_CASE;
6758
			}
6759
		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
6760
			return R_EXACT_NAME;
6761
		}
6762
		return 0;
6763
	}
6764
	private int computeRelevanceForAnnotation(){
6765
		if(this.assistNodeIsAnnotation) {
6766
			return R_ANNOTATION;
6767
		}
6494
		}
6768
		return 0;
6769
	}
6495
	}
6770
	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
6496
	
6771
		if (this.assistNodeIsAnnotation &&
6497
	private void findInterfacesMethodDeclarations(
6772
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
6498
		char[] selector,
6773
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
6499
		ReferenceBinding receiverType,
6774
			if(target == 0 || (target & this.targetedElement) != 0) {
6500
		ReferenceBinding[] itsInterfaces,
6775
				return R_TARGET;
6501
		Scope scope,
6502
		ObjectVector methodsFound,
6503
		Binding[] missingElements,
6504
		int[] missingElementssStarts,
6505
		int[] missingElementsEnds,
6506
		boolean missingElementsHaveProblems) {
6507
6508
		if (selector == null)
6509
			return;
6510
6511
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6512
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6513
			int nextPosition = interfacesToVisit.length;
6514
6515
			for (int i = 0; i < nextPosition; i++) {
6516
				ReferenceBinding currentType = interfacesToVisit[i];
6517
				MethodBinding[] methods = currentType.availableMethods();
6518
				if(methods != null) {
6519
					findLocalMethodDeclarations(
6520
						selector,
6521
						methods,
6522
						scope,
6523
						methodsFound,
6524
						false,
6525
						receiverType);
6526
				}
6527
6528
				itsInterfaces = currentType.superInterfaces();
6529
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6530
					int itsLength = itsInterfaces.length;
6531
					if (nextPosition + itsLength >= interfacesToVisit.length)
6532
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6533
					nextInterface : for (int a = 0; a < itsLength; a++) {
6534
						ReferenceBinding next = itsInterfaces[a];
6535
						for (int b = 0; b < nextPosition; b++)
6536
							if (next == interfacesToVisit[b]) continue nextInterface;
6537
						interfacesToVisit[nextPosition++] = next;
6538
					}
6539
				}
6776
			}
6540
			}
6777
		}
6541
		}
6778
		return 0;
6779
	}
6780
	private int computeRelevanceForClass(){
6781
		if(this.assistNodeIsClass) {
6782
			return R_CLASS;
6783
		}
6784
		return 0;
6785
	}
6786
	private int computeRelevanceForEnum(){
6787
		if(this.assistNodeIsEnum) {
6788
			return R_ENUM;
6789
		}
6790
		return 0;
6791
	}
6792
	private int computeRelevanceForInterface(){
6793
		if(this.assistNodeIsInterface) {
6794
			return R_INTERFACE;
6795
		}
6796
		return 0;
6797
	}
6798
	private int computeRelevanceForMissingElements(boolean hasProblems) {
6799
		if (!hasProblems) {
6800
			return R_NO_PROBLEMS;
6801
		}
6802
		return 0;
6803
	}
6542
	}
6804
	int computeRelevanceForQualification(boolean prefixRequired) {
6543
	
6805
		if(!prefixRequired && !this.insideQualifiedReference) {
6544
	private void findInterfacesMethods(
6806
			return R_UNQUALIFIED;
6545
		char[] selector,
6807
		}
6546
		TypeBinding[] typeArgTypes,
6547
		TypeBinding[] argTypes,
6548
		ReferenceBinding receiverType,
6549
		ReferenceBinding[] itsInterfaces,
6550
		Scope scope,
6551
		ObjectVector methodsFound,
6552
		boolean onlyStaticMethods,
6553
		boolean exactMatch,
6554
		InvocationSite invocationSite,
6555
		Scope invocationScope,
6556
		boolean implicitCall,
6557
		boolean superCall,
6558
		boolean canBePrefixed,
6559
		Binding[] missingElements,
6560
		int[] missingElementssStarts,
6561
		int[] missingElementsEnds,
6562
		boolean missingElementsHaveProblems,
6563
		char[] castedReceiver,
6564
		int receiverStart,
6565
		int receiverEnd) {
6808
6566
6809
		if(prefixRequired && this.insideQualifiedReference) {
6567
		if (selector == null)
6810
			return R_QUALIFIED;
6568
			return;
6569
6570
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6571
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6572
			int nextPosition = interfacesToVisit.length;
6573
6574
			for (int i = 0; i < nextPosition; i++) {
6575
				ReferenceBinding currentType = interfacesToVisit[i];
6576
				MethodBinding[] methods = currentType.availableMethods();
6577
				if(methods != null) {
6578
					findLocalMethods(
6579
						selector,
6580
						typeArgTypes,
6581
						argTypes,
6582
						methods,
6583
						scope,
6584
						methodsFound,
6585
						onlyStaticMethods,
6586
						exactMatch,
6587
						receiverType,
6588
						invocationSite,
6589
						invocationScope,
6590
						implicitCall,
6591
						superCall,
6592
						canBePrefixed,
6593
						missingElements,
6594
						missingElementssStarts,
6595
						missingElementsEnds,
6596
						missingElementsHaveProblems,
6597
						castedReceiver,
6598
						receiverStart,
6599
						receiverEnd);
6600
				}
6601
6602
				itsInterfaces = currentType.superInterfaces();
6603
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6604
					int itsLength = itsInterfaces.length;
6605
					if (nextPosition + itsLength >= interfacesToVisit.length)
6606
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6607
					nextInterface : for (int a = 0; a < itsLength; a++) {
6608
						ReferenceBinding next = itsInterfaces[a];
6609
						for (int b = 0; b < nextPosition; b++)
6610
							if (next == interfacesToVisit[b]) continue nextInterface;
6611
						interfacesToVisit[nextPosition++] = next;
6612
					}
6613
				}
6614
			}
6811
		}
6615
		}
6812
		return 0;
6813
	}
6616
	}
6814
	int computeRelevanceForRestrictions(int accessRuleKind) {
6617
	/*
6815
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
6618
	 * Find javadoc block tags for a given completion javadoc tag node
6816
			return R_NON_RESTRICTED;
6619
	 */
6620
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
6621
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
6622
		if (possibleTags == null) return;
6623
		int length = possibleTags.length;
6624
		for (int i=0; i<length; i++) {
6625
			int relevance = computeBaseRelevance();
6626
			relevance += computeRelevanceForInterestingProposal();
6627
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6628
6629
			this.noProposal = false;
6630
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
6631
				char[] possibleTag = possibleTags[i];
6632
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
6633
				proposal.setName(possibleTag);
6634
				int tagLength = possibleTag.length;
6635
				char[] completion = new char[1+tagLength];
6636
				completion[0] = '@';
6637
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
6638
				proposal.setCompletion(completion);
6639
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6640
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6641
				proposal.setRelevance(relevance);
6642
				this.requestor.accept(proposal);
6643
				if (DEBUG) {
6644
					this.printDebug(proposal);
6645
				}
6646
			}
6817
		}
6647
		}
6818
		return 0;
6819
	}
6648
	}
6820
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
6649
6821
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
6650
	/*
6822
			return R_NON_STATIC;
6651
	 * Find javadoc inline tags for a given completion javadoc tag node
6652
	 */
6653
	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
6654
		char[][] possibleTags = javadocTag.getPossibleInlineTags();
6655
		if (possibleTags == null) return;
6656
		int length = possibleTags.length;
6657
		for (int i=0; i<length; i++) {
6658
			int relevance = computeBaseRelevance();
6659
			relevance += computeRelevanceForInterestingProposal();
6660
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6661
6662
			this.noProposal = false;
6663
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
6664
				char[] possibleTag = possibleTags[i];
6665
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
6666
				proposal.setName(possibleTag);
6667
				int tagLength = possibleTag.length;
6668
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
6669
				char[] completion = new char[2+tagLength+1];
6670
				completion[0] = '{';
6671
				completion[1] = '@';
6672
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
6673
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
6674
				//completion[tagLength+2] = ' ';
6675
				completion[tagLength+2] = '}';
6676
				proposal.setCompletion(completion);
6677
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6678
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6679
				proposal.setRelevance(relevance);
6680
				this.requestor.accept(proposal);
6681
				if (DEBUG) {
6682
					this.printDebug(proposal);
6683
				}
6684
			}
6823
		}
6685
		}
6824
		return 0;
6825
	}
6686
	}
6826
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
6827
		if(this.assistNodeIsEnum &&
6828
				proposalType != null &&
6829
				this.expectedTypes != null) {
6830
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
6831
				if (proposalType.isEnum() &&
6832
						proposalType == this.expectedTypes[i]) {
6833
					return R_ENUM + R_ENUM_CONSTANT;
6834
				}
6835
6687
6688
	/*
6689
	 * Find javadoc parameter names.
6690
	 */
6691
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
6692
6693
		if (missingParams == null) return;
6694
6695
		// Get relevance
6696
		int relevance = computeBaseRelevance();
6697
		relevance += computeRelevanceForInterestingProposal();
6698
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
6699
		if (!isTypeParam) relevance += R_INTERESTING;
6700
6701
		// Propose missing param
6702
		int length = missingParams.length;
6703
		relevance += length;
6704
		for (int i=0; i<length; i++) {
6705
			char[] argName = missingParams[i];
6706
			if (token == null || CharOperation.prefixEquals(token, argName)) {
6707
6708
				this.noProposal = false;
6709
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
6710
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
6711
					proposal.setName(argName);
6712
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
6713
					proposal.setCompletion(completion);
6714
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6715
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6716
					proposal.setRelevance(--relevance);
6717
					this.requestor.accept(proposal);
6718
					if (DEBUG) {
6719
						this.printDebug(proposal);
6720
					}
6721
				}
6836
			}
6722
			}
6837
		}
6723
		}
6838
		return 0;
6839
	}
6724
	}
6840
	private int computeRelevanceForException(){
6725
6841
		if (this.assistNodeIsException) {
6726
	// what about onDemand types? Ignore them since it does not happen!
6842
			return R_EXCEPTION;
6727
	// import p1.p2.A.*;
6843
		}
6728
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
6844
		return 0;
6729
		if(choices == null || choices.length == 0) return;
6730
6731
		int length = keyword.length;
6732
		if (canCompleteEmptyToken || length > 0)
6733
			for (int i = 0; i < choices.length; i++)
6734
				if (length <= choices[i].length
6735
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
6736
				)){
6737
					int relevance = computeBaseRelevance();
6738
					relevance += computeRelevanceForResolution();
6739
					relevance += computeRelevanceForInterestingProposal();
6740
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
6741
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
6742
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
6743
6744
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
6745
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
6746
						relevance += computeRelevanceForQualification(false);
6747
					}
6748
					this.noProposal = false;
6749
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
6750
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
6751
						proposal.setName(choices[i]);
6752
						proposal.setCompletion(choices[i]);
6753
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6754
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6755
						proposal.setRelevance(relevance);
6756
						this.requestor.accept(proposal);
6757
						if(DEBUG) {
6758
							this.printDebug(proposal);
6759
						}
6760
					}
6761
				}
6845
	}
6762
	}
6846
	private int computeRelevanceForException(char[] proposalName){
6763
	private void findKeywordsForMember(char[] token, int modifiers) {
6764
		char[][] keywords = new char[Keywords.COUNT][];
6765
		int count = 0;
6847
6766
6848
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
6767
		// visibility
6849
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
6768
		if((modifiers & ClassFileConstants.AccPrivate) == 0
6850
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
6769
			&& (modifiers & ClassFileConstants.AccProtected) == 0
6851
			return R_EXCEPTION;
6770
			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
6771
			keywords[count++] = Keywords.PROTECTED;
6772
			keywords[count++] = Keywords.PUBLIC;
6773
			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6774
				keywords[count++] = Keywords.PRIVATE;
6775
			}
6852
		}
6776
		}
6853
		return 0;
6854
	}
6855
	private int computeRelevanceForExpectingType(TypeBinding proposalType){
6856
		if(this.expectedTypes != null && proposalType != null) {
6857
			int relevance = 0;
6858
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
6859
				if((this.expectedTypesFilter & SUBTYPE) != 0
6860
						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
6861
6777
6862
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
6778
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6863
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
6779
			// abtract
6864
						return R_EXACT_EXPECTED_TYPE;
6780
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
6865
					}
6781
				keywords[count++] = Keywords.ABSTRACT;
6782
			}
6866
6783
6867
					relevance = R_EXPECTED_TYPE;
6784
			// final
6868
				}
6785
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
6869
				if((this.expectedTypesFilter & SUPERTYPE) != 0
6786
				keywords[count++] = Keywords.FINAL;
6870
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
6787
			}
6871
6788
6872
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
6789
			// static
6873
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
6790
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
6874
						return R_EXACT_EXPECTED_TYPE;
6791
				keywords[count++] = Keywords.STATIC;
6875
					}
6792
			}
6876
6793
6877
					relevance = R_EXPECTED_TYPE;
6794
			boolean canBeField = true;
6795
			boolean canBeMethod = true;
6796
			boolean canBeType = true;
6797
			if((modifiers & ClassFileConstants.AccNative) != 0
6798
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
6799
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
6800
				canBeField = false;
6801
				canBeType = false;
6802
			}
6803
6804
			if((modifiers & ClassFileConstants.AccTransient) != 0
6805
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
6806
				canBeMethod = false;
6807
				canBeType = false;
6808
			}
6809
6810
			if(canBeField) {
6811
				// transient
6812
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
6813
					keywords[count++] = Keywords.TRANSIENT;
6814
				}
6815
6816
				// volatile
6817
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
6818
					keywords[count++] = Keywords.VOLATILE;
6878
				}
6819
				}
6879
			}
6820
			}
6880
			return relevance;
6821
6881
		}
6822
			if(canBeMethod) {
6882
		return 0;
6823
				// native
6883
	}
6824
				if((modifiers & ClassFileConstants.AccNative) == 0) {
6884
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
6825
					keywords[count++] = Keywords.NATIVE;
6885
		if(this.expectedTypes != null) {
6826
				}
6886
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
6827
6887
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
6828
				// strictfp
6888
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
6829
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
6889
					return R_EXACT_EXPECTED_TYPE;
6830
					keywords[count++] = Keywords.STRICTFP;
6831
				}
6832
6833
				// synchronized
6834
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
6835
					keywords[count++] = Keywords.SYNCHRONIZED;
6890
				}
6836
				}
6891
			}
6837
			}
6892
			if(this.hasJavaLangObjectAsExpectedType) {
6893
				return R_EXPECTED_TYPE;
6894
			}
6895
		}
6896
		return 0;
6897
	}
6898
6838
6899
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
6839
			if(canBeType) {
6900
		if (receiverType == declaringClass) return R_NON_INHERITED;
6840
				keywords[count++] = Keywords.CLASS;
6901
		return 0;
6841
				keywords[count++] = Keywords.INTERFACE;
6902
	}
6903
6842
6904
	int computeRelevanceForInterestingProposal(){
6843
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
6905
		return computeRelevanceForInterestingProposal(null);
6844
					keywords[count++] = Keywords.ENUM;
6906
	}
6907
	private int computeRelevanceForInterestingProposal(Binding binding){
6908
		if(this.uninterestingBindings != null) {
6909
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
6910
				if(this.uninterestingBindings[i] == binding) {
6911
					return 0;
6912
				}
6845
				}
6913
			}
6846
			}
6847
		} else {
6848
			// class
6849
			keywords[count++] = Keywords.CLASS;
6850
			keywords[count++] = Keywords.INTERFACE;
6914
		}
6851
		}
6915
		return R_INTERESTING;
6852
		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
6916
	}
6917
	private void computeUninterestingBindings(ASTNode parent, Scope scope){
6918
		if(parent instanceof LocalDeclaration) {
6919
			addUninterestingBindings(((LocalDeclaration)parent).binding);
6920
		} else if (parent instanceof FieldDeclaration) {
6921
			addUninterestingBindings(((FieldDeclaration)parent).binding);
6922
		}
6923
	}
6924
6853
6854
		findKeywords(token, keywords, false, false);
6855
	}
6925
	private void findLabels(char[] label, char[][] choices) {
6856
	private void findLabels(char[] label, char[][] choices) {
6926
		if(choices == null || choices.length == 0) return;
6857
		if(choices == null || choices.length == 0) return;
6927
6858
Lines 7068-7312 Link Here
7068
				}
6999
				}
7069
				proposal.setKey(method.computeUniqueKey());
7000
				proposal.setKey(method.computeUniqueKey());
7070
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7001
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7071
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7002
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7072
				proposal.setParameterPackageNames(parameterPackageNames);
7003
				proposal.setParameterPackageNames(parameterPackageNames);
7073
				proposal.setParameterTypeNames(parameterFullTypeNames);
7004
				proposal.setParameterTypeNames(parameterFullTypeNames);
7074
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7005
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7075
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7006
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7076
				proposal.setCompletion(completion.toString().toCharArray());
7007
				proposal.setCompletion(completion.toString().toCharArray());
7077
				proposal.setName(method.selector);
7008
				proposal.setName(method.selector);
7078
				proposal.setFlags(method.modifiers);
7009
				proposal.setFlags(method.modifiers);
7079
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7010
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7080
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7011
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7081
				proposal.setRelevance(relevance);
7012
				proposal.setRelevance(relevance);
7082
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7013
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7083
				this.requestor.accept(proposal);
7014
				this.requestor.accept(proposal);
7084
				if(DEBUG) {
7015
				if(DEBUG) {
7085
					this.printDebug(proposal);
7016
					this.printDebug(proposal);
7086
				}
7087
			}
7088
		}
7089
		methodsFound.addAll(newMethodsFound);
7090
	}
7091
7092
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
7093
		completion.append(typeVariable.sourceName);
7094
7095
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
7096
		    completion.append(' ');
7097
		    completion.append(EXTENDS);
7098
		    completion.append(' ');
7099
		    createType(typeVariable.superclass, scope, completion);
7100
		}
7101
		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
7102
		   if (typeVariable.firstBound != typeVariable.superclass) {
7103
			   completion.append(' ');
7104
			   completion.append(EXTENDS);
7105
			   completion.append(' ');
7106
		   }
7107
		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
7108
			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
7109
				   completion.append(' ');
7110
				   completion.append(EXTENDS);
7111
				   completion.append(' ');
7112
			   }
7113
			   createType(typeVariable.superInterfaces[i], scope, completion);
7114
		   }
7115
		}
7116
	}
7117
7118
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
7119
		switch (type.kind()) {
7120
			case Binding.BASE_TYPE :
7121
				completion.append(type.sourceName());
7122
				break;
7123
			case Binding.WILDCARD_TYPE :
7124
			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
7125
				WildcardBinding wildcardBinding = (WildcardBinding) type;
7126
				completion.append('?');
7127
				switch (wildcardBinding.boundKind) {
7128
					case Wildcard.EXTENDS:
7129
						completion.append(' ');
7130
						completion.append(EXTENDS);
7131
						completion.append(' ');
7132
						createType(wildcardBinding.bound, scope, completion);
7133
						if(wildcardBinding.otherBounds != null) {
7134
7135
							int length = wildcardBinding.otherBounds.length;
7136
							for (int i = 0; i < length; i++) {
7137
								completion.append(' ');
7138
								completion.append('&');
7139
								completion.append(' ');
7140
								createType(wildcardBinding.otherBounds[i], scope, completion);
7141
							}
7142
						}
7143
						break;
7144
					case Wildcard.SUPER:
7145
						completion.append(' ');
7146
						completion.append(SUPER);
7147
						completion.append(' ');
7148
						createType(wildcardBinding.bound, scope, completion);
7149
						break;
7150
				}
7151
				break;
7152
			case Binding.ARRAY_TYPE :
7153
				createType(type.leafComponentType(), scope, completion);
7154
				int dim = type.dimensions();
7155
				for (int i = 0; i < dim; i++) {
7156
					completion.append('[');
7157
					completion.append(']');
7158
				}
7159
				break;
7160
			case Binding.PARAMETERIZED_TYPE :
7161
				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
7162
				if (type.isMemberType()) {
7163
					createType(parameterizedType.enclosingType(), scope, completion);
7164
					completion.append('.');
7165
					completion.append(parameterizedType.sourceName);
7166
				} else {
7167
					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
7168
				}
7169
				if (parameterizedType.arguments != null) {
7170
					completion.append('<');
7171
				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
7172
				        if (i != 0) completion.append(',');
7173
				        createType(parameterizedType.arguments[i], scope, completion);
7174
				    }
7175
				    completion.append('>');
7176
				}
7177
				break;
7178
			default :
7179
				char[] packageName = type.qualifiedPackageName();
7180
			char[] typeName = type.qualifiedSourceName();
7181
			if(mustQualifyType(
7182
					(ReferenceBinding)type,
7183
					packageName,
7184
					scope)) {
7185
				completion.append(CharOperation.concat(packageName, typeName,'.'));
7186
			} else {
7187
				completion.append(type.sourceName());
7188
			}
7189
			break;
7190
		}
7191
	}
7192
7193
	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
7194
		if (type.isArrayType()) {
7195
			createType(type.leafComponentType(), scope, completion);
7196
			int dim = type.dimensions() - 1;
7197
			for (int i = 0; i < dim; i++) {
7198
				completion.append('[');
7199
				completion.append(']');
7200
			}
7201
			completion.append(VARARGS);
7202
		} else {
7203
			createType(type, scope, completion);
7204
		}
7205
	}
7206
	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
7207
		char[] result = IMPORT;
7208
		if (isStatic) {
7209
			result = CharOperation.concat(result, STATIC, ' ');
7210
		}
7211
		result = CharOperation.concat(result, importedElement, ' ');
7212
		if (onDemand) {
7213
			result = CharOperation.concat(result, ON_DEMAND);
7214
		}
7215
		return CharOperation.concat(result, IMPORT_END);
7216
	}
7217
	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
7218
		//// Modifiers
7219
		// flush uninteresting modifiers
7220
		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
7221
		if(insertedModifiers != ClassFileConstants.AccDefault){
7222
			ASTNode.printModifiers(insertedModifiers, completion);
7223
		}
7224
7225
		//// Type parameters
7226
7227
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
7228
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
7229
			completion.append('<');
7230
			for (int i = 0; i < typeVariableBindings.length; i++) {
7231
				if(i != 0) {
7232
					completion.append(',');
7233
					completion.append(' ');
7234
				}
7235
				createTypeVariable(typeVariableBindings[i], scope, completion);
7236
			}
7237
			completion.append('>');
7238
			completion.append(' ');
7239
		}
7240
7241
		//// Return type
7242
		createType(method.returnType, scope, completion);
7243
		completion.append(' ');
7244
7245
		//// Selector
7246
		completion.append(method.selector);
7247
7248
		completion.append('(');
7249
7250
		////Parameters
7251
		TypeBinding[] parameterTypes = method.parameters;
7252
		int length = parameterTypes.length;
7253
		for (int i = 0; i < length; i++) {
7254
			if(i != 0) {
7255
				completion.append(',');
7256
				completion.append(' ');
7257
			}
7258
			createType(parameterTypes[i], scope, completion);
7259
			completion.append(' ');
7260
			if(parameterNames != null){
7261
				completion.append(parameterNames[i]);
7262
			} else {
7263
				completion.append('%');
7264
			}
7265
		}
7266
7267
		completion.append(')');
7268
7269
		//// Exceptions
7270
		ReferenceBinding[] exceptions = method.thrownExceptions;
7271
7272
		if (exceptions != null && exceptions.length > 0){
7273
			completion.append(' ');
7274
			completion.append(THROWS);
7275
			completion.append(' ');
7276
			for(int i = 0; i < exceptions.length ; i++){
7277
				if(i != 0) {
7278
					completion.append(' ');
7279
					completion.append(',');
7280
				}
7017
				}
7281
				createType(exceptions[i], scope, completion);
7282
			}
7018
			}
7283
		}
7019
		}
7020
		methodsFound.addAll(newMethodsFound);
7284
	}
7021
	}
7285
7022
7286
	private boolean isIgnored(int kind, boolean missingTypes) {
7023
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
7287
		return this.requestor.isIgnored(kind) ||
7024
	private void findLocalMethods(
7288
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
7025
		char[] methodName,
7289
	}
7290
7291
	private boolean isIgnored(int kind) {
7292
		return this.requestor.isIgnored(kind);
7293
	}
7294
7295
	private boolean isIgnored(int kind, int requiredProposalKind) {
7296
		return this.requestor.isIgnored(kind) ||
7297
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
7298
	}
7299
7300
	private void findMethods(
7301
		char[] selector,
7302
		TypeBinding[] typeArgTypes,
7026
		TypeBinding[] typeArgTypes,
7303
		TypeBinding[] argTypes,
7027
		TypeBinding[] argTypes,
7304
		ReferenceBinding receiverType,
7028
		MethodBinding[] methods,
7305
		Scope scope,
7029
		Scope scope,
7306
		ObjectVector methodsFound,
7030
		ObjectVector methodsFound,
7307
		boolean onlyStaticMethods,
7031
		boolean onlyStaticMethods,
7308
		boolean exactMatch,
7032
		boolean exactMatch,
7309
		boolean isCompletingDeclaration,
7033
		ReferenceBinding receiverType,
7310
		InvocationSite invocationSite,
7034
		InvocationSite invocationSite,
7311
		Scope invocationScope,
7035
		Scope invocationScope,
7312
		boolean implicitCall,
7036
		boolean implicitCall,
Lines 7320-10022 Link Here
7320
		int receiverStart,
7044
		int receiverStart,
7321
		int receiverEnd) {
7045
		int receiverEnd) {
7322
7046
7323
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
7047
		ObjectVector newMethodsFound =  new ObjectVector();
7324
		if (selector == null && notInJavadoc) {
7048
		// Inherited methods which are hidden by subclasses are filtered out
7325
			return;
7049
		// No visibility checks can be performed without the scope & invocationSite
7326
		}
7327
7050
7328
		if(isCompletingDeclaration) {
7051
		int methodLength = methodName.length;
7329
			MethodBinding[] methods = receiverType.availableMethods();
7052
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
7330
			if (methods != null){
7053
		int minArgLength = argTypes == null ? 0 : argTypes.length;
7331
				for (int i = 0; i < methods.length; i++) {
7054
7332
					if(!methods[i].isDefaultAbstract()) {
7055
		next : for (int f = methods.length; --f >= 0;) {
7333
						methodsFound.add(methods[i]);
7056
			MethodBinding method = methods[f];
7334
					}
7057
7335
				}
7058
			if (method.isSynthetic()) continue next;
7059
7060
			if (method.isDefaultAbstract())	continue next;
7061
7062
			if (method.isConstructor()) continue next;
7063
7064
			if (this.options.checkDeprecation &&
7065
					method.isViewedAsDeprecated() &&
7066
					!scope.isDefinedInSameUnit(method.declaringClass))
7067
				continue next;
7068
7069
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
7070
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
7071
7072
			if (onlyStaticMethods && !method.isStatic()) continue next;
7073
7074
			if (this.options.checkVisibility
7075
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7076
7077
			if(superCall && method.isAbstract()) {
7078
				methodsFound.add(new Object[]{method, receiverType});
7079
				continue next;
7336
			}
7080
			}
7337
		}
7338
7081
7339
		ReferenceBinding currentType = receiverType;
7082
			if (exactMatch) {
7340
		if (notInJavadoc) {
7083
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
7341
			if (receiverType.isInterface()) {
7084
					continue next;
7342
				if (isCompletingDeclaration) {
7343
					findInterfacesMethods(
7344
						selector,
7345
						typeArgTypes,
7346
						argTypes,
7347
						receiverType,
7348
						currentType.superInterfaces(),
7349
						scope,
7350
						methodsFound,
7351
						onlyStaticMethods,
7352
						exactMatch,
7353
						isCompletingDeclaration,
7354
						invocationSite,
7355
						invocationScope,
7356
						implicitCall,
7357
						superCall,
7358
						canBePrefixed,
7359
						missingElements,
7360
						missingElementsStarts,
7361
						missingElementsEnds,
7362
						missingElementsHaveProblems,
7363
						castedReceiver,
7364
						receiverStart,
7365
						receiverEnd);
7366
				} else {
7367
					findInterfacesMethods(
7368
						selector,
7369
						typeArgTypes,
7370
						argTypes,
7371
						receiverType,
7372
						new ReferenceBinding[]{currentType},
7373
						scope,
7374
						methodsFound,
7375
						onlyStaticMethods,
7376
						exactMatch,
7377
						isCompletingDeclaration,
7378
						invocationSite,
7379
						invocationScope,
7380
						implicitCall,
7381
						superCall,
7382
						canBePrefixed,
7383
						missingElements,
7384
						missingElementsStarts,
7385
						missingElementsEnds,
7386
						missingElementsHaveProblems,
7387
						castedReceiver,
7388
						receiverStart,
7389
						receiverEnd);
7390
				}
7085
				}
7391
7392
				currentType = scope.getJavaLangObject();
7393
			} else {
7086
			} else {
7394
				if (isCompletingDeclaration){
7087
				if (methodLength > method.selector.length) continue next;
7395
					findInterfacesMethods(
7088
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
7396
						selector,
7089
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
7397
						typeArgTypes,
7090
					continue next;
7398
						argTypes,
7399
						receiverType,
7400
						currentType.superInterfaces(),
7401
						scope,
7402
						methodsFound,
7403
						onlyStaticMethods,
7404
						exactMatch,
7405
						isCompletingDeclaration,
7406
						invocationSite,
7407
						invocationScope,
7408
						implicitCall,
7409
						superCall,
7410
						canBePrefixed,
7411
						missingElements,
7412
						missingElementsStarts,
7413
						missingElementsEnds,
7414
						missingElementsHaveProblems,
7415
						castedReceiver,
7416
						receiverStart,
7417
						receiverEnd);
7418
7419
					currentType = receiverType.superclass();
7420
				}
7091
				}
7421
			}
7092
			}
7422
		}
7423
		boolean hasPotentialDefaultAbstractMethods = true;
7424
		while (currentType != null) {
7425
7093
7426
			MethodBinding[] methods = currentType.availableMethods();
7094
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
7427
			if (methods != null) {
7095
				continue next;
7428
				if (isCompletingDeclaration){
7096
7429
					findLocalMethodDeclarations(
7097
			if (minTypeArgLength != 0) {
7430
						selector,
7098
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
7431
						methods,
7432
						scope,
7433
						methodsFound,
7434
						exactMatch,
7435
						receiverType);
7436
				} else{
7437
					findLocalMethods(
7438
						selector,
7439
						typeArgTypes,
7440
						argTypes,
7441
						methods,
7442
						scope,
7443
						methodsFound,
7444
						onlyStaticMethods,
7445
						exactMatch,
7446
						receiverType,
7447
						invocationSite,
7448
						invocationScope,
7449
						implicitCall,
7450
						superCall,
7451
						canBePrefixed,
7452
						missingElements,
7453
						missingElementsStarts,
7454
						missingElementsEnds,
7455
						missingElementsHaveProblems,
7456
						castedReceiver,
7457
						receiverStart,
7458
						receiverEnd);
7459
				}
7460
			}
7099
			}
7461
7100
7462
			if (hasPotentialDefaultAbstractMethods &&
7101
			if (minArgLength > method.parameters.length)
7463
					(currentType.isAbstract() ||
7102
				continue next;
7464
							currentType.isTypeVariable() ||
7465
							currentType.isIntersectionType() ||
7466
							currentType.isEnum())){
7467
7103
7468
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
7104
			for (int a = minArgLength; --a >= 0;){
7469
				if (superInterfaces != null && currentType.isIntersectionType()) {
7105
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
7470
					for (int i = 0; i < superInterfaces.length; i++) {
7106
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
7471
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
7107
						continue next;
7472
					}
7108
					}
7473
				}
7109
				}
7110
			}
7474
7111
7475
				findInterfacesMethods(
7112
			boolean prefixRequired = false;
7476
					selector,
7113
7477
					typeArgTypes,
7114
			for (int i = methodsFound.size; --i >= 0;) {
7478
					argTypes,
7115
				Object[] other = (Object[]) methodsFound.elementAt(i);
7479
					receiverType,
7116
				MethodBinding otherMethod = (MethodBinding) other[0];
7480
					superInterfaces,
7117
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
7481
					scope,
7118
				if (method == otherMethod && receiverType == otherReceiverType)
7482
					methodsFound,
7119
					continue next;
7483
					onlyStaticMethods,
7120
7484
					exactMatch,
7121
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7485
					isCompletingDeclaration,
7122
					if (receiverType == otherReceiverType) {
7486
					invocationSite,
7123
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7487
					invocationScope,
7124
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
7488
					implicitCall,
7125
								continue next;
7489
					superCall,
7126
							}
7490
					canBePrefixed,
7127
						}
7491
					missingElements,
7128
					} else {
7492
					missingElementsStarts,
7129
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7493
					missingElementsEnds,
7130
							if(receiverType.isAnonymousType()) continue next;
7494
					missingElementsHaveProblems,
7131
7495
					castedReceiver,
7132
							if(!superCall) {
7496
					receiverStart,
7133
								if(!canBePrefixed) continue next;
7497
					receiverEnd);
7134
7498
			} else {
7135
								prefixRequired = true;
7499
				hasPotentialDefaultAbstractMethods = false;
7136
							}
7137
						}
7138
					}
7139
				}
7500
			}
7140
			}
7501
			currentType = currentType.superclass();
7502
		}
7503
	}
7504
	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
7505
		TypeBinding erasure =  method.declaringClass.erasure();
7506
		if(!(erasure instanceof ReferenceBinding)) return null;
7507
7141
7508
		char[][] parameterNames = null;
7142
			newMethodsFound.add(new Object[]{method, receiverType});
7509
7143
7510
		int length = parameterTypeNames.length;
7144
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7145
			if (method.declaringClass != superTypeWithSameErasure) {
7146
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7147
				for (int i = 0; i < otherMethods.length; i++) {
7148
					if(otherMethods[i].original() == method.original()) {
7149
						method = otherMethods[i];
7150
					}
7151
				}
7152
			}
7511
7153
7512
		if (length == 0){
7154
			int length = method.parameters.length;
7513
			return CharOperation.NO_CHAR_CHAR;
7155
			char[][] parameterPackageNames = new char[length][];
7514
		}
7156
			char[][] parameterTypeNames = new char[length][];
7515
		// look into the corresponding unit if it is available
7516
		if (erasure instanceof SourceTypeBinding){
7517
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
7518
7157
7519
			if (sourceType.scope != null){
7158
			for (int i = 0; i < length; i++) {
7520
				TypeDeclaration parsedType;
7159
				TypeBinding type = method.original().parameters[i];
7160
				parameterPackageNames[i] = type.qualifiedPackageName();
7161
				parameterTypeNames[i] = type.qualifiedSourceName();
7162
			}
7163
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7521
7164
7522
				if ((parsedType = sourceType.scope.referenceContext) != null){
7165
			char[] completion = CharOperation.NO_CHAR;
7523
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
7524
7166
7525
					if (methodDecl != null){
7167
			int previousStartPosition = this.startPosition;
7526
						Argument[] arguments = methodDecl.arguments;
7168
			int previousTokenStart = this.tokenStart;
7527
						parameterNames = new char[length][];
7528
7169
7529
						for(int i = 0 ; i < length ; i++){
7170
			// Special case for completion in javadoc
7530
							parameterNames[i] = arguments[i].name;
7171
			if (this.assistNodeInJavadoc > 0) {
7172
				Expression receiver = null;
7173
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
7174
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
7175
					receiver = msg.receiver;
7176
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
7177
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
7178
					receiver = fieldRef.receiver;
7179
				}
7180
				if (receiver != null) {
7181
					StringBuffer javadocCompletion = new StringBuffer();
7182
					if (receiver.isThis()) {
7183
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7184
							javadocCompletion.append('#');
7185
						}
7186
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7187
						if (receiver instanceof JavadocSingleTypeReference) {
7188
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
7189
							javadocCompletion.append(typeRef.token);
7190
							javadocCompletion.append('#');
7191
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
7192
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
7193
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
7194
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
7195
								if (t>0) javadocCompletion.append('.');
7196
								javadocCompletion.append(typeRef.tokens[t]);
7197
							}
7198
							javadocCompletion.append('#');
7199
						}
7200
					}
7201
					javadocCompletion.append(method.selector);
7202
					// Append parameters types
7203
					javadocCompletion.append('(');
7204
					if (method.parameters != null) {
7205
						boolean isVarargs = method.isVarargs();
7206
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
7207
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
7208
							TypeBinding argTypeBinding = method.parameters[p];
7209
							if (isVarargs && p == ln - 1)  {
7210
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
7211
							} else {
7212
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
7213
							}
7531
						}
7214
						}
7532
					}
7215
					}
7216
					javadocCompletion.append(')');
7217
					completion = javadocCompletion.toString().toCharArray();
7533
				}
7218
				}
7534
			}
7219
			} else {
7535
		}
7220
				// nothing to insert - do not want to replace the existing selector & arguments
7536
		// look into the model
7221
				if (!exactMatch) {
7537
		if(parameterNames == null){
7222
					if (this.source != null
7538
7223
						&& this.source.length > this.endPosition
7539
			ReferenceBinding bindingType = (ReferenceBinding)erasure;
7224
						&& this.source[this.endPosition] == '(')
7540
7225
						completion = method.selector;
7541
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
7226
					else
7542
			Object type = this.typeCache.get(compoundName);
7227
						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7543
7228
7544
			ISourceType sourceType = null;
7229
					if (castedReceiver != null) {
7545
			if(type != null) {
7230
						completion = CharOperation.concat(castedReceiver, completion);
7546
				if(type instanceof ISourceType) {
7231
					}
7547
					sourceType = (ISourceType) type;
7232
				} else {
7233
					if(prefixRequired && (this.source != null)) {
7234
						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
7235
					} else {
7236
						this.startPosition = this.endPosition;
7237
					}
7238
					this.tokenStart = this.tokenEnd;
7548
				}
7239
				}
7549
			} else {
7240
7550
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
7241
				if(prefixRequired || this.options.forceImplicitQualification){
7551
				if(answer != null && answer.isSourceType()) {
7242
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
7552
					sourceType = answer.getSourceTypes()[0];
7243
					completion = CharOperation.concat(prefix,completion,'.');
7553
					this.typeCache.put(compoundName, sourceType);
7554
				}
7244
				}
7555
			}
7245
			}
7556
7246
7557
			if(sourceType != null) {
7247
			int relevance = computeBaseRelevance();
7558
				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
7248
			relevance += computeRelevanceForResolution();
7249
			relevance += computeRelevanceForInterestingProposal();
7250
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7251
			relevance += computeRelevanceForExpectingType(method.returnType);
7252
			relevance += computeRelevanceForEnumConstant(method.returnType);
7253
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
7254
			relevance += computeRelevanceForQualification(prefixRequired);
7255
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7256
			if (onlyStaticMethods && this.insideQualifiedReference) {
7257
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
7258
			}
7259
			if (missingElements != null) {
7260
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
7261
			}
7559
7262
7560
				String[] parameterTypeSignatures = new String[length];
7263
			this.noProposal = false;
7561
				for (int i = 0; i < length; i++) {
7264
7562
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
7265
			if (castedReceiver == null) {
7266
				// Standard proposal
7267
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
7268
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7269
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7270
					proposal.setSignature(getSignature(method));
7271
					MethodBinding original = method.original();
7272
					if(original != method) {
7273
						proposal.setOriginalSignature(getSignature(original));
7274
					}
7275
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7276
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7277
					proposal.setParameterPackageNames(parameterPackageNames);
7278
					proposal.setParameterTypeNames(parameterTypeNames);
7279
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7280
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7281
					proposal.setName(method.selector);
7282
					if (missingElements != null) {
7283
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7284
						for (int i = 0; i < missingElements.length; i++) {
7285
							subProposals[i] =
7286
								createRequiredTypeProposal(
7287
										missingElements[i],
7288
										missingElementsStarts[i],
7289
										missingElementsEnds[i],
7290
										relevance);
7291
						}
7292
						proposal.setRequiredProposals(subProposals);
7293
					}
7294
					proposal.setCompletion(completion);
7295
					proposal.setFlags(method.modifiers);
7296
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7297
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7298
					proposal.setRelevance(relevance);
7299
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7300
					this.requestor.accept(proposal);
7301
					if(DEBUG) {
7302
						this.printDebug(proposal);
7303
					}
7563
				}
7304
				}
7564
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
7565
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
7566
7305
7567
				if(foundMethods != null) {
7306
				// Javadoc proposal
7568
					int len = foundMethods.length;
7307
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
7569
					if(len == 1) {
7308
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
7570
						try {
7309
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
7571
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
7310
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7572
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
7311
					proposal.setSignature(getSignature(method));
7573
						} catch (JavaModelException e) {
7312
					MethodBinding original = method.original();
7574
							// method doesn't exist: ignore
7313
					if(original != method) {
7314
						proposal.setOriginalSignature(getSignature(original));
7315
					}
7316
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7317
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7318
					proposal.setParameterPackageNames(parameterPackageNames);
7319
					proposal.setParameterTypeNames(parameterTypeNames);
7320
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7321
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7322
					proposal.setName(method.selector);
7323
					proposal.setCompletion(javadocCompletion);
7324
					proposal.setFlags(method.modifiers);
7325
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
7326
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
7327
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7328
					proposal.setRelevance(relevance+R_INLINE_TAG);
7329
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7330
					this.requestor.accept(proposal);
7331
					if(DEBUG) {
7332
						this.printDebug(proposal);
7333
					}
7334
				}
7335
			} else {
7336
				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
7337
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
7338
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7339
					proposal.setSignature(getSignature(method));
7340
					MethodBinding original = method.original();
7341
					if(original != method) {
7342
						proposal.setOriginalSignature(getSignature(original));
7343
					}
7344
					proposal.setReceiverSignature(getSignature(receiverType));
7345
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7346
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7347
					proposal.setParameterPackageNames(parameterPackageNames);
7348
					proposal.setParameterTypeNames(parameterTypeNames);
7349
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7350
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7351
					proposal.setName(method.selector);
7352
					if (missingElements != null) {
7353
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7354
						for (int i = 0; i < missingElements.length; i++) {
7355
							subProposals[i] =
7356
								createRequiredTypeProposal(
7357
										missingElements[i],
7358
										missingElementsStarts[i],
7359
										missingElementsEnds[i],
7360
										relevance);
7575
						}
7361
						}
7362
						proposal.setRequiredProposals(subProposals);
7363
					}
7364
					proposal.setCompletion(completion);
7365
					proposal.setFlags(method.modifiers);
7366
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7367
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
7368
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7369
					proposal.setRelevance(relevance);
7370
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7371
					this.requestor.accept(proposal);
7372
					if(DEBUG) {
7373
						this.printDebug(proposal);
7576
					}
7374
					}
7577
				}
7375
				}
7578
			}
7376
			}
7377
			this.startPosition = previousStartPosition;
7378
			this.tokenStart = previousTokenStart;
7579
		}
7379
		}
7580
		return parameterNames;
7380
7381
		methodsFound.addAll(newMethodsFound);
7581
	}
7382
	}
7383
	private void findLocalMethodsFromFavorites(
7384
			char[] methodName,
7385
			MethodBinding[] methods,
7386
			Scope scope,
7387
			ObjectVector methodsFound,
7388
			ObjectVector methodsFoundFromFavorites,
7389
			ReferenceBinding receiverType,
7390
			InvocationSite invocationSite,
7391
			Scope invocationScope) {
7582
7392
7583
	private void findNestedTypes(
7393
			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
7584
		char[] typeName,
7585
		SourceTypeBinding currentType,
7586
		Scope scope,
7587
		boolean proposeAllMemberTypes,
7588
		ObjectVector typesFound) {
7589
		if (typeName == null)
7590
			return;
7591
7394
7592
		int typeLength = typeName.length;
7395
			int methodLength = methodName.length;
7593
7396
7594
		SourceTypeBinding nextTypeToIgnore = null;
7397
			next : for (int f = methods.length; --f >= 0;) {
7595
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
7398
				MethodBinding method = methods[f];
7596
7399
7597
			switch (scope.kind) {
7400
				if (method.isSynthetic()) continue next;
7598
7401
7599
				case Scope.METHOD_SCOPE :
7402
				if (method.isDefaultAbstract())	continue next;
7600
				case Scope.BLOCK_SCOPE :
7601
					BlockScope blockScope = (BlockScope) scope;
7602
7403
7603
					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
7404
				if (method.isConstructor()) continue next;
7604
7405
7605
						if (blockScope.subscopes[i] instanceof ClassScope) {
7406
				if (this.options.checkDeprecation &&
7606
							SourceTypeBinding localType =
7407
						method.isViewedAsDeprecated() &&
7607
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
7408
						!scope.isDefinedInSameUnit(method.declaringClass))
7409
					continue next;
7608
7410
7609
							if (!localType.isAnonymousType()) {
7411
				if (!method.isStatic()) continue next;
7610
								if (isForbidden(localType))
7611
									continue next;
7612
7412
7613
								if (typeLength > localType.sourceName.length)
7413
				if (this.options.checkVisibility
7614
									continue next;
7414
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7615
								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
7616
										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
7617
									continue next;
7618
7415
7619
								for (int j = typesFound.size; --j >= 0;) {
7416
				if (methodLength > method.selector.length) continue next;
7620
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
7621
7417
7622
									if (localType == otherType)
7418
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
7623
										continue next;
7419
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
7624
								}
7420
					continue next;
7421
				}
7625
7422
7626
								if(this.assistNodeIsClass) {
7423
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
7627
									if(!localType.isClass()) continue next;
7424
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
7628
								} else if(this.assistNodeIsInterface) {
7425
					MethodBinding otherMethod = (MethodBinding) other[0];
7629
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
7630
								} else if (this.assistNodeIsAnnotation) {
7631
									if(!localType.isAnnotationType()) continue next;
7632
								}
7633
7426
7634
								int relevance = computeBaseRelevance();
7427
					if (method == otherMethod) continue next;
7635
								relevance += computeRelevanceForResolution();
7636
								relevance += computeRelevanceForInterestingProposal();
7637
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
7638
								relevance += computeRelevanceForExpectingType(localType);
7639
								relevance += computeRelevanceForException(localType.sourceName);
7640
								relevance += computeRelevanceForClass();
7641
								relevance += computeRelevanceForQualification(false);
7642
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
7643
								relevance += computeRelevanceForAnnotationTarget(localType);
7644
7428
7645
								this.noProposal = false;
7429
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7646
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7430
						if (otherMethod.declaringClass == method.declaringClass &&
7647
									createTypeProposal(
7431
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7648
											localType,
7432
							continue next;
7649
											localType.sourceName,
7650
											IAccessRule.K_ACCESSIBLE,
7651
											localType.sourceName,
7652
											relevance,
7653
											null,
7654
											null,
7655
											null,
7656
											false);
7657
								}
7658
							}
7659
						}
7433
						}
7660
					}
7434
					}
7661
					break;
7662
7663
				case Scope.CLASS_SCOPE :
7664
					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
7665
					findMemberTypes(
7666
							typeName,
7667
							enclosingSourceType,
7668
							scope,
7669
							currentType,
7670
							false,
7671
							false,
7672
							false,
7673
							false,
7674
							proposeAllMemberTypes,
7675
							nextTypeToIgnore,
7676
							typesFound,
7677
							null,
7678
							null,
7679
							null,
7680
							false);
7681
					nextTypeToIgnore = enclosingSourceType;
7682
					if (typeLength == 0)
7683
						return; // do not search outside the class scope if no prefix was provided
7684
					break;
7685
7686
				case Scope.COMPILATION_UNIT_SCOPE :
7687
					return;
7688
			}
7689
			scope = scope.parent;
7690
		}
7691
	}
7692
7693
	private void findPackages(CompletionOnPackageReference packageStatement) {
7694
7695
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
7696
		if (this.completionToken.length == 0)
7697
			return;
7698
7699
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
7700
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
7701
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
7702
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
7703
	}
7704
7705
	private void findParameterizedType(TypeReference ref, Scope scope) {
7706
		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
7707
		if(refBinding != null) {
7708
			if (this.options.checkDeprecation &&
7709
					refBinding.isViewedAsDeprecated() &&
7710
					!scope.isDefinedInSameUnit(refBinding))
7711
				return;
7712
7713
			int accessibility = IAccessRule.K_ACCESSIBLE;
7714
			if(refBinding.hasRestrictedAccess()) {
7715
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7716
				if(accessRestriction != null) {
7717
					switch (accessRestriction.getProblemId()) {
7718
						case IProblem.ForbiddenReference:
7719
							if (this.options.checkForbiddenReference) {
7720
								return;
7721
							}
7722
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
7723
							break;
7724
						case IProblem.DiscouragedReference:
7725
							if (this.options.checkDiscouragedReference) {
7726
								return;
7727
							}
7728
							accessibility = IAccessRule.K_DISCOURAGED;
7729
							break;
7730
					}
7731
				}
7435
				}
7732
			}
7733
7734
			int relevance = computeBaseRelevance();
7735
			relevance += computeRelevanceForResolution();
7736
			relevance += computeRelevanceForInterestingProposal();
7737
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
7738
			relevance += computeRelevanceForExpectingType(refBinding);
7739
			relevance += computeRelevanceForQualification(false);
7740
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
7741
7742
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7743
				createTypeProposal(
7744
						refBinding,
7745
						refBinding.qualifiedSourceName(),
7746
						IAccessRule.K_ACCESSIBLE,
7747
						CharOperation.NO_CHAR,
7748
						relevance,
7749
						null,
7750
						null,
7751
						null,
7752
						false);
7753
			}
7754
		}
7755
	}
7756
	private void findTypeParameters(char[] token, Scope scope) {
7757
		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
7758
7759
		TypeParameter[] typeParameters = null;
7760
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
7761
			typeParameters = null;
7762
			switch (scope.kind) {
7763
				case Scope.METHOD_SCOPE :
7764
					MethodScope methodScope = (MethodScope) scope;
7765
					if(methodScope.referenceContext instanceof MethodDeclaration) {
7766
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
7767
						typeParameters = methodDeclaration.typeParameters;
7768
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
7769
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
7770
						typeParameters = methodDeclaration.typeParameters;
7771
					}
7772
					break;
7773
				case Scope.CLASS_SCOPE :
7774
					ClassScope classScope = (ClassScope) scope;
7775
					typeParameters = classScope.referenceContext.typeParameters;
7776
					break;
7777
				case Scope.COMPILATION_UNIT_SCOPE :
7778
					return;
7779
			}
7780
			if(typeParameters != null) {
7781
				for (int i = 0; i < typeParameters.length; i++) {
7782
					int typeLength = token.length;
7783
					TypeParameter typeParameter = typeParameters[i];
7784
7436
7785
					if(typeParameter.binding == null) continue;
7437
				for (int i = methodsFound.size; --i >= 0;) {
7438
					Object[] other = (Object[]) methodsFound.elementAt(i);
7439
					MethodBinding otherMethod = (MethodBinding) other[0];
7786
7440
7787
					if (typeLength > typeParameter.name.length) continue;
7441
					if (method == otherMethod) continue next;
7788
7442
7789
					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
7443
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7790
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
7444
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7445
							continue next;
7446
						}
7447
					}
7448
				}
7791
7449
7792
					int relevance = computeBaseRelevance();
7450
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
7793
					relevance += computeRelevanceForResolution();
7451
					this.options.suggestStaticImport;
7794
					relevance += computeRelevanceForInterestingProposal();
7795
					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
7796
					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
7797
					relevance += computeRelevanceForQualification(false);
7798
					relevance += computeRelevanceForException(typeParameter.name);
7799
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
7800
7452
7801
					this.noProposal = false;
7453
				boolean isAlreadyImported = false;
7802
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7454
				if (!proposeStaticImport) {
7803
						createTypeParameterProposal(typeParameter, relevance);
7455
					if(!this.importCachesInitialized) {
7456
						initializeImportCaches();
7457
					}
7458
					for (int j = 0; j < this.importCacheCount; j++) {
7459
						char[][] importName = this.importsCache[j];
7460
						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
7461
							if (!CharOperation.equals(typeName, importName[1])) {
7462
								continue next;
7463
							} else {
7464
								isAlreadyImported = true;
7465
							}
7466
						}
7804
					}
7467
					}
7805
				}
7468
				}
7806
			}
7807
			scope = scope.parent;
7808
		}
7809
	}
7810
	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
7811
7469
7812
		if (token == null)
7470
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
7813
			return;
7814
7471
7815
		// do not propose type if completion token is empty
7472
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7816
		boolean skip = false;
7473
				if (method.declaringClass != superTypeWithSameErasure) {
7817
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
7474
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7818
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
7475
					for (int i = 0; i < otherMethods.length; i++) {
7819
				return;
7476
						if(otherMethods[i].original() == method.original()) {
7820
			}
7477
							method = otherMethods[i];
7821
			skip = true;
7478
						}
7822
		}
7479
					}
7480
				}
7823
7481
7824
		boolean proposeType =
7482
				int length = method.parameters.length;
7825
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
7483
				char[][] parameterPackageNames = new char[length][];
7826
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
7484
				char[][] parameterTypeNames = new char[length][];
7827
7485
7828
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
7486
				for (int i = 0; i < length; i++) {
7487
					TypeBinding type = method.original().parameters[i];
7488
					parameterPackageNames[i] = type.qualifiedPackageName();
7489
					parameterTypeNames[i] = type.qualifiedSourceName();
7490
				}
7491
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7829
7492
7830
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
7493
				char[] completion = CharOperation.NO_CHAR;
7831
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
7832
			if(!this.assistNodeIsInterface &&
7833
					!this.assistNodeIsConstructor &&
7834
					!this.assistNodeIsAnnotation &&
7835
					this.assistNodeInJavadoc == 0) {
7836
				// don't propose type parameters if the completion is a constructor ('new |')
7837
				findTypeParameters(token, scope);
7838
			}
7839
		}
7840
7494
7841
		boolean isEmptyPrefix = token.length == 0;
7495
				int previousStartPosition = this.startPosition;
7496
				int previousTokenStart = this.tokenStart;
7842
7497
7843
		if (!skip && proposeType && this.unitScope != null) {
7498
				if (this.source != null
7844
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
7499
					&& this.source.length > this.endPosition
7845
			if(outerInvocationType != null) {
7500
					&& this.source[this.endPosition] == '(') {
7846
				ReferenceBinding temp = outerInvocationType.enclosingType();
7501
					completion = method.selector;
7847
				while(temp != null) {
7502
				} else {
7848
					outerInvocationType = temp;
7503
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7849
					temp = temp.enclosingType();
7850
				}
7504
				}
7851
			}
7852
7505
7853
			int typeLength = token.length;
7506
				int relevance = computeBaseRelevance();
7854
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
7507
				relevance += computeRelevanceForResolution();
7508
				relevance += computeRelevanceForInterestingProposal();
7509
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7510
				relevance += computeRelevanceForExpectingType(method.returnType);
7511
				relevance += computeRelevanceForEnumConstant(method.returnType);
7512
				relevance += computeRelevanceForStatic(true, method.isStatic());
7513
				relevance += computeRelevanceForQualification(true);
7514
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7855
7515
7856
			next : for (int i = 0, length = types.length; i < length; i++) {
7516
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
7857
				SourceTypeBinding sourceType = types[i];
7517
				int importStart = cu.types[0].declarationSourceStart;
7518
				int importEnd = importStart;
7858
7519
7859
				if(isForbidden(sourceType)) continue next;
7520
				this.noProposal = false;
7860
7521
7861
				if(proposeAllMemberTypes &&
7522
				if (!proposeStaticImport) {
7862
					sourceType != outerInvocationType) {
7523
					if (isAlreadyImported) {
7863
					findSubMemberTypes(
7524
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
7864
							token,
7525
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
7865
							sourceType,
7866
							scope,
7867
							scope.enclosingSourceType(),
7868
							false,
7869
							false,
7870
							false,
7871
							typesFound);
7872
				}
7873
7526
7874
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
7527
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7875
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
7528
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
7529
							proposal.setSignature(getSignature(method));
7530
							MethodBinding original = method.original();
7531
							if(original != method) {
7532
								proposal.setOriginalSignature(getSignature(original));
7533
							}
7534
							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7535
							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7536
							proposal.setParameterPackageNames(parameterPackageNames);
7537
							proposal.setParameterTypeNames(parameterTypeNames);
7538
							proposal.setPackageName(method.returnType.qualifiedPackageName());
7539
							proposal.setTypeName(method.returnType.qualifiedSourceName());
7540
							proposal.setName(method.selector);
7541
							proposal.setCompletion(completion);
7542
							proposal.setFlags(method.modifiers);
7543
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7544
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7545
							proposal.setRelevance(relevance);
7546
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
7876
7547
7877
				if (typeLength > sourceType.sourceName.length) continue next;
7548
							this.requestor.accept(proposal);
7549
							if(DEBUG) {
7550
								this.printDebug(proposal);
7551
							}
7552
						}
7553
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
7554
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
7878
7555
7879
				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
7556
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7880
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
7557
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7558
						proposal.setSignature(getSignature(method));
7559
						MethodBinding original = method.original();
7560
						if(original != method) {
7561
							proposal.setOriginalSignature(getSignature(original));
7562
						}
7563
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7564
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7565
						proposal.setParameterPackageNames(parameterPackageNames);
7566
						proposal.setParameterTypeNames(parameterTypeNames);
7567
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7568
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7569
						proposal.setName(method.selector);
7570
						proposal.setCompletion(completion);
7571
						proposal.setFlags(method.modifiers);
7572
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7573
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7574
						proposal.setRelevance(relevance);
7575
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
7881
7576
7882
				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
7577
						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
7883
					continue next;
7884
				}
7885
7578
7886
				for (int j = typesFound.size; --j >= 0;) {
7579
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
7887
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
7580
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
7581
						typeImportProposal.completionEngine = this;
7582
						char[] packageName = receiverType.qualifiedPackageName();
7583
						typeImportProposal.setDeclarationSignature(packageName);
7584
						typeImportProposal.setSignature(getSignature(receiverType));
7585
						typeImportProposal.setPackageName(packageName);
7586
						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
7587
						typeImportProposal.setCompletion(typeImportCompletion);
7588
						typeImportProposal.setFlags(receiverType.modifiers);
7589
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
7590
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7591
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7592
						typeImportProposal.setRelevance(relevance);
7888
7593
7889
					if (sourceType == otherType) continue next;
7594
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
7890
				}
7891
7595
7892
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
7596
						this.requestor.accept(proposal);
7597
						if(DEBUG) {
7598
							this.printDebug(proposal);
7599
						}
7600
					}
7601
				} else {
7602
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
7603
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7604
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7605
						proposal.setSignature(getSignature(method));
7606
						MethodBinding original = method.original();
7607
						if(original != method) {
7608
							proposal.setOriginalSignature(getSignature(original));
7609
						}
7610
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7611
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7612
						proposal.setParameterPackageNames(parameterPackageNames);
7613
						proposal.setParameterTypeNames(parameterTypeNames);
7614
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7615
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7616
						proposal.setName(method.selector);
7617
						proposal.setCompletion(completion);
7618
						proposal.setFlags(method.modifiers);
7619
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7620
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7621
						proposal.setRelevance(relevance);
7622
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
7623
7624
						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
7625
7626
						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
7627
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
7628
						methodImportProposal.setSignature(getSignature(method));
7629
						if(original != method) {
7630
							proposal.setOriginalSignature(getSignature(original));
7631
						}
7632
						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7633
						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7634
						methodImportProposal.setParameterPackageNames(parameterPackageNames);
7635
						methodImportProposal.setParameterTypeNames(parameterTypeNames);
7636
						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
7637
						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
7638
						methodImportProposal.setName(method.selector);
7639
						methodImportProposal.setCompletion(methodImportCompletion);
7640
						methodImportProposal.setFlags(method.modifiers);
7641
						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
7642
						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7643
						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7644
						methodImportProposal.setRelevance(relevance);
7645
						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
7646
7647
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
7893
7648
7894
				if(this.assistNodeIsClass) {
7649
						this.requestor.accept(proposal);
7895
					if(!sourceType.isClass()) continue next;
7650
						if(DEBUG) {
7896
				} else if(this.assistNodeIsInterface) {
7651
							this.printDebug(proposal);
7897
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
7652
						}
7898
				} else if (this.assistNodeIsAnnotation) {
7899
					if(!sourceType.isAnnotationType()) continue next;
7900
				} else if (isEmptyPrefix && this.assistNodeIsException) {
7901
					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
7902
						continue next;
7903
					}
7653
					}
7904
				}
7654
				}
7905
7655
7906
				int relevance = computeBaseRelevance();
7656
				this.startPosition = previousStartPosition;
7907
				relevance += computeRelevanceForResolution();
7657
				this.tokenStart = previousTokenStart;
7908
				relevance += computeRelevanceForInterestingProposal();
7909
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
7910
				relevance += computeRelevanceForExpectingType(sourceType);
7911
				relevance += computeRelevanceForQualification(false);
7912
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
7913
7914
				if (sourceType.isAnnotationType()) {
7915
					relevance += computeRelevanceForAnnotation();
7916
					relevance += computeRelevanceForAnnotationTarget(sourceType);
7917
				} else if (sourceType.isInterface()) {
7918
					relevance += computeRelevanceForInterface();
7919
				} else if(sourceType.isClass()){
7920
					relevance += computeRelevanceForClass();
7921
					relevance += computeRelevanceForException(sourceType.sourceName);
7922
				}
7923
				this.noProposal = false;
7924
				if(proposeType) {
7925
					char[] typeName = sourceType.sourceName();
7926
					createTypeProposal(
7927
							sourceType,
7928
							typeName,
7929
							IAccessRule.K_ACCESSIBLE,
7930
							typeName,
7931
							relevance,
7932
							null,
7933
							null,
7934
							null,
7935
							false);
7936
				}
7937
			}
7658
			}
7938
		}
7659
		}
7939
7660
7940
		if(!skip && proposeType) {
7661
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
7941
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
7662
	private void findLocalMethodsFromStaticImports(
7942
		}
7663
		char[] methodName,
7664
		MethodBinding[] methods,
7665
		Scope scope,
7666
		boolean exactMatch,
7667
		ObjectVector methodsFound,
7668
		ReferenceBinding receiverType,
7669
		InvocationSite invocationSite) {
7943
7670
7944
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
7671
		ObjectVector newMethodsFound =  new ObjectVector();
7945
			if(proposeType && this.expectedTypesPtr > -1) {
7946
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
7947
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
7948
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
7949
7672
7950
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
7673
		next : for (int f = methods.length; --f >= 0;) {
7951
							// don't propose type variable if the completion is a constructor ('new |')
7674
			MethodBinding method = methods[f];
7952
							continue next;
7953
						}
7954
						if (this.options.checkDeprecation &&
7955
								refBinding.isViewedAsDeprecated() &&
7956
								!scope.isDefinedInSameUnit(refBinding))
7957
							continue next;
7958
7675
7959
						int accessibility = IAccessRule.K_ACCESSIBLE;
7676
			if (method.isSynthetic()) continue next;
7960
						if(refBinding.hasRestrictedAccess()) {
7961
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7962
							if(accessRestriction != null) {
7963
								switch (accessRestriction.getProblemId()) {
7964
									case IProblem.ForbiddenReference:
7965
										if (this.options.checkForbiddenReference) {
7966
											continue next;
7967
										}
7968
										accessibility = IAccessRule.K_NON_ACCESSIBLE;
7969
										break;
7970
									case IProblem.DiscouragedReference:
7971
										if (this.options.checkDiscouragedReference) {
7972
											continue next;
7973
										}
7974
										accessibility = IAccessRule.K_DISCOURAGED;
7975
										break;
7976
								}
7977
							}
7978
						}
7979
7677
7980
						for (int j = 0; j < typesFound.size(); j++) {
7678
			if (method.isDefaultAbstract())	continue next;
7981
							ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
7982
							if (typeFound == refBinding) {
7983
								continue next;
7984
							}
7985
						}
7986
7679
7987
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
7680
			if (method.isConstructor()) continue next;
7988
7681
7989
						// top level types of the current unit are already proposed.
7682
			if (!method.isStatic()) continue next;
7990
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
7991
							char[] packageName = refBinding.qualifiedPackageName();
7992
							char[] typeName = refBinding.sourceName();
7993
							char[] completionName = typeName;
7994
7683
7995
							boolean isQualified = false;
7684
			if (this.options.checkDeprecation &&
7996
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
7685
					method.isViewedAsDeprecated() &&
7997
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
7686
					!scope.isDefinedInSameUnit(method.declaringClass))
7998
									if (packageName == null || packageName.length == 0)
7687
				continue next;
7999
										if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
8000
											continue next; // ignore types from the default package from outside it
8001
									completionName = CharOperation.concat(packageName, typeName, '.');
8002
									isQualified = true;
8003
								}
8004
							}
8005
7688
8006
							if(this.assistNodeIsClass) {
7689
			if (this.options.checkVisibility
8007
								if(!refBinding.isClass()) continue next;
7690
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
8008
							} else if(this.assistNodeIsInterface) {
8009
								if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
8010
							} else if (this.assistNodeIsAnnotation) {
8011
								if(!refBinding.isAnnotationType()) continue next;
8012
							}
8013
7691
8014
							int relevance = computeBaseRelevance();
7692
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
8015
							relevance += computeRelevanceForResolution();
7693
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
8016
							relevance += computeRelevanceForInterestingProposal();
7694
				continue next;
8017
							relevance += computeRelevanceForCaseMatching(token, typeName);
8018
							relevance += computeRelevanceForExpectingType(refBinding);
8019
							relevance += computeRelevanceForQualification(isQualified);
8020
							relevance += computeRelevanceForRestrictions(accessibility);
8021
7695
8022
							if(refBinding.isClass()) {
7696
			for (int i = methodsFound.size; --i >= 0;) {
8023
								relevance += computeRelevanceForClass();
7697
				Object[] other = (Object[]) methodsFound.elementAt(i);
8024
								relevance += computeRelevanceForException(typeName);
7698
				MethodBinding otherMethod = (MethodBinding) other[0];
8025
							} else if(refBinding.isEnum()) {
7699
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
8026
								relevance += computeRelevanceForEnum();
7700
				if (method == otherMethod && receiverType == otherReceiverType)
8027
							} else if(refBinding.isInterface()) {
7701
					continue next;
8028
								relevance += computeRelevanceForInterface();
8029
							}
8030
7702
8031
							this.noProposal = false;
7703
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
8032
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7704
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
8033
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
7705
						continue next;
8034
								proposal.setDeclarationSignature(packageName);
8035
								proposal.setSignature(getSignature(refBinding));
8036
								proposal.setPackageName(packageName);
8037
								proposal.setTypeName(typeName);
8038
								proposal.setCompletion(completionName);
8039
								proposal.setFlags(refBinding.modifiers);
8040
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8041
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8042
								proposal.setRelevance(relevance);
8043
								proposal.setAccessibility(accessibility);
8044
								this.requestor.accept(proposal);
8045
								if(DEBUG) {
8046
									this.printDebug(proposal);
8047
								}
8048
							}
8049
						}
8050
					}
8051
				}
8052
			}
8053
		} else {
8054
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
8055
				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
8056
					if (proposeBaseTypes) {
8057
						if (proposeVoidType) {
8058
							findKeywords(token, BASE_TYPE_NAMES, false, false);
8059
						} else {
8060
							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
8061
						}
8062
					}
7706
					}
8063
				}
7707
				}
8064
			}
7708
			}
8065
			if(proposeType) {
8066
				int l = typesFound.size();
8067
				for (int i = 0; i < l; i++) {
8068
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
8069
					char[] fullyQualifiedTypeName =
8070
						CharOperation.concat(
8071
								typeFound.qualifiedPackageName(),
8072
								typeFound.qualifiedSourceName(),
8073
								'.');
8074
					this.knownTypes.put(fullyQualifiedTypeName, this);
8075
				}
8076
				int searchFor = IJavaSearchConstants.TYPE;
8077
				if(this.assistNodeIsClass) {
8078
					searchFor = IJavaSearchConstants.CLASS;
8079
				} else if(this.assistNodeIsInterface) {
8080
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
8081
				} else if(this.assistNodeIsEnum) {
8082
					searchFor = IJavaSearchConstants.ENUM;
8083
				} else if(this.assistNodeIsAnnotation) {
8084
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
8085
				}
8086
				this.nameEnvironment.findTypes(
8087
						token,
8088
						proposeAllMemberTypes,
8089
						this.options.camelCaseMatch,
8090
						searchFor,
8091
						this);
8092
				acceptTypes(scope);
8093
			}
8094
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
8095
				this.nameEnvironment.findPackages(token, this);
8096
			}
8097
		}
8098
	}
8099
8100
	private void findTypesAndSubpackages(
8101
		char[] token,
8102
		PackageBinding packageBinding,
8103
		Scope scope) {
8104
8105
		boolean proposeType =
8106
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
8107
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
8108
7709
8109
		char[] qualifiedName =
7710
			newMethodsFound.add(new Object[]{method, receiverType});
8110
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
8111
7711
8112
		if (token == null || token.length == 0) {
7712
			int length = method.parameters.length;
8113
			int length = qualifiedName.length;
7713
			char[][] parameterPackageNames = new char[length][];
8114
			System.arraycopy(
7714
			char[][] parameterTypeNames = new char[length][];
8115
				qualifiedName,
8116
				0,
8117
				qualifiedName = new char[length + 1],
8118
				0,
8119
				length);
8120
			qualifiedName[length] = '.';
8121
		}
8122
7715
8123
		this.qualifiedCompletionToken = qualifiedName;
7716
			for (int i = 0; i < length; i++) {
7717
				TypeBinding type = method.original().parameters[i];
7718
				parameterPackageNames[i] = type.qualifiedPackageName();
7719
				parameterTypeNames[i] = type.qualifiedSourceName();
7720
			}
7721
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
8124
7722
8125
		if (proposeType && this.unitScope != null) {
7723
			char[] completion = CharOperation.NO_CHAR;
8126
			int typeLength = qualifiedName.length;
8127
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
8128
7724
8129
			for (int i = 0, length = types.length; i < length; i++) {
7725
			int previousStartPosition = this.startPosition;
8130
				SourceTypeBinding sourceType = types[i];
7726
			int previousTokenStart = this.tokenStart;
8131
7727
8132
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
7728
			if (!exactMatch) {
7729
				if (this.source != null
7730
					&& this.source.length > this.endPosition
7731
					&& this.source[this.endPosition] == '(') {
7732
					completion = method.selector;
7733
				} else {
7734
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7735
				}
7736
			} else {
7737
				this.startPosition = this.endPosition;
7738
				this.tokenStart = this.tokenEnd;
7739
			}
8133
7740
8134
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
7741
			int relevance = computeBaseRelevance();
8135
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
7742
			relevance += computeRelevanceForResolution();
8136
				if (typeLength > qualifiedSourceTypeName.length) continue;
7743
			relevance += computeRelevanceForInterestingProposal();
8137
				if (!(packageBinding == sourceType.getPackage())) continue;
7744
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7745
			relevance += computeRelevanceForExpectingType(method.returnType);
7746
			relevance += computeRelevanceForEnumConstant(method.returnType);
7747
			relevance += computeRelevanceForStatic(true, method.isStatic());
7748
			relevance += computeRelevanceForQualification(false);
7749
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8138
7750
8139
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
7751
			this.noProposal = false;
8140
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
7752
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7753
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7754
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
7755
				proposal.setSignature(getSignature(method));
7756
				MethodBinding original = method.original();
7757
				if(original != method) {
7758
					proposal.setOriginalSignature(getSignature(original));
7759
				}
7760
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7761
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7762
				proposal.setParameterPackageNames(parameterPackageNames);
7763
				proposal.setParameterTypeNames(parameterTypeNames);
7764
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7765
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7766
				proposal.setName(method.selector);
7767
				proposal.setCompletion(completion);
7768
				proposal.setFlags(method.modifiers);
7769
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7770
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7771
				proposal.setRelevance(relevance);
7772
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7773
				this.requestor.accept(proposal);
7774
				if(DEBUG) {
7775
					this.printDebug(proposal);
7776
				}
7777
			}
7778
			this.startPosition = previousStartPosition;
7779
			this.tokenStart = previousTokenStart;
7780
		}
8141
7781
8142
				if (this.options.checkDeprecation &&
7782
		methodsFound.addAll(newMethodsFound);
8143
						sourceType.isViewedAsDeprecated() &&
7783
	}
8144
						!scope.isDefinedInSameUnit(sourceType))
8145
					continue;
8146
7784
8147
				int accessibility = IAccessRule.K_ACCESSIBLE;
7785
	private void findLocalMethodsFromStaticImports(
8148
				if(sourceType.hasRestrictedAccess()) {
7786
			char[] token,
8149
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
7787
			Scope scope,
8150
					if(accessRestriction != null) {
7788
			InvocationSite invocationSite,
8151
						switch (accessRestriction.getProblemId()) {
7789
			Scope invocationScope,
8152
							case IProblem.ForbiddenReference:
7790
			boolean exactMatch,
8153
								if (this.options.checkForbiddenReference) {
7791
			ObjectVector methodsFound,
8154
									continue;
7792
			boolean proposeMethod) {
8155
								}
7793
		findFieldsAndMethodsFromStaticImports(
8156
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
7794
				token,
8157
								break;
7795
				scope,
8158
							case IProblem.DiscouragedReference:
7796
				invocationSite,
8159
								if (this.options.checkDiscouragedReference) {
7797
				invocationScope,
8160
									continue;
7798
				exactMatch,
8161
								}
7799
				false,
8162
								accessibility = IAccessRule.K_DISCOURAGED;
7800
				new ObjectVector(),
8163
								break;
7801
				new ObjectVector(),
8164
						}
7802
				methodsFound,
8165
					}
7803
				false,
8166
				}
7804
				proposeMethod);
7805
	}
7806
	protected void findMembers(
7807
			char[] token,
7808
			ReferenceBinding receiverType,
7809
			Scope scope,
7810
			InvocationSite invocationSite,
7811
			boolean isInsideAnnotationAttribute,
7812
			Binding[] missingElements,
7813
			int[] missingElementsStarts,
7814
			int[] missingElementsEnds,
7815
			boolean missingElementsHaveProblems) {
8167
7816
8168
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
7817
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7818
			findMemberTypes(
7819
					token,
7820
					receiverType,
7821
					scope,
7822
					scope.enclosingSourceType(),
7823
					false,
7824
					true,
7825
					new ObjectVector(),
7826
					missingElements,
7827
					missingElementsStarts,
7828
					missingElementsEnds,
7829
					missingElementsHaveProblems);
7830
		}
7831
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
7832
			findClassField(
7833
					token,
7834
					receiverType,
7835
					scope,
7836
					missingElements,
7837
					missingElementsStarts,
7838
					missingElementsEnds,
7839
					missingElementsHaveProblems);
7840
		}
8169
7841
7842
		MethodScope methodScope = null;
7843
		if (!isInsideAnnotationAttribute &&
7844
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
7845
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
7846
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
7847
			if (token.length > 0) {
7848
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
7849
			} else {
8170
				int relevance = computeBaseRelevance();
7850
				int relevance = computeBaseRelevance();
8171
				relevance += computeRelevanceForResolution();
7851
				relevance += computeRelevanceForResolution();
8172
				relevance += computeRelevanceForInterestingProposal();
7852
				relevance += computeRelevanceForInterestingProposal();
8173
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
7853
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
8174
				relevance += computeRelevanceForExpectingType(sourceType);
7854
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
8175
				relevance += computeRelevanceForQualification(false);
7855
				relevance += R_NON_INHERITED;
8176
				relevance += computeRelevanceForRestrictions(accessibility);
8177
7856
8178
				if (sourceType.isAnnotationType()) {
8179
					relevance += computeRelevanceForAnnotation();
8180
				} else if (sourceType.isInterface()) {
8181
					relevance += computeRelevanceForInterface();
8182
				} else if (sourceType.isClass()) {
8183
					relevance += computeRelevanceForClass();
8184
					relevance += computeRelevanceForException(sourceType.sourceName);
8185
				}
8186
				this.noProposal = false;
7857
				this.noProposal = false;
8187
				if(proposeType) {
7858
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
8188
					char[] typeName = sourceType.sourceName();
7859
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
8189
					createTypeProposal(
7860
					proposal.setName(Keywords.THIS);
8190
							sourceType,
7861
					proposal.setCompletion(Keywords.THIS);
8191
							typeName,
7862
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8192
							IAccessRule.K_ACCESSIBLE,
7863
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8193
							typeName,
7864
					proposal.setRelevance(relevance);
8194
							relevance,
7865
					this.requestor.accept(proposal);
8195
							null,
7866
					if (DEBUG) {
8196
							null,
7867
						this.printDebug(proposal);
8197
							null,
7868
					}
8198
							false);
8199
				}
7869
				}
8200
			}
7870
			}
8201
		}
7871
		}
8202
7872
8203
		if(proposeType) {
7873
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
8204
			int searchFor = IJavaSearchConstants.TYPE;
7874
			findFields(
8205
			if(this.assistNodeIsClass) {
7875
				token,
8206
				searchFor = IJavaSearchConstants.CLASS;
7876
				receiverType,
8207
			} else if(this.assistNodeIsInterface) {
7877
				scope,
8208
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
7878
				new ObjectVector(),
8209
			} else if(this.assistNodeIsEnum) {
7879
				new ObjectVector(),
8210
				searchFor = IJavaSearchConstants.ENUM;
7880
				true,
8211
			} else if(this.assistNodeIsAnnotation) {
7881
				invocationSite,
8212
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
7882
				scope,
8213
			}
7883
				false,
8214
			this.nameEnvironment.findTypes(
7884
				false,
8215
					qualifiedName,
7885
				missingElements,
8216
					false,
7886
				missingElementsStarts,
8217
					this.options.camelCaseMatch,
7887
				missingElementsEnds,
8218
					searchFor,
7888
				missingElementsHaveProblems,
8219
					this);
7889
				null,
8220
			acceptTypes(scope);
7890
				-1,
7891
				-1);
8221
		}
7892
		}
8222
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
7893
8223
			this.nameEnvironment.findPackages(qualifiedName, this);
7894
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7895
			findMethods(
7896
				token,
7897
				null,
7898
				null,
7899
				receiverType,
7900
				scope,
7901
				new ObjectVector(),
7902
				true,
7903
				false,
7904
				invocationSite,
7905
				scope,
7906
				false,
7907
				false,
7908
				false,
7909
				missingElements,
7910
				missingElementsStarts,
7911
				missingElementsEnds,
7912
				missingElementsHaveProblems,
7913
				null,
7914
				-1,
7915
				-1);
8224
		}
7916
		}
8225
	}
7917
	}
8226
7918
8227
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
7919
	private void findMembersFromMissingType(
8228
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
7920
			final char[] token,
8229
		for (int i = 0; i < importBindings.length; i++) {
7921
			final long pos,
8230
			ImportBinding importBinding = importBindings[i];
7922
			TypeBinding resolveType,
8231
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
7923
			final Scope scope,
8232
				Binding binding = importBinding.resolvedImport;
7924
			final InvocationSite invocationSite,
8233
				if(binding != null && binding.isValidBinding()) {
7925
			final boolean isInsideAnnotationAttribute) {
8234
					if(importBinding.onDemand) {
7926
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8235
						if((binding.kind() & Binding.TYPE) != 0) {
7927
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8236
							this.findMemberTypes(
7928
			new MissingTypesGuesser.GuessedTypeRequestor() {
8237
									token,
7929
				public void accept(
8238
									(ReferenceBinding) binding,
7930
						TypeBinding guessedType,
8239
									scope,
7931
						Binding[] missingElements,
8240
									scope.enclosingSourceType(),
7932
						int[] missingElementsStarts,
8241
									true,
7933
						int[] missingElementsEnds,
8242
									false,
7934
						boolean hasProblems) {
8243
									true,
7935
					if (guessedType instanceof ReferenceBinding) {
8244
									true,
7936
						findMembers(
8245
									proposeAllMemberTypes,
7937
								CompletionEngine.this.completionToken,
8246
									null,
7938
								(ReferenceBinding)guessedType,
8247
									typesFound,
7939
								scope,
8248
									null,
7940
								invocationSite,
8249
									null,
7941
								isInsideAnnotationAttribute,
8250
									null,
7942
								missingElements,
8251
									false);
7943
								missingElementsStarts,
8252
						}
7944
								missingElementsEnds,
8253
					} else {
7945
								hasProblems);
8254
						if ((binding.kind() & Binding.TYPE) != 0) {
7946
					}
8255
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
7947
				}
8256
							int typeLength = token.length;
7948
			};
7949
		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
7950
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
7951
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
7952
	}
8257
7953
8258
							if (!typeBinding.isStatic()) continue;
7954
	private void findMemberTypes(
7955
		char[] typeName,
7956
		ReferenceBinding receiverType,
7957
		Scope scope,
7958
		SourceTypeBinding typeInvocation,
7959
		boolean staticOnly,
7960
		boolean staticFieldsAndMethodOnly,
7961
		boolean fromStaticImport,
7962
		boolean checkQualification,
7963
		boolean proposeAllMemberTypes,
7964
		SourceTypeBinding typeToIgnore,
7965
		ObjectVector typesFound,
7966
		Binding[] missingElements,
7967
		int[] missingElementsStarts,
7968
		int[] missingElementsEnds,
7969
		boolean missingElementsHaveProblems) {
8259
7970
8260
							if (typeLength > typeBinding.sourceName.length)	continue;
7971
		ReferenceBinding currentType = receiverType;
7972
		if (typeName == null)
7973
			return;
8261
7974
8262
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
7975
		if (this.insideQualifiedReference
8263
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
7976
			|| typeName.length == 0) { // do not search up the hierarchy
8264
7977
8265
							if (typesFound.contains(typeBinding))  continue;
7978
			findMemberTypes(
7979
				typeName,
7980
				currentType.memberTypes(),
7981
				typesFound,
7982
				receiverType,
7983
				typeInvocation,
7984
				staticOnly,
7985
				staticFieldsAndMethodOnly,
7986
				fromStaticImport,
7987
				checkQualification,
7988
				scope,
7989
				missingElements,
7990
				missingElementsStarts,
7991
				missingElementsEnds,
7992
				missingElementsHaveProblems);
7993
			return;
7994
		}
8266
7995
8267
							typesFound.add(typeBinding);
7996
		ReferenceBinding[] interfacesToVisit = null;
7997
		int nextPosition = 0;
8268
7998
8269
							if(this.assistNodeIsClass) {
7999
		do {
8270
								if(!typeBinding.isClass()) continue;
8000
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
8271
							} else if(this.assistNodeIsInterface) {
8001
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8272
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
8002
				if (interfacesToVisit == null) {
8273
							} else if (this.assistNodeIsAnnotation) {
8003
					interfacesToVisit = itsInterfaces;
8274
								if(!typeBinding.isAnnotationType()) continue;
8004
					nextPosition = interfacesToVisit.length;
8275
							}
8005
				} else {
8006
					int itsLength = itsInterfaces.length;
8007
					if (nextPosition + itsLength >= interfacesToVisit.length)
8008
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8009
					nextInterface : for (int a = 0; a < itsLength; a++) {
8010
						ReferenceBinding next = itsInterfaces[a];
8011
						for (int b = 0; b < nextPosition; b++)
8012
							if (next == interfacesToVisit[b]) continue nextInterface;
8013
						interfacesToVisit[nextPosition++] = next;
8014
					}
8015
				}
8016
			}
8276
8017
8277
							int relevance = computeBaseRelevance();
8018
			findMemberTypes(
8278
							relevance += computeRelevanceForResolution();
8019
				typeName,
8279
							relevance += computeRelevanceForInterestingProposal();
8020
				currentType.memberTypes(),
8280
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
8021
				typesFound,
8281
							relevance += computeRelevanceForExpectingType(typeBinding);
8022
				receiverType,
8282
							relevance += computeRelevanceForQualification(false);
8023
				typeInvocation,
8283
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8024
				staticOnly,
8025
				staticFieldsAndMethodOnly,
8026
				fromStaticImport,
8027
				checkQualification,
8028
				scope,
8029
				missingElements,
8030
				missingElementsStarts,
8031
				missingElementsEnds,
8032
				missingElementsHaveProblems);
8284
8033
8285
							if (typeBinding.isClass()) {
8034
			currentType = currentType.superclass();
8286
								relevance += computeRelevanceForClass();
8035
		} while (currentType != null);
8287
								relevance += computeRelevanceForException(typeBinding.sourceName);
8288
							} else if(typeBinding.isEnum()) {
8289
								relevance += computeRelevanceForEnum();
8290
							} else if(typeBinding.isInterface()) {
8291
								relevance += computeRelevanceForInterface();
8292
							}
8293
8036
8294
							this.noProposal = false;
8037
		if(proposeAllMemberTypes) {
8295
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8038
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
8296
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
8039
			for (int i = 0; i < memberTypes.length; i++) {
8297
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
8040
				if(memberTypes[i] != typeToIgnore) {
8298
								proposal.setSignature(getSignature(typeBinding));
8041
					findSubMemberTypes(
8299
								proposal.setPackageName(typeBinding.qualifiedPackageName());
8042
						typeName,
8300
								proposal.setTypeName(typeBinding.qualifiedSourceName());
8043
						memberTypes[i],
8301
								proposal.setCompletion(typeBinding.sourceName());
8044
						scope,
8302
								proposal.setFlags(typeBinding.modifiers);
8045
						typeInvocation,
8303
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8046
						staticOnly,
8304
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8047
						staticFieldsAndMethodOnly,
8305
								proposal.setRelevance(relevance);
8048
						fromStaticImport,
8306
								this.requestor.accept(proposal);
8049
						typesFound);
8307
								if(DEBUG) {
8050
				}
8308
									this.printDebug(proposal);
8051
			}
8309
								}
8052
		}
8310
							}
8053
8311
						}
8054
		if (interfacesToVisit != null) {
8055
			for (int i = 0; i < nextPosition; i++) {
8056
				ReferenceBinding anInterface = interfacesToVisit[i];
8057
				findMemberTypes(
8058
					typeName,
8059
					anInterface.memberTypes(),
8060
					typesFound,
8061
					receiverType,
8062
					typeInvocation,
8063
					staticOnly,
8064
					staticFieldsAndMethodOnly,
8065
					fromStaticImport,
8066
					checkQualification,
8067
					scope,
8068
					missingElements,
8069
					missingElementsStarts,
8070
					missingElementsEnds,
8071
					missingElementsHaveProblems);
8072
8073
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
8074
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8075
					int itsLength = itsInterfaces.length;
8076
					if (nextPosition + itsLength >= interfacesToVisit.length)
8077
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8078
					nextInterface : for (int a = 0; a < itsLength; a++) {
8079
						ReferenceBinding next = itsInterfaces[a];
8080
						for (int b = 0; b < nextPosition; b++)
8081
							if (next == interfacesToVisit[b]) continue nextInterface;
8082
						interfacesToVisit[nextPosition++] = next;
8312
					}
8083
					}
8313
				}
8084
				}
8314
			}
8085
			}
8315
		}
8086
		}
8316
	}
8087
	}
8317
	private void findVariablesAndMethods(
8088
8318
		char[] token,
8089
	protected void findMemberTypes(
8090
		char[] typeName,
8091
		ReferenceBinding receiverType,
8092
		Scope scope,
8093
		SourceTypeBinding typeInvocation,
8094
		boolean staticOnly,
8095
		boolean staticFieldsAndMethodOnly,
8096
		ObjectVector typesFound,
8097
		Binding[] missingElements,
8098
		int[] missingElementsStarts,
8099
		int[] missingElementsEnds,
8100
		boolean missingElementsHaveProblems)  {
8101
		findMemberTypes(
8102
				typeName,
8103
				receiverType,
8104
				scope,
8105
				typeInvocation,
8106
				staticOnly,
8107
				staticFieldsAndMethodOnly,
8108
				false,
8109
				false,
8110
				false,
8111
				null,
8112
				typesFound,
8113
				missingElements,
8114
				missingElementsStarts,
8115
				missingElementsEnds,
8116
				missingElementsHaveProblems);
8117
	}
8118
		// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
8119
	private void findMemberTypes(
8120
		char[] typeName,
8121
		ReferenceBinding[] memberTypes,
8122
		ObjectVector typesFound,
8123
		ReferenceBinding receiverType,
8124
		SourceTypeBinding invocationType,
8125
		boolean staticOnly,
8126
		boolean staticFieldsAndMethodOnly,
8127
		boolean fromStaticImport,
8128
		boolean checkQualification,
8319
		Scope scope,
8129
		Scope scope,
8320
		InvocationSite invocationSite,
8130
		Binding[] missingElements,
8321
		Scope invocationScope,
8131
		int[] missingElementsStarts,
8322
		boolean insideTypeAnnotation,
8132
		int[] missingElementsEnds,
8323
		boolean insideAnnotationAttribute) {
8133
		boolean missingElementsHaveProblems) {
8324
8325
		if (token == null)
8326
			return;
8327
8328
		// Should local variables hide fields from the receiver type or any of its enclosing types?
8329
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
8330
8331
		boolean staticsOnly = false;
8332
		// need to know if we're in a static context (or inside a constructor)
8333
		int tokenLength = token.length;
8334
8134
8335
		ObjectVector localsFound = new ObjectVector();
8135
		// Inherited member types which are hidden by subclasses are filtered out
8336
		ObjectVector fieldsFound = new ObjectVector();
8136
		// No visibility checks can be performed without the scope & invocationSite
8337
		ObjectVector methodsFound = new ObjectVector();
8137
		int typeLength = typeName.length;
8138
		next : for (int m = memberTypes.length; --m >= 0;) {
8139
			ReferenceBinding memberType = memberTypes[m];
8140
			//		if (!wantClasses && memberType.isClass()) continue next;
8141
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
8338
8142
8339
		Scope currentScope = scope;
8143
			if (staticOnly && !memberType.isStatic()) continue next;
8340
8144
8341
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
8145
			if (isForbidden(memberType)) continue next;
8342
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
8343
8146
8344
				switch (currentScope.kind) {
8147
			if (typeLength > memberType.sourceName.length)
8148
				continue next;
8345
8149
8346
					case Scope.METHOD_SCOPE :
8150
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
8347
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
8151
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
8348
						MethodScope methodScope = (MethodScope) currentScope;
8152
				continue next;
8349
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
8350
8153
8351
					//$FALL-THROUGH$
8154
			if (this.options.checkDeprecation &&
8352
					case Scope.BLOCK_SCOPE :
8155
					memberType.isViewedAsDeprecated() &&
8353
						BlockScope blockScope = (BlockScope) currentScope;
8156
					!scope.isDefinedInSameUnit(memberType))
8157
				continue next;
8354
8158
8355
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
8159
			if (this.options.checkVisibility) {
8356
							LocalVariableBinding local = blockScope.locals[i];
8160
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
8161
					continue next;
8162
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
8163
					continue next;
8164
				}
8165
			}
8357
8166
8358
							if (local == null)
8167
			if (this.insideQualifiedReference &&
8359
								break next;
8168
					receiverType.isParameterizedType() &&
8169
					memberType.isStatic()) {
8170
				continue next;
8171
			}
8360
8172
8361
							if (tokenLength > local.name.length)
8173
			for (int i = typesFound.size; --i >= 0;) {
8362
								continue next;
8174
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
8363
8175
8364
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
8176
				if (memberType == otherType)
8365
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
8177
					continue next;
8366
								continue next;
8367
8178
8368
							if (local.isSecret())
8179
				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
8369
								continue next;
8370
8180
8371
							for (int f = 0; f < localsFound.size; f++) {
8181
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
8372
								LocalVariableBinding otherLocal =
8182
						continue next;
8373
									(LocalVariableBinding) localsFound.elementAt(f);
8374
								if (CharOperation.equals(otherLocal.name, local.name, true))
8375
									continue next;
8376
							}
8377
							localsFound.add(local);
8378
8183
8379
							int relevance = computeBaseRelevance();
8184
					if (otherType.enclosingType().isInterface())
8380
							relevance += computeRelevanceForResolution();
8185
						if (memberType.enclosingType()
8381
							relevance += computeRelevanceForInterestingProposal(local);
8186
							.implementsInterface(otherType.enclosingType(), true))
8382
							relevance += computeRelevanceForCaseMatching(token, local.name);
8187
							continue next;
8383
							relevance += computeRelevanceForExpectingType(local.type);
8384
							relevance += computeRelevanceForEnumConstant(local.type);
8385
							relevance += computeRelevanceForQualification(false);
8386
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
8387
							this.noProposal = false;
8388
							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
8389
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
8390
								proposal.setSignature(
8391
									local.type == null
8392
									? createTypeSignature(
8393
											CharOperation.NO_CHAR,
8394
											local.declaration.type.toString().toCharArray())
8395
									: getSignature(local.type));
8396
								if(local.type == null) {
8397
									//proposal.setPackageName(null);
8398
									proposal.setTypeName(local.declaration.type.toString().toCharArray());
8399
								} else {
8400
									proposal.setPackageName(local.type.qualifiedPackageName());
8401
									proposal.setTypeName(local.type.qualifiedSourceName());
8402
								}
8403
								proposal.setName(local.name);
8404
								proposal.setCompletion(local.name);
8405
								proposal.setFlags(local.modifiers);
8406
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8407
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8408
								proposal.setRelevance(relevance);
8409
								this.requestor.accept(proposal);
8410
								if(DEBUG) {
8411
									this.printDebug(proposal);
8412
								}
8413
							}
8414
						}
8415
						break;
8416
8188
8417
					case Scope.COMPILATION_UNIT_SCOPE :
8189
					if (memberType.enclosingType().isInterface())
8418
						break done1;
8190
						if (otherType.enclosingType()
8191
							.implementsInterface(memberType.enclosingType(), true))
8192
							continue next;
8419
				}
8193
				}
8420
				currentScope = currentScope.parent;
8421
			}
8194
			}
8422
		}
8423
8424
		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
8425
		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
8426
8195
8427
		staticsOnly = false;
8196
			typesFound.add(memberType);
8428
		currentScope = scope;
8429
8197
8430
		if(proposeField || proposeMethod) {
8198
			if(!this.insideQualifiedReference) {
8431
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
8199
				if(this.assistNodeIsClass) {
8200
					if(!memberType.isClass()) continue next;
8201
				} else if(this.assistNodeIsInterface) {
8202
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
8203
				} else if (this.assistNodeIsAnnotation) {
8204
					if(!memberType.isAnnotationType()) continue next;
8205
				}
8206
			}
8432
8207
8433
				switch (currentScope.kind) {
8208
			char[] completionName = memberType.sourceName();
8434
					case Scope.METHOD_SCOPE :
8435
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
8436
						MethodScope methodScope = (MethodScope) currentScope;
8437
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
8438
						break;
8439
					case Scope.CLASS_SCOPE :
8440
						ClassScope classScope = (ClassScope) currentScope;
8441
						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
8442
						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
8443
											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
8444
											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
8445
											break done;
8446
										} else { */
8447
						if(!insideTypeAnnotation) {
8448
							if(proposeField) {
8449
								findFields(
8450
									token,
8451
									enclosingType,
8452
									classScope,
8453
									fieldsFound,
8454
									localsFound,
8455
									staticsOnly,
8456
									invocationSite,
8457
									invocationScope,
8458
									true,
8459
									true,
8460
									null,
8461
									null,
8462
									null,
8463
									false,
8464
									null,
8465
									-1,
8466
									-1);
8467
							}
8468
							if(proposeMethod && !insideAnnotationAttribute) {
8469
								findMethods(
8470
									token,
8471
									null,
8472
									null,
8473
									enclosingType,
8474
									classScope,
8475
									methodsFound,
8476
									staticsOnly,
8477
									false,
8478
									false,
8479
									invocationSite,
8480
									invocationScope,
8481
									true,
8482
									false,
8483
									true,
8484
									null,
8485
									null,
8486
									null,
8487
									false,
8488
									null,
8489
									-1,
8490
									-1);
8491
							}
8492
						}
8493
						staticsOnly |= enclosingType.isStatic();
8494
						insideTypeAnnotation = false;
8495
						//				}
8496
						break;
8497
8209
8498
					case Scope.COMPILATION_UNIT_SCOPE :
8210
			boolean isQualified = false;
8499
						break done2;
8211
			if(checkQualification && !fromStaticImport) {
8212
				char[] memberPackageName = memberType.qualifiedPackageName();
8213
				char[] memberTypeName = memberType.sourceName();
8214
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
8215
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
8216
					if (memberPackageName == null || memberPackageName.length == 0)
8217
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
8218
							break next; // ignore types from the default package from outside it
8219
					isQualified = true;
8220
					completionName =
8221
						CharOperation.concat(
8222
								memberPackageName,
8223
								CharOperation.concat(
8224
										memberEnclosingTypeNames,
8225
										memberTypeName,
8226
										'.'),
8227
								'.');
8500
				}
8228
				}
8501
				currentScope = currentScope.parent;
8502
			}
8229
			}
8503
8230
8504
			findFieldsAndMethodsFromStaticImports(
8231
			int relevance = computeBaseRelevance();
8505
					token,
8232
			relevance += computeRelevanceForResolution();
8506
					scope,
8233
			relevance += computeRelevanceForInterestingProposal();
8507
					invocationSite,
8234
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
8508
					invocationScope,
8235
			relevance += computeRelevanceForExpectingType(memberType);
8509
					false,
8236
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8510
					insideAnnotationAttribute,
8237
			if(!this.insideQualifiedReference) {
8511
					localsFound,
8238
				relevance += computeRelevanceForQualification(isQualified);
8512
					fieldsFound,
8239
			}
8513
					methodsFound,
8240
			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.
8514
					proposeField,
8515
					proposeMethod);
8516
8241
8517
			if (this.assistNodeInJavadoc == 0) {
8242
			if (memberType.isAnnotationType()) {
8518
				// search in favorites import
8243
				relevance += computeRelevanceForAnnotation();
8519
				findFieldsAndMethodsFromFavorites(
8244
				relevance += computeRelevanceForAnnotationTarget(memberType);
8520
						token,
8245
			} else if (memberType.isClass()) {
8521
						scope,
8246
				relevance += computeRelevanceForClass();
8522
						invocationSite,
8247
				relevance += computeRelevanceForException(memberType.sourceName);
8523
						invocationScope,
8248
			} else if(memberType.isEnum()) {
8524
						localsFound,
8249
				relevance += computeRelevanceForEnum();
8525
						fieldsFound,
8250
			} else if(memberType.isInterface()) {
8526
						methodsFound);
8251
				relevance += computeRelevanceForInterface();
8527
			}
8252
			}
8528
8253
8529
			findEnumConstantsFromExpectedTypes(
8254
			if (missingElements != null) {
8530
					token,
8255
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
8531
					invocationScope,
8256
			}
8532
					fieldsFound);
8257
8258
			this.noProposal = false;
8259
			createTypeProposal(
8260
					memberType,
8261
					memberType.qualifiedSourceName(),
8262
					IAccessRule.K_ACCESSIBLE,
8263
					completionName,
8264
					relevance,
8265
					missingElements,
8266
					missingElementsStarts,
8267
					missingElementsEnds,
8268
					missingElementsHaveProblems);
8533
		}
8269
		}
8534
	}
8270
	}
8535
8271
	private void findMemberTypesFromMissingType(
8536
	private void findLocalMethodsFromStaticImports(
8272
			char[] typeName,
8537
			char[] token,
8273
			final long pos,
8538
			Scope scope,
8274
			final Scope scope)  {
8539
			InvocationSite invocationSite,
8275
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8540
			Scope invocationScope,
8276
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8541
			boolean exactMatch,
8277
			new MissingTypesGuesser.GuessedTypeRequestor() {
8542
			ObjectVector methodsFound,
8278
				public void accept(
8543
			boolean proposeMethod) {
8279
						TypeBinding guessedType,
8544
		findFieldsAndMethodsFromStaticImports(
8280
						Binding[] missingElements,
8545
				token,
8281
						int[] missingElementsStarts,
8546
				scope,
8282
						int[] missingElementsEnds,
8547
				invocationSite,
8283
						boolean hasProblems) {
8548
				invocationScope,
8284
					if (guessedType instanceof ReferenceBinding) {
8549
				exactMatch,
8285
						findMemberTypes(
8550
				false,
8286
								CompletionEngine.this.completionToken,
8551
				new ObjectVector(),
8287
								(ReferenceBinding)guessedType,
8552
				new ObjectVector(),
8288
								scope,
8553
				methodsFound,
8289
								scope.enclosingSourceType(),
8554
				false,
8290
								false,
8555
				proposeMethod);
8291
								false,
8292
								new ObjectVector(),
8293
								missingElements,
8294
								missingElementsStarts,
8295
								missingElementsEnds,
8296
								hasProblems);
8297
					}
8298
				}
8299
			};
8300
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
8301
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
8302
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8556
	}
8303
	}
8557
8304
	
8558
	private void findFieldsAndMethodsFromStaticImports(
8305
	private void findMemberTypesFromMissingType(
8559
			char[] token,
8306
			TypeReference typeRef,
8560
			Scope scope,
8307
			final long pos,
8561
			InvocationSite invocationSite,
8308
			final Scope scope)  {
8562
			Scope invocationScope,
8309
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8563
			boolean exactMatch,
8310
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8564
			boolean insideAnnotationAttribute,
8311
			new MissingTypesGuesser.GuessedTypeRequestor() {
8565
			ObjectVector localsFound,
8312
				public void accept(
8566
			ObjectVector fieldsFound,
8313
						TypeBinding guessedType,
8567
			ObjectVector methodsFound,
8314
						Binding[] missingElements,
8568
			boolean proposeField,
8315
						int[] missingElementsStarts,
8569
			boolean proposeMethod) {
8316
						int[] missingElementsEnds,
8570
		// search in static import
8317
						boolean hasProblems) {
8571
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
8318
					if (guessedType instanceof ReferenceBinding) {
8572
		for (int i = 0; i < importBindings.length; i++) {
8319
						findMemberTypes(
8573
			ImportBinding importBinding = importBindings[i];
8320
								CompletionEngine.this.completionToken,
8574
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
8321
								(ReferenceBinding)guessedType,
8575
				Binding binding = importBinding.resolvedImport;
8322
								scope,
8576
				if(binding != null && binding.isValidBinding()) {
8323
								scope.enclosingSourceType(),
8577
					if(importBinding.onDemand) {
8324
								false,
8578
						if((binding.kind() & Binding.TYPE) != 0) {
8325
								false,
8579
							if(proposeField) {
8326
								new ObjectVector(),
8580
								findFields(
8327
								missingElements,
8581
									token,
8328
								missingElementsStarts,
8582
									(ReferenceBinding)binding,
8329
								missingElementsEnds,
8583
									scope,
8330
								hasProblems);
8584
									fieldsFound,
8585
									localsFound,
8586
									true,
8587
									invocationSite,
8588
									invocationScope,
8589
									true,
8590
									false,
8591
									null,
8592
									null,
8593
									null,
8594
									false,
8595
									null,
8596
									-1,
8597
									-1);
8598
							}
8599
							if(proposeMethod && !insideAnnotationAttribute) {
8600
								findMethods(
8601
									token,
8602
									null,
8603
									null,
8604
									(ReferenceBinding)binding,
8605
									scope,
8606
									methodsFound,
8607
									true,
8608
									exactMatch,
8609
									false,
8610
									invocationSite,
8611
									invocationScope,
8612
									true,
8613
									false,
8614
									false,
8615
									null,
8616
									null,
8617
									null,
8618
									false,
8619
									null,
8620
									-1,
8621
									-1);
8622
							}
8623
						}
8624
					} else {
8625
						if ((binding.kind() & Binding.FIELD) != 0) {
8626
							if(proposeField) {
8627
									findFields(
8628
											token,
8629
											new FieldBinding[]{(FieldBinding)binding},
8630
											scope,
8631
											fieldsFound,
8632
											localsFound,
8633
											true,
8634
											((FieldBinding)binding).declaringClass,
8635
											invocationSite,
8636
											invocationScope,
8637
											true,
8638
											false,
8639
											null,
8640
											null,
8641
											null,
8642
											false,
8643
											null,
8644
											-1,
8645
											-1);
8646
							}
8647
						} else if ((binding.kind() & Binding.METHOD) != 0) {
8648
							if(proposeMethod && !insideAnnotationAttribute) {
8649
								MethodBinding methodBinding = (MethodBinding)binding;
8650
								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
8651
										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
8652
8653
									findLocalMethodsFromStaticImports(
8654
											methodBinding.selector,
8655
											methodBinding.declaringClass.methods(),
8656
											scope,
8657
											exactMatch,
8658
											methodsFound,
8659
											methodBinding.declaringClass,
8660
											invocationSite);
8661
								}
8662
							}
8663
						}
8664
					}
8331
					}
8665
				}
8332
				}
8333
			};
8334
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8335
	}
8336
8337
	private void findMethodDeclarations(
8338
		char[] selector,
8339
		ReferenceBinding receiverType,
8340
		Scope scope,
8341
		ObjectVector methodsFound,
8342
		Binding[] missingElements,
8343
		int[] missingElementsStarts,
8344
		int[] missingElementsEnds,
8345
		boolean missingElementsHaveProblems) {
8346
8347
		if (selector == null) {
8348
			return;
8349
		}
8350
8351
		MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
8352
		if (receiverTypeMethods != null){
8353
			for (int i = 0; i < receiverTypeMethods.length; i++) {
8354
				if(!receiverTypeMethods[i].isDefaultAbstract()) {
8355
					methodsFound.add(receiverTypeMethods[i]);
8356
				}
8357
			}
8358
		}
8359
8360
		ReferenceBinding currentType = receiverType;
8361
		
8362
		findInterfacesMethodDeclarations(
8363
			selector,
8364
			receiverType,
8365
			currentType.superInterfaces(),
8366
			scope,
8367
			methodsFound,
8368
			missingElements,
8369
			missingElementsStarts,
8370
			missingElementsEnds,
8371
			missingElementsHaveProblems);
8372
		
8373
		if (receiverType.isInterface()) {
8374
			currentType = scope.getJavaLangObject();
8375
		} else {
8376
			currentType = receiverType.superclass();
8377
		}
8378
		
8379
		boolean hasPotentialDefaultAbstractMethods = true;
8380
		while (currentType != null) {
8381
8382
			MethodBinding[] methods = currentType.availableMethods();
8383
			if (methods != null) {
8384
				findLocalMethodDeclarations(
8385
					selector,
8386
					methods,
8387
					scope,
8388
					methodsFound,
8389
					false,
8390
					receiverType);
8391
			}
8392
8393
			if (hasPotentialDefaultAbstractMethods &&
8394
					(currentType.isAbstract() ||
8395
							currentType.isTypeVariable() ||
8396
							currentType.isIntersectionType() ||
8397
							currentType.isEnum())){
8398
8399
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
8400
8401
				findInterfacesMethodDeclarations(
8402
					selector,
8403
					receiverType,
8404
					superInterfaces,
8405
					scope,
8406
					methodsFound,
8407
					missingElements,
8408
					missingElementsStarts,
8409
					missingElementsEnds,
8410
					missingElementsHaveProblems);
8411
			} else {
8412
				hasPotentialDefaultAbstractMethods = false;
8666
			}
8413
			}
8414
			currentType = currentType.superclass();
8667
		}
8415
		}
8668
	}
8416
	}
8669
	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
8417
	
8670
		final TypeReference type = variable.type;
8418
	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
8671
		if(type != null &&
8419
		TypeBinding erasure =  method.declaringClass.erasure();
8672
				type.resolvedType != null &&
8420
		if(!(erasure instanceof ReferenceBinding)) return null;
8673
				type.resolvedType.problemId() == ProblemReasons.NoError){
8674
8421
8675
			final ArrayList proposedNames = new ArrayList();
8422
		char[][] parameterNames = null;
8676
8423
8677
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8424
		int length = parameterTypeNames.length;
8678
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8679
					public void acceptName(char[] name) {
8680
						int relevance = computeBaseRelevance();
8681
						relevance += computeRelevanceForInterestingProposal();
8682
						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
8683
						relevance += R_NAME_FIRST_PREFIX;
8684
						relevance += R_NAME_FIRST_SUFFIX;
8685
						relevance += R_NAME_LESS_NEW_CHARACTERS;
8686
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
8687
8425
8688
						// accept result
8426
		if (length == 0){
8689
						CompletionEngine.this.noProposal = false;
8427
			return CharOperation.NO_CHAR_CHAR;
8690
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8428
		}
8691
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8429
		// look into the corresponding unit if it is available
8692
							proposal.setSignature(getSignature(type.resolvedType));
8430
		if (erasure instanceof SourceTypeBinding){
8693
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
8431
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
8694
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
8432
8695
							proposal.setName(name);
8433
			if (sourceType.scope != null){
8696
							proposal.setCompletion(name);
8434
				TypeDeclaration parsedType;
8697
							//proposal.setFlags(Flags.AccDefault);
8435
8698
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8436
				if ((parsedType = sourceType.scope.referenceContext) != null){
8699
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8437
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
8700
							proposal.setRelevance(relevance);
8438
8701
							CompletionEngine.this.requestor.accept(proposal);
8439
					if (methodDecl != null){
8702
							if(DEBUG) {
8440
						Argument[] arguments = methodDecl.arguments;
8703
								CompletionEngine.this.printDebug(proposal);
8441
						parameterNames = new char[length][];
8704
							}
8442
8443
						for(int i = 0 ; i < length ; i++){
8444
							parameterNames[i] = arguments[i].name;
8705
						}
8445
						}
8706
						proposedNames.add(name);
8707
					}
8446
					}
8708
				};
8447
				}
8448
			}
8449
		}
8450
		// look into the model
8451
		if(parameterNames == null){
8709
8452
8710
			ReferenceContext referenceContext = scope.referenceContext();
8453
			ReferenceBinding bindingType = (ReferenceBinding)erasure;
8711
			if (referenceContext instanceof AbstractMethodDeclaration) {
8712
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8713
8454
8714
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8455
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
8715
				nameFinder.find(
8456
			Object type = this.typeCache.get(compoundName);
8716
						this.completionToken,
8457
8717
						md,
8458
			ISourceType sourceType = null;
8718
						variable.declarationSourceEnd + 1,
8459
			if(type != null) {
8719
						discouragedNames,
8460
				if(type instanceof ISourceType) {
8720
						nameRequestor);
8461
					sourceType = (ISourceType) type;
8721
			} else if (referenceContext instanceof TypeDeclaration) {
8462
				}
8722
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
8463
			} else {
8723
				FieldDeclaration[] fields = typeDeclaration.fields;
8464
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
8724
				if (fields != null) {
8465
				if(answer != null && answer.isSourceType()) {
8725
					done : for (int i = 0; i < fields.length; i++) {
8466
					sourceType = answer.getSourceTypes()[0];
8726
						if (fields[i] instanceof Initializer) {
8467
					this.typeCache.put(compoundName, sourceType);
8727
							Initializer initializer = (Initializer) fields[i];
8468
				}
8728
							if (initializer.bodyStart <= variable.sourceStart &&
8469
			}
8729
									variable.sourceStart < initializer.bodyEnd) {
8470
8730
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8471
			if(sourceType != null) {
8731
								nameFinder.find(
8472
				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
8732
										this.completionToken,
8473
8733
										initializer,
8474
				String[] parameterTypeSignatures = new String[length];
8734
										typeDeclaration.scope,
8475
				for (int i = 0; i < length; i++) {
8735
										variable.declarationSourceEnd + 1,
8476
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
8736
										discouragedNames,
8477
				}
8737
										nameRequestor);
8478
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
8738
								break done;
8479
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
8739
							}
8480
8481
				if(foundMethods != null) {
8482
					int len = foundMethods.length;
8483
					if(len == 1) {
8484
						try {
8485
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
8486
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
8487
						} catch (JavaModelException e) {
8488
							// method doesn't exist: ignore
8740
						}
8489
						}
8741
					}
8490
					}
8742
				}
8491
				}
8743
			}
8492
			}
8493
		}
8494
		return parameterNames;
8495
	}
8744
8496
8745
			int proposedNamesCount = proposedNames.size();
8497
	private void findMethods(
8746
			if (proposedNamesCount > 0) {
8498
		char[] selector,
8747
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8499
		TypeBinding[] typeArgTypes,
8500
		TypeBinding[] argTypes,
8501
		ReferenceBinding receiverType,
8502
		Scope scope,
8503
		ObjectVector methodsFound,
8504
		boolean onlyStaticMethods,
8505
		boolean exactMatch,
8506
		InvocationSite invocationSite,
8507
		Scope invocationScope,
8508
		boolean implicitCall,
8509
		boolean superCall,
8510
		boolean canBePrefixed,
8511
		Binding[] missingElements,
8512
		int[] missingElementsStarts,
8513
		int[] missingElementsEnds,
8514
		boolean missingElementsHaveProblems,
8515
		char[] castedReceiver,
8516
		int receiverStart,
8517
		int receiverEnd) {
8518
8519
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
8520
		if (selector == null && notInJavadoc) {
8521
			return;
8522
		}
8523
8524
		ReferenceBinding currentType = receiverType;
8525
		if (notInJavadoc) {
8526
			if (receiverType.isInterface()) {
8527
				findInterfacesMethods(
8528
					selector,
8529
					typeArgTypes,
8530
					argTypes,
8531
					receiverType,
8532
					new ReferenceBinding[]{currentType},
8533
					scope,
8534
					methodsFound,
8535
					onlyStaticMethods,
8536
					exactMatch,
8537
					invocationSite,
8538
					invocationScope,
8539
					implicitCall,
8540
					superCall,
8541
					canBePrefixed,
8542
					missingElements,
8543
					missingElementsStarts,
8544
					missingElementsEnds,
8545
					missingElementsHaveProblems,
8546
					castedReceiver,
8547
					receiverStart,
8548
					receiverEnd);
8549
8550
				currentType = scope.getJavaLangObject();
8551
			}
8552
		}
8553
		boolean hasPotentialDefaultAbstractMethods = true;
8554
		while (currentType != null) {
8555
8556
			MethodBinding[] methods = currentType.availableMethods();
8557
			if (methods != null) {
8558
				findLocalMethods(
8559
					selector,
8560
					typeArgTypes,
8561
					argTypes,
8562
					methods,
8563
					scope,
8564
					methodsFound,
8565
					onlyStaticMethods,
8566
					exactMatch,
8567
					receiverType,
8568
					invocationSite,
8569
					invocationScope,
8570
					implicitCall,
8571
					superCall,
8572
					canBePrefixed,
8573
					missingElements,
8574
					missingElementsStarts,
8575
					missingElementsEnds,
8576
					missingElementsHaveProblems,
8577
					castedReceiver,
8578
					receiverStart,
8579
					receiverEnd);
8748
			}
8580
			}
8749
		}
8750
8751
		return null;
8752
	}
8753
8754
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
8755
		final ArrayList proposedNames = new ArrayList();
8756
8757
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8758
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8759
				public void acceptName(char[] name) {
8760
					CompletionEngine.this.acceptUnresolvedName(name);
8761
					proposedNames.add(name);
8762
				}
8763
			};
8764
8581
8765
		ReferenceContext referenceContext = scope.referenceContext();
8582
			if (hasPotentialDefaultAbstractMethods &&
8766
		if (referenceContext instanceof AbstractMethodDeclaration) {
8583
					(currentType.isAbstract() ||
8767
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8584
							currentType.isTypeVariable() ||
8585
							currentType.isIntersectionType() ||
8586
							currentType.isEnum())){
8768
8587
8769
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8588
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
8770
			nameFinder.findAfter(
8589
				if (superInterfaces != null && currentType.isIntersectionType()) {
8771
					this.completionToken,
8590
					for (int i = 0; i < superInterfaces.length; i++) {
8772
					md.scope,
8591
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
8773
					md.scope.classScope(),
8774
					from,
8775
					md.bodyEnd,
8776
					discouragedNames,
8777
					nameRequestor);
8778
		} else if (referenceContext instanceof TypeDeclaration) {
8779
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
8780
			FieldDeclaration[] fields = typeDeclaration.fields;
8781
			if (fields != null) {
8782
				done : for (int i = 0; i < fields.length; i++) {
8783
					if (fields[i] instanceof Initializer) {
8784
						Initializer initializer = (Initializer) fields[i];
8785
						if (initializer.block.sourceStart <= from &&
8786
								from < initializer.bodyEnd) {
8787
							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8788
							nameFinder.findAfter(
8789
										this.completionToken,
8790
										typeDeclaration.scope,
8791
										typeDeclaration.scope,
8792
										from,
8793
										initializer.bodyEnd,
8794
										discouragedNames,
8795
										nameRequestor);
8796
							break done;
8797
						}
8798
					}
8592
					}
8799
				}
8593
				}
8594
8595
				findInterfacesMethods(
8596
					selector,
8597
					typeArgTypes,
8598
					argTypes,
8599
					receiverType,
8600
					superInterfaces,
8601
					scope,
8602
					methodsFound,
8603
					onlyStaticMethods,
8604
					exactMatch,
8605
					invocationSite,
8606
					invocationScope,
8607
					implicitCall,
8608
					superCall,
8609
					canBePrefixed,
8610
					missingElements,
8611
					missingElementsStarts,
8612
					missingElementsEnds,
8613
					missingElementsHaveProblems,
8614
					castedReceiver,
8615
					receiverStart,
8616
					receiverEnd);
8617
			} else {
8618
				hasPotentialDefaultAbstractMethods = false;
8800
			}
8619
			}
8620
			currentType = currentType.superclass();
8801
		}
8621
		}
8622
	}
8802
8623
8803
		int proposedNamesCount = proposedNames.size();
8624
	private void findNestedTypes(
8804
		if (proposedNamesCount > 0) {
8625
		char[] typeName,
8805
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8626
		SourceTypeBinding currentType,
8806
		}
8627
		Scope scope,
8628
		boolean proposeAllMemberTypes,
8629
		ObjectVector typesFound) {
8630
		
8631
		if (typeName == null)
8632
			return;
8807
8633
8808
		return null;
8634
		int typeLength = typeName.length;
8809
	}
8810
8635
8811
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
8636
		SourceTypeBinding nextTypeToIgnore = null;
8812
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
8637
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
8813
		if (foundNames != null && foundNames.length > 1) {
8814
			int discouragedNamesLength = discouragedNames.length;
8815
			int foundNamesLength = foundNames.length;
8816
			int newLength = discouragedNamesLength + foundNamesLength;
8817
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
8818
			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
8819
		}
8820
		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
8821
	}
8822
8638
8823
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
8639
			switch (scope.kind) {
8824
		final ArrayList proposedNames = new ArrayList();
8825
8640
8826
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8641
				case Scope.METHOD_SCOPE :
8827
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8642
				case Scope.BLOCK_SCOPE :
8828
				public void acceptName(char[] name) {
8643
					BlockScope blockScope = (BlockScope) scope;
8829
					CompletionEngine.this.acceptUnresolvedName(name);
8830
					proposedNames.add(name);
8831
				}
8832
			};
8833
8644
8834
		BlockScope upperScope = scope;
8645
					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
8835
		while (upperScope.enclosingMethodScope() != null) {
8836
			upperScope = upperScope.enclosingMethodScope();
8837
		}
8838
8646
8839
		ReferenceContext referenceContext = upperScope.referenceContext();
8647
						if (blockScope.subscopes[i] instanceof ClassScope) {
8840
		if (referenceContext instanceof AbstractMethodDeclaration) {
8648
							SourceTypeBinding localType =
8841
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8649
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
8842
8650
8843
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8651
							if (!localType.isAnonymousType()) {
8844
			nameFinder.findBefore(
8652
								if (isForbidden(localType))
8845
					this.completionToken,
8653
									continue next;
8846
					md.scope,
8847
					md.scope.classScope(),
8848
					md.bodyStart,
8849
					recordTo,
8850
					parseTo,
8851
					discouragedNames,
8852
					nameRequestor);
8853
		} else if (referenceContext instanceof TypeDeclaration) {
8854
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
8855
8654
8655
								if (typeLength > localType.sourceName.length)
8656
									continue next;
8657
								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
8658
										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
8659
									continue next;
8856
8660
8857
			done : {
8661
								for (int j = typesFound.size; --j >= 0;) {
8858
				FieldDeclaration[] fields = typeDeclaration.fields;
8662
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
8859
				if (fields != null) {
8860
					for (int i = 0; i < fields.length; i++) {
8861
						if (fields[i] instanceof Initializer) {
8862
							Initializer initializer = (Initializer) fields[i];
8863
							if (initializer.block.sourceStart <= recordTo &&
8864
									recordTo < initializer.bodyEnd) {
8865
8663
8866
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8664
									if (localType == otherType)
8867
								nameFinder.findBefore(
8665
										continue next;
8868
										this.completionToken,
8666
								}
8869
										typeDeclaration.scope,
8870
										typeDeclaration.scope,
8871
										initializer.block.sourceStart,
8872
										recordTo,
8873
										parseTo,
8874
										discouragedNames,
8875
										nameRequestor);
8876
								break done;
8877
							}
8878
						}
8879
					}
8880
				}
8881
			}
8882
		}
8883
8667
8884
		int proposedNamesCount = proposedNames.size();
8668
								if(this.assistNodeIsClass) {
8885
		if (proposedNamesCount > 0) {
8669
									if(!localType.isClass()) continue next;
8886
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8670
								} else if(this.assistNodeIsInterface) {
8887
		}
8671
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
8672
								} else if (this.assistNodeIsAnnotation) {
8673
									if(!localType.isAnnotationType()) continue next;
8674
								}
8888
8675
8889
		return null;
8676
								int relevance = computeBaseRelevance();
8890
	}
8677
								relevance += computeRelevanceForResolution();
8891
		// Helper method for private void findVariableNames(char[] name, TypeReference type )
8678
								relevance += computeRelevanceForInterestingProposal();
8892
	private void findVariableName(
8679
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
8893
			char[] token,
8680
								relevance += computeRelevanceForExpectingType(localType);
8894
			char[] qualifiedPackageName,
8681
								relevance += computeRelevanceForException(localType.sourceName);
8895
			char[] qualifiedSourceName,
8682
								relevance += computeRelevanceForClass();
8896
			char[] sourceName,
8683
								relevance += computeRelevanceForQualification(false);
8897
			final TypeBinding typeBinding,
8684
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
8898
			char[][] discouragedNames,
8685
								relevance += computeRelevanceForAnnotationTarget(localType);
8899
			final char[][] forbiddenNames,
8686
8900
			int dim,
8687
								this.noProposal = false;
8901
			int kind,
8688
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8902
			int modifiers){
8689
									createTypeProposal(
8903
		findVariableName(
8690
											localType,
8904
				token,
8691
											localType.sourceName,
8905
				qualifiedPackageName,
8692
											IAccessRule.K_ACCESSIBLE,
8906
				qualifiedSourceName,
8693
											localType.sourceName,
8907
				sourceName,
8694
											relevance,
8908
				typeBinding,
8695
											null,
8909
				discouragedNames,
8696
											null,
8910
				forbiddenNames,
8697
											null,
8911
				false,
8698
											false);
8912
				dim,
8699
								}
8913
				kind,
8700
							}
8914
				modifiers);
8701
						}
8915
	}
8702
					}
8916
	private void findVariableName(
8703
					break;
8917
			char[] token,
8918
			char[] qualifiedPackageName,
8919
			char[] qualifiedSourceName,
8920
			char[] sourceName,
8921
			final TypeBinding typeBinding,
8922
			char[][] discouragedNames,
8923
			final char[][] forbiddenNames,
8924
			boolean forCollection,
8925
			int dim,
8926
			int kind,
8927
			int modifiers){
8928
8704
8929
		if(sourceName == null || sourceName.length == 0)
8705
				case Scope.CLASS_SCOPE :
8930
			return;
8706
					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
8707
					findMemberTypes(
8708
							typeName,
8709
							enclosingSourceType,
8710
							scope,
8711
							currentType,
8712
							false,
8713
							false,
8714
							false,
8715
							false,
8716
							proposeAllMemberTypes,
8717
							nextTypeToIgnore,
8718
							typesFound,
8719
							null,
8720
							null,
8721
							null,
8722
							false);
8723
					nextTypeToIgnore = enclosingSourceType;
8724
					if (typeLength == 0)
8725
						return; // do not search outside the class scope if no prefix was provided
8726
					break;
8931
8727
8932
		// compute variable name for non base type
8728
				case Scope.COMPILATION_UNIT_SCOPE :
8933
		final char[] displayName;
8729
					return;
8934
		if (!forCollection) {
8935
			if (dim > 0){
8936
				int l = qualifiedSourceName.length;
8937
				displayName = new char[l+(2*dim)];
8938
				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
8939
				for(int i = 0; i < dim; i++){
8940
					displayName[l+(i*2)] = '[';
8941
					displayName[l+(i*2)+1] = ']';
8942
				}
8943
			} else {
8944
				displayName = qualifiedSourceName;
8945
			}
8730
			}
8946
		} else {
8731
			scope = scope.parent;
8947
			displayName = typeBinding.qualifiedSourceName();
8948
		}
8732
		}
8733
	}
8949
8734
8950
		final char[] t = token;
8735
	private void findPackages(CompletionOnPackageReference packageStatement) {
8951
		final char[] q = qualifiedPackageName;
8952
		INamingRequestor namingRequestor = new INamingRequestor() {
8953
			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
8954
				accept(
8955
						name,
8956
						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
8957
						reusedCharacters);
8958
			}
8959
8960
			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
8961
				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
8962
			}
8963
8736
8964
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
8737
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
8965
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
8738
		if (this.completionToken.length == 0)
8966
			}
8739
			return;
8967
8740
8968
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
8741
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
8969
				accept(name, 0, reusedCharacters);
8742
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
8970
			}
8743
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
8971
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
8744
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
8972
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
8745
	}
8973
				for (int i = 0; i < l; i++) {
8974
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
8975
				}
8976
8746
8977
				if (CharOperation.prefixEquals(t, name, false)) {
8747
	private void findParameterizedType(TypeReference ref, Scope scope) {
8978
					int relevance = computeBaseRelevance();
8748
		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
8979
					relevance += computeRelevanceForInterestingProposal();
8749
		if(refBinding != null) {
8980
					relevance += computeRelevanceForCaseMatching(t, name);
8750
			if (this.options.checkDeprecation &&
8981
					relevance += prefixAndSuffixRelevance;
8751
					refBinding.isViewedAsDeprecated() &&
8982
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
8752
					!scope.isDefinedInSameUnit(refBinding))
8983
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
8753
				return;
8984
8754
8985
					// accept result
8755
			int accessibility = IAccessRule.K_ACCESSIBLE;
8986
					CompletionEngine.this.noProposal = false;
8756
			if(refBinding.hasRestrictedAccess()) {
8987
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8757
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
8988
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8758
				if(accessRestriction != null) {
8989
						proposal.setSignature(getSignature(typeBinding));
8759
					switch (accessRestriction.getProblemId()) {
8990
						proposal.setPackageName(q);
8760
						case IProblem.ForbiddenReference:
8991
						proposal.setTypeName(displayName);
8761
							if (this.options.checkForbiddenReference) {
8992
						proposal.setName(name);
8762
								return;
8993
						proposal.setCompletion(name);
8763
							}
8994
						//proposal.setFlags(Flags.AccDefault);
8764
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
8995
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8765
							break;
8996
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8766
						case IProblem.DiscouragedReference:
8997
						proposal.setRelevance(relevance);
8767
							if (this.options.checkDiscouragedReference) {
8998
						CompletionEngine.this.requestor.accept(proposal);
8768
								return;
8999
						if(DEBUG) {
8769
							}
9000
							CompletionEngine.this.printDebug(proposal);
8770
							accessibility = IAccessRule.K_DISCOURAGED;
9001
						}
8771
							break;
9002
					}
8772
					}
9003
				}
8773
				}
9004
			}
8774
			}
9005
		};
9006
8775
9007
		switch (kind) {
8776
			int relevance = computeBaseRelevance();
9008
			case FIELD :
8777
			relevance += computeRelevanceForResolution();
9009
				InternalNamingConventions.suggestFieldNames(
8778
			relevance += computeRelevanceForInterestingProposal();
9010
					this.javaProject,
8779
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
9011
					qualifiedPackageName,
8780
			relevance += computeRelevanceForExpectingType(refBinding);
9012
					qualifiedSourceName,
8781
			relevance += computeRelevanceForQualification(false);
9013
					dim,
8782
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
9014
					modifiers,
8783
9015
					token,
8784
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9016
					discouragedNames,
8785
				createTypeProposal(
9017
					namingRequestor);
8786
						refBinding,
9018
				break;
8787
						refBinding.qualifiedSourceName(),
9019
			case LOCAL :
8788
						IAccessRule.K_ACCESSIBLE,
9020
				InternalNamingConventions.suggestLocalVariableNames(
8789
						CharOperation.NO_CHAR,
9021
					this.javaProject,
8790
						relevance,
9022
					qualifiedPackageName,
8791
						null,
9023
					qualifiedSourceName,
8792
						null,
9024
					dim,
8793
						null,
9025
					token,
8794
						false);
9026
					discouragedNames,
8795
			}
9027
					namingRequestor);
9028
				break;
9029
			case ARGUMENT :
9030
				InternalNamingConventions.suggestArgumentNames(
9031
					this.javaProject,
9032
					qualifiedPackageName,
9033
					qualifiedSourceName,
9034
					dim,
9035
					token,
9036
					discouragedNames,
9037
					namingRequestor);
9038
				break;
9039
		}
8796
		}
9040
	}
8797
	}
9041
	
9042
	private void findVariableNameForCollection(
9043
			char[] token,
9044
			char[] qualifiedPackageName,
9045
			char[] qualifiedSourceName,
9046
			char[] sourceName,
9047
			final TypeBinding typeBinding,
9048
			char[][] discouragedNames,
9049
			final char[][] forbiddenNames,
9050
			int kind,
9051
			int modifiers){
9052
8798
9053
		findVariableName(
8799
	private void findSubMemberTypes(
9054
				token,
8800
		char[] typeName,
9055
				qualifiedPackageName,
8801
		ReferenceBinding receiverType,
9056
				qualifiedSourceName,
8802
		Scope scope,
9057
				sourceName,
8803
		SourceTypeBinding typeInvocation,
9058
				typeBinding,
8804
		boolean staticOnly,
9059
				discouragedNames,
8805
		boolean staticFieldsAndMethodOnly,
9060
				forbiddenNames,
8806
		boolean fromStaticImport,
9061
				false,
8807
		ObjectVector typesFound) {
9062
				1,
8808
9063
				kind,
8809
		ReferenceBinding currentType = receiverType;
9064
				modifiers);
8810
		if (typeName == null || typeName.length == 0)
8811
			return;
8812
8813
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
8814
8815
		findMemberTypes(
8816
				typeName,
8817
				currentType.memberTypes(),
8818
				typesFound,
8819
				receiverType,
8820
				typeInvocation,
8821
				staticOnly,
8822
				staticFieldsAndMethodOnly,
8823
				fromStaticImport,
8824
				true,
8825
				scope,
8826
				null,
8827
				null,
8828
				null,
8829
				false);
8830
8831
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
8832
		next : for (int i = 0; i < memberTypes.length; i++) {
8833
			if (this.options.checkVisibility) {
8834
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
8835
					continue next;
8836
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
8837
					continue next;
8838
				}
8839
			}
8840
			findSubMemberTypes(
8841
				typeName,
8842
				memberTypes[i],
8843
				scope,
8844
				typeInvocation,
8845
				staticOnly,
8846
				staticFieldsAndMethodOnly,
8847
				fromStaticImport,
8848
				typesFound);
8849
		}
9065
	}
8850
	}
9066
8851
9067
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
8852
	private void findTrueOrFalseKeywords(char[][] choices) {
9068
		if(type != null &&
8853
		if(choices == null || choices.length == 0) return;
9069
			type.resolvedType != null) {
9070
			TypeBinding tb = type.resolvedType;
9071
8854
9072
			if (tb.problemId() == ProblemReasons.NoError &&
8855
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
9073
					tb != Scope.getBaseType(VOID)) {
8856
9074
				findVariableName(
8857
		for (int i = 0; i < choices.length; i++) {
9075
					name,
8858
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
9076
					tb.leafComponentType().qualifiedPackageName(),
8859
					CharOperation.equals(choices[i], Keywords.FALSE)
9077
					tb.leafComponentType().qualifiedSourceName(),
8860
			){
9078
					tb.leafComponentType().sourceName(),
8861
				int relevance = computeBaseRelevance();
9079
					tb,
8862
				relevance += computeRelevanceForResolution();
9080
					discouragedNames,
8863
				relevance += computeRelevanceForInterestingProposal();
9081
					forbiddenNames,
8864
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
9082
					type.dimensions(),
8865
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
9083
					kind,
8866
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
9084
					modifiers);
8867
				relevance += computeRelevanceForQualification(false);
9085
				
8868
				relevance += R_TRUE_OR_FALSE;
9086
				if (tb.isParameterizedType() &&
8869
9087
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
8870
				this.noProposal = false;
9088
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
8871
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
9089
					TypeBinding[] arguments = ptb.arguments;
8872
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
9090
					if (arguments != null && arguments.length == 1) {
8873
					proposal.setName(choices[i]);
9091
						TypeBinding argument = arguments[0];
8874
					proposal.setCompletion(choices[i]);
9092
						findVariableNameForCollection(
8875
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9093
							name,
8876
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9094
							argument.leafComponentType().qualifiedPackageName(),
8877
					proposal.setRelevance(relevance);
9095
							argument.leafComponentType().qualifiedSourceName(),
8878
					this.requestor.accept(proposal);
9096
							argument.leafComponentType().sourceName(),
8879
					if(DEBUG) {
9097
							tb,
8880
						this.printDebug(proposal);
9098
							discouragedNames,
9099
							forbiddenNames,
9100
							kind,
9101
							modifiers);
9102
					}
8881
					}
9103
				}
8882
				}
9104
			}
8883
			}
9105
		}
8884
		}
9106
9107
	}
8885
	}
9108
8886
9109
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
8887
	private void findTypeParameters(char[] token, Scope scope) {
9110
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
8888
		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
9111
9112
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
9113
8889
9114
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
8890
		TypeParameter[] typeParameters = null;
8891
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
8892
			typeParameters = null;
8893
			switch (scope.kind) {
8894
				case Scope.METHOD_SCOPE :
8895
					MethodScope methodScope = (MethodScope) scope;
8896
					if(methodScope.referenceContext instanceof MethodDeclaration) {
8897
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
8898
						typeParameters = methodDeclaration.typeParameters;
8899
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
8900
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
8901
						typeParameters = methodDeclaration.typeParameters;
8902
					}
8903
					break;
8904
				case Scope.CLASS_SCOPE :
8905
					ClassScope classScope = (ClassScope) scope;
8906
					typeParameters = classScope.referenceContext.typeParameters;
8907
					break;
8908
				case Scope.COMPILATION_UNIT_SCOPE :
8909
					return;
8910
			}
8911
			if(typeParameters != null) {
8912
				for (int i = 0; i < typeParameters.length; i++) {
8913
					int typeLength = token.length;
8914
					TypeParameter typeParameter = typeParameters[i];
9115
8915
9116
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
8916
					if(typeParameter.binding == null) continue;
9117
8917
9118
		int count = 0;
8918
					if (typeLength > typeParameter.name.length) continue;
9119
		next : for (int i = 0; i < favoriteReferences.length; i++) {
9120
			String favoriteReference = favoriteReferences[i];
9121
8919
9122
			int length;
8920
					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
9123
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
8921
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
9124
8922
9125
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
8923
					int relevance = computeBaseRelevance();
8924
					relevance += computeRelevanceForResolution();
8925
					relevance += computeRelevanceForInterestingProposal();
8926
					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
8927
					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
8928
					relevance += computeRelevanceForQualification(false);
8929
					relevance += computeRelevanceForException(typeParameter.name);
8930
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
9126
8931
9127
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
8932
					this.noProposal = false;
9128
			if (onDemand) {
8933
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9129
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
8934
						createTypeParameterProposal(typeParameter, relevance);
8935
					}
8936
				}
9130
			}
8937
			}
8938
			scope = scope.parent;
8939
		}
8940
	}
9131
8941
9132
			// remove duplicate and conflicting
8942
	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
9133
			for (int j = 0; j < count; j++) {
9134
				ImportReference f = resolvedImports[j].reference;
9135
8943
9136
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
8944
		if (token == null)
8945
			return;
9137
8946
9138
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
8947
		// do not propose type if completion token is empty
9139
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
8948
		boolean skip = false;
9140
						continue next;
8949
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
9141
				}
8950
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
8951
				return;
9142
			}
8952
			}
8953
			skip = true;
8954
		}
9143
8955
9144
			boolean isStatic = true;
8956
		boolean proposeType =
9145
8957
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9146
			ImportReference importReference =
8958
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9147
				new ImportReference(
9148
						compoundName,
9149
						new long[compoundName.length],
9150
						onDemand,
9151
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
9152
8959
9153
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
8960
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
9154
8961
9155
			if (!importBinding.isValidBinding()) {
8962
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
9156
				continue next;
8963
			
8964
			checkTimeout();
8965
			
8966
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
8967
			if(!this.assistNodeIsInterface &&
8968
					!this.assistNodeIsConstructor &&
8969
					!this.assistNodeIsAnnotation &&
8970
					this.assistNodeInJavadoc == 0) {
8971
				
8972
				checkTimeout();
8973
				
8974
				// don't propose type parameters if the completion is a constructor ('new |')
8975
				findTypeParameters(token, scope);
9157
			}
8976
			}
8977
		}
9158
8978
9159
			if (importBinding instanceof PackageBinding) {
8979
		boolean isEmptyPrefix = token.length == 0;
9160
				continue next;
8980
8981
		if (!skip && proposeType && this.unitScope != null) {
8982
			
8983
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
8984
			if(outerInvocationType != null) {
8985
				ReferenceBinding temp = outerInvocationType.enclosingType();
8986
				while(temp != null) {
8987
					outerInvocationType = temp;
8988
					temp = temp.enclosingType();
8989
				}
9161
			}
8990
			}
9162
8991
9163
			resolvedImports[count++] =
8992
			int typeLength = token.length;
9164
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
8993
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9165
		}
9166
8994
9167
		if (resolvedImports.length > count)
8995
			next : for (int i = 0, length = types.length; i < length; i++) {
9168
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
8996
				
8997
				checkTimeout();
8998
				
8999
				SourceTypeBinding sourceType = types[i];
9169
9000
9170
		return this.favoriteReferenceBindings = resolvedImports;
9001
				if(isForbidden(sourceType)) continue next;
9171
	}
9172
9002
9173
	public AssistParser getParser() {
9003
				if(proposeAllMemberTypes &&
9004
					sourceType != outerInvocationType) {
9005
					findSubMemberTypes(
9006
							token,
9007
							sourceType,
9008
							scope,
9009
							scope.enclosingSourceType(),
9010
							false,
9011
							false,
9012
							false,
9013
							typesFound);
9014
				}
9174
9015
9175
		return this.parser;
9016
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
9176
	}
9017
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
9177
9018
9178
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
9019
				if (typeLength > sourceType.sourceName.length) continue next;
9179
		char[] result = null;
9180
		StringBuffer sig = new StringBuffer(10);
9181
		if (!referenceBinding.isMemberType()) {
9182
			char[] typeSig = referenceBinding.genericTypeSignature();
9183
			sig.append(typeSig, 0, typeSig.length);
9184
		} else if (!this.insideQualifiedReference) {
9185
			if (referenceBinding.isStatic()) {
9186
				char[] typeSig = referenceBinding.signature();
9187
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9188
9020
9189
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9021
				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
9190
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9022
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
9191
				    sig.append(Signature.C_GENERIC_START);
9023
9192
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9024
				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
9193
				        sig.append(typeVariables[i].genericTypeSignature());
9025
					continue next;
9194
				    }
9195
				    sig.append(Signature.C_GENERIC_END);
9196
				}
9026
				}
9197
				sig.append(Signature.C_SEMICOLON);
9198
			} else {
9199
				char[] typeSig = referenceBinding.genericTypeSignature();
9200
				sig.append(typeSig, 0, typeSig.length);
9201
			}
9202
		} else {
9203
			ReferenceBinding enclosingType = referenceBinding.enclosingType();
9204
			if (enclosingType.isParameterizedType()) {
9205
				char[] typeSig = referenceBinding.genericTypeSignature();
9206
				sig.append(typeSig, 0, typeSig.length-1);
9207
9027
9208
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9028
				for (int j = typesFound.size; --j >= 0;) {
9209
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9029
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
9210
				    sig.append(Signature.C_GENERIC_START);
9030
9211
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9031
					if (sourceType == otherType) continue next;
9212
				        sig.append(typeVariables[i].genericTypeSignature());
9213
				    }
9214
				    sig.append(Signature.C_GENERIC_END);
9215
				}
9032
				}
9216
			} else {
9217
				char[] typeSig = referenceBinding.signature();
9218
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9219
9033
9220
				if (referenceBinding.isStatic()) {
9034
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9221
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9035
9222
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9036
				if(this.assistNodeIsClass) {
9223
					    sig.append(Signature.C_GENERIC_START);
9037
					if(!sourceType.isClass()) continue next;
9224
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
9038
				} else if(this.assistNodeIsInterface) {
9225
					        sig.append(typeVariables[i].genericTypeSignature());
9039
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
9226
					    }
9040
				} else if (this.assistNodeIsAnnotation) {
9227
					    sig.append(Signature.C_GENERIC_END);
9041
					if(!sourceType.isAnnotationType()) continue next;
9042
				} else if (isEmptyPrefix && this.assistNodeIsException) {
9043
					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
9044
						continue next;
9228
					}
9045
					}
9229
				}
9046
				}
9047
9048
				int relevance = computeBaseRelevance();
9049
				relevance += computeRelevanceForResolution();
9050
				relevance += computeRelevanceForInterestingProposal();
9051
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
9052
				relevance += computeRelevanceForExpectingType(sourceType);
9053
				relevance += computeRelevanceForQualification(false);
9054
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
9055
9056
				if (sourceType.isAnnotationType()) {
9057
					relevance += computeRelevanceForAnnotation();
9058
					relevance += computeRelevanceForAnnotationTarget(sourceType);
9059
				} else if (sourceType.isInterface()) {
9060
					relevance += computeRelevanceForInterface();
9061
				} else if(sourceType.isClass()){
9062
					relevance += computeRelevanceForClass();
9063
					relevance += computeRelevanceForException(sourceType.sourceName);
9064
				}
9065
				this.noProposal = false;
9066
				if(proposeType) {
9067
					char[] typeName = sourceType.sourceName();
9068
					createTypeProposal(
9069
							sourceType,
9070
							typeName,
9071
							IAccessRule.K_ACCESSIBLE,
9072
							typeName,
9073
							relevance,
9074
							null,
9075
							null,
9076
							null,
9077
							false);
9078
				}
9230
			}
9079
			}
9231
			sig.append(Signature.C_SEMICOLON);
9232
		}
9080
		}
9233
		int sigLength = sig.length();
9234
		result = new char[sigLength];
9235
		sig.getChars(0, sigLength, result, 0);
9236
		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
9237
		return result;
9238
	}
9239
9081
9240
	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
9082
		if(!skip && proposeType) {
9241
		char[] result = null;
9083
			
9242
		StringBuffer sig = new StringBuffer(10);
9084
			checkTimeout();
9085
			
9086
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
9087
		}
9243
9088
9244
		sig.append(typeBinding.signature());
9089
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
9090
			if(proposeType && this.expectedTypesPtr > -1) {
9091
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
9092
					
9093
					checkTimeout();
9094
					
9095
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
9096
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
9245
9097
9246
		int sigLength = sig.length();
9098
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
9247
		result = new char[sigLength];
9099
							// don't propose type variable if the completion is a constructor ('new |')
9248
		sig.getChars(0, sigLength, result, 0);
9100
							continue next;
9249
		result = CharOperation.replaceOnCopy(result, '/', '.');
9101
						}
9250
		return result;
9102
						if (this.options.checkDeprecation &&
9251
	}
9103
								refBinding.isViewedAsDeprecated() &&
9104
								!scope.isDefinedInSameUnit(refBinding))
9105
							continue next;
9252
9106
9253
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
9107
						int accessibility = IAccessRule.K_ACCESSIBLE;
9254
		if (this.targetedElement == TagBits.AnnotationForPackage) {
9108
						if(refBinding.hasRestrictedAccess()) {
9255
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9109
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
9256
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
9110
							if(accessRestriction != null) {
9257
				return false;
9111
								switch (accessRestriction.getProblemId()) {
9258
			}
9112
									case IProblem.ForbiddenReference:
9259
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
9113
										if (this.options.checkForbiddenReference) {
9260
			if (scope.parent != null &&
9114
											continue next;
9261
					scope.parent.parent != null &&
9115
										}
9262
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
9116
										accessibility = IAccessRule.K_NON_ACCESSIBLE;
9263
					scope.parent.parent instanceof CompilationUnitScope) {
9117
										break;
9264
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9118
									case IProblem.DiscouragedReference:
9265
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
9119
										if (this.options.checkDiscouragedReference) {
9266
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
9120
											continue next;
9267
						return false;
9121
										}
9268
					}
9122
										accessibility = IAccessRule.K_DISCOURAGED;
9269
				} else {
9123
										break;
9270
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
9124
								}
9271
						return false;
9125
							}
9272
					}
9126
						}
9273
				}
9274
			}
9275
		}
9276
		return true;
9277
	}
9278
9127
9279
	protected void reset() {
9128
						for (int j = 0; j < typesFound.size(); j++) {
9129
							ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
9130
							if (typeFound == refBinding) {
9131
								continue next;
9132
							}
9133
						}
9280
9134
9281
		super.reset(false);
9135
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
9282
		this.knownPkgs = new HashtableOfObject(10);
9283
		this.knownTypes = new HashtableOfObject(10);
9284
	}
9285
9136
9286
	private void setSourceAndTokenRange(int start, int end) {
9137
						// top level types of the current unit are already proposed.
9287
		this.setSourceAndTokenRange(start, end, true);
9138
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
9288
	}
9139
							char[] packageName = refBinding.qualifiedPackageName();
9140
							char[] typeName = refBinding.sourceName();
9141
							char[] completionName = typeName;
9289
9142
9290
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
9143
							boolean isQualified = false;
9291
		this.setSourceRange(start, end, emptyTokenAdjstment);
9144
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
9292
		this.setTokenRange(start, end, emptyTokenAdjstment);
9145
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
9293
	}
9146
									if (packageName == null || packageName.length == 0)
9147
										if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
9148
											continue next; // ignore types from the default package from outside it
9149
									completionName = CharOperation.concat(packageName, typeName, '.');
9150
									isQualified = true;
9151
								}
9152
							}
9294
9153
9295
	private void setSourceRange(int start, int end) {
9154
							if(this.assistNodeIsClass) {
9296
		this.setSourceRange(start, end, true);
9155
								if(!refBinding.isClass()) continue next;
9297
	}
9156
							} else if(this.assistNodeIsInterface) {
9157
								if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
9158
							} else if (this.assistNodeIsAnnotation) {
9159
								if(!refBinding.isAnnotationType()) continue next;
9160
							}
9298
9161
9299
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
9162
							int relevance = computeBaseRelevance();
9300
		this.startPosition = start;
9163
							relevance += computeRelevanceForResolution();
9301
		if(emptyTokenAdjstment) {
9164
							relevance += computeRelevanceForInterestingProposal();
9302
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
9165
							relevance += computeRelevanceForCaseMatching(token, typeName);
9303
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
9166
							relevance += computeRelevanceForExpectingType(refBinding);
9304
		} else {
9167
							relevance += computeRelevanceForQualification(isQualified);
9305
			this.endPosition = end + 1;
9168
							relevance += computeRelevanceForRestrictions(accessibility);
9306
		}
9307
	}
9308
9169
9309
	private void setTokenRange(int start, int end) {
9170
							if(refBinding.isClass()) {
9310
		this.setTokenRange(start, end, true);
9171
								relevance += computeRelevanceForClass();
9311
	}
9172
								relevance += computeRelevanceForException(typeName);
9173
							} else if(refBinding.isEnum()) {
9174
								relevance += computeRelevanceForEnum();
9175
							} else if(refBinding.isInterface()) {
9176
								relevance += computeRelevanceForInterface();
9177
							}
9312
9178
9313
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
9179
							this.noProposal = false;
9314
		this.tokenStart = start;
9180
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9315
		if(emptyTokenAdjstment) {
9181
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9316
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
9182
								proposal.setDeclarationSignature(packageName);
9317
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
9183
								proposal.setSignature(getSignature(refBinding));
9184
								proposal.setPackageName(packageName);
9185
								proposal.setTypeName(typeName);
9186
								proposal.setCompletion(completionName);
9187
								proposal.setFlags(refBinding.modifiers);
9188
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9189
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9190
								proposal.setRelevance(relevance);
9191
								proposal.setAccessibility(accessibility);
9192
								this.requestor.accept(proposal);
9193
								if(DEBUG) {
9194
									this.printDebug(proposal);
9195
								}
9196
							}
9197
						}
9198
					}
9199
				}
9200
			}
9318
		} else {
9201
		} else {
9319
			this.tokenEnd = end + 1;
9202
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
9203
				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
9204
					if (proposeBaseTypes) {
9205
						if (proposeVoidType) {
9206
							findKeywords(token, BASE_TYPE_NAMES, false, false);
9207
						} else {
9208
							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
9209
						}
9210
					}
9211
				}
9212
			}
9213
			if(proposeType) {
9214
				int l = typesFound.size();
9215
				for (int i = 0; i < l; i++) {
9216
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
9217
					char[] fullyQualifiedTypeName =
9218
						CharOperation.concat(
9219
								typeFound.qualifiedPackageName(),
9220
								typeFound.qualifiedSourceName(),
9221
								'.');
9222
					this.knownTypes.put(fullyQualifiedTypeName, this);
9223
				}
9224
				int searchFor = IJavaSearchConstants.TYPE;
9225
				if(this.assistNodeIsClass) {
9226
					searchFor = IJavaSearchConstants.CLASS;
9227
				} else if(this.assistNodeIsInterface) {
9228
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9229
				} else if(this.assistNodeIsEnum) {
9230
					searchFor = IJavaSearchConstants.ENUM;
9231
				} else if(this.assistNodeIsAnnotation) {
9232
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9233
				}
9234
				
9235
				checkTimeout();
9236
				
9237
				this.nameEnvironment.findTypes(
9238
						token,
9239
						proposeAllMemberTypes,
9240
						this.options.camelCaseMatch,
9241
						searchFor,
9242
						this);
9243
				acceptTypes(scope);
9244
			}
9245
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9246
				
9247
				checkTimeout();
9248
				
9249
				this.nameEnvironment.findPackages(token, this);
9250
			}
9320
		}
9251
		}
9321
	}
9252
	}
9322
9253
9323
	private char[][] computeAlreadyDefinedName(
9254
	private void findTypesAndSubpackages(
9324
			BlockScope scope,
9255
		char[] token,
9325
			InvocationSite invocationSite) {
9256
		PackageBinding packageBinding,
9326
		ArrayList result = new ArrayList();
9257
		Scope scope) {
9327
9328
		boolean staticsOnly = false;
9329
9330
		Scope currentScope = scope;
9331
9332
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9333
9334
			switch (currentScope.kind) {
9335
9336
				case Scope.METHOD_SCOPE :
9337
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9338
					MethodScope methodScope = (MethodScope) currentScope;
9339
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9340
9258
9341
				//$FALL-THROUGH$
9259
		boolean proposeType =
9342
				case Scope.BLOCK_SCOPE :
9260
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9343
					BlockScope blockScope = (BlockScope) currentScope;
9261
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9344
9262
9345
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9263
		char[] qualifiedName =
9346
						LocalVariableBinding local = blockScope.locals[i];
9264
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
9347
9265
9348
						if (local == null)
9266
		if (token == null || token.length == 0) {
9349
							break next;
9267
			int length = qualifiedName.length;
9268
			System.arraycopy(
9269
				qualifiedName,
9270
				0,
9271
				qualifiedName = new char[length + 1],
9272
				0,
9273
				length);
9274
			qualifiedName[length] = '.';
9275
		}
9350
9276
9351
						if (local.isSecret())
9277
		this.qualifiedCompletionToken = qualifiedName;
9352
							continue next;
9353
9278
9354
						result.add(local.name);
9279
		if (proposeType && this.unitScope != null) {
9355
					}
9280
			int typeLength = qualifiedName.length;
9356
					break;
9281
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9357
9282
9358
				case Scope.CLASS_SCOPE :
9283
			for (int i = 0, length = types.length; i < length; i++) {
9359
					ClassScope classScope = (ClassScope) currentScope;
9284
				
9360
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
9285
				checkTimeout();
9361
					computeAlreadyDefinedName(
9286
				
9362
							enclosingType,
9287
				SourceTypeBinding sourceType = types[i];
9363
							classScope,
9364
							staticsOnly,
9365
							invocationSite,
9366
							result);
9367
					staticsOnly |= enclosingType.isStatic();
9368
					break;
9369
9288
9370
				case Scope.COMPILATION_UNIT_SCOPE :
9289
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
9371
					break done1;
9372
			}
9373
			currentScope = currentScope.parent;
9374
		}
9375
9290
9376
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
9291
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
9292
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
9293
				if (typeLength > qualifiedSourceTypeName.length) continue;
9294
				if (!(packageBinding == sourceType.getPackage())) continue;
9377
9295
9378
		return (char[][])result.toArray(new char[result.size()][]);
9296
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
9379
	}
9297
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
9380
9298
9381
	private void computeAlreadyDefinedName(
9299
				if (this.options.checkDeprecation &&
9382
			SourceTypeBinding receiverType,
9300
						sourceType.isViewedAsDeprecated() &&
9383
			ClassScope scope,
9301
						!scope.isDefinedInSameUnit(sourceType))
9384
			boolean onlyStaticFields,
9302
					continue;
9385
			InvocationSite invocationSite,
9386
			ArrayList result) {
9387
9303
9388
		ReferenceBinding currentType = receiverType;
9304
				int accessibility = IAccessRule.K_ACCESSIBLE;
9389
		ReferenceBinding[] interfacesToVisit = null;
9305
				if(sourceType.hasRestrictedAccess()) {
9390
		int nextPosition = 0;
9306
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
9391
		do {
9307
					if(accessRestriction != null) {
9392
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
9308
						switch (accessRestriction.getProblemId()) {
9393
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9309
							case IProblem.ForbiddenReference:
9394
				if (interfacesToVisit == null) {
9310
								if (this.options.checkForbiddenReference) {
9395
					interfacesToVisit = itsInterfaces;
9311
									continue;
9396
					nextPosition = interfacesToVisit.length;
9312
								}
9397
				} else {
9313
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
9398
					int itsLength = itsInterfaces.length;
9314
								break;
9399
					if (nextPosition + itsLength >= interfacesToVisit.length)
9315
							case IProblem.DiscouragedReference:
9400
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9316
								if (this.options.checkDiscouragedReference) {
9401
					nextInterface : for (int a = 0; a < itsLength; a++) {
9317
									continue;
9402
						ReferenceBinding next = itsInterfaces[a];
9318
								}
9403
						for (int b = 0; b < nextPosition; b++)
9319
								accessibility = IAccessRule.K_DISCOURAGED;
9404
							if (next == interfacesToVisit[b]) continue nextInterface;
9320
								break;
9405
						interfacesToVisit[nextPosition++] = next;
9321
						}
9406
					}
9322
					}
9407
				}
9323
				}
9408
			}
9409
9324
9410
			FieldBinding[] fields = currentType.availableFields();
9325
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9411
			if(fields != null && fields.length > 0) {
9412
				computeAlreadyDefinedName(
9413
					fields,
9414
					scope,
9415
					onlyStaticFields,
9416
					receiverType,
9417
					invocationSite,
9418
					result);
9419
			}
9420
			currentType = currentType.superclass();
9421
		} while ( currentType != null);
9422
9326
9423
		if (interfacesToVisit != null) {
9327
				int relevance = computeBaseRelevance();
9424
			for (int i = 0; i < nextPosition; i++) {
9328
				relevance += computeRelevanceForResolution();
9425
				ReferenceBinding anInterface = interfacesToVisit[i];
9329
				relevance += computeRelevanceForInterestingProposal();
9426
				FieldBinding[] fields = anInterface.availableFields();
9330
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
9427
				if(fields !=  null) {
9331
				relevance += computeRelevanceForExpectingType(sourceType);
9428
					computeAlreadyDefinedName(
9332
				relevance += computeRelevanceForQualification(false);
9429
						fields,
9333
				relevance += computeRelevanceForRestrictions(accessibility);
9430
						scope,
9431
						onlyStaticFields,
9432
						receiverType,
9433
						invocationSite,
9434
						result);
9435
				}
9436
9334
9437
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
9335
				if (sourceType.isAnnotationType()) {
9438
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9336
					relevance += computeRelevanceForAnnotation();
9439
					int itsLength = itsInterfaces.length;
9337
				} else if (sourceType.isInterface()) {
9440
					if (nextPosition + itsLength >= interfacesToVisit.length)
9338
					relevance += computeRelevanceForInterface();
9441
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9339
				} else if (sourceType.isClass()) {
9442
					nextInterface : for (int a = 0; a < itsLength; a++) {
9340
					relevance += computeRelevanceForClass();
9443
						ReferenceBinding next = itsInterfaces[a];
9341
					relevance += computeRelevanceForException(sourceType.sourceName);
9444
						for (int b = 0; b < nextPosition; b++)
9342
				}
9445
							if (next == interfacesToVisit[b]) continue nextInterface;
9343
				this.noProposal = false;
9446
						interfacesToVisit[nextPosition++] = next;
9344
				if(proposeType) {
9447
					}
9345
					char[] typeName = sourceType.sourceName();
9346
					createTypeProposal(
9347
							sourceType,
9348
							typeName,
9349
							IAccessRule.K_ACCESSIBLE,
9350
							typeName,
9351
							relevance,
9352
							null,
9353
							null,
9354
							null,
9355
							false);
9448
				}
9356
				}
9449
			}
9357
			}
9450
		}
9358
		}
9451
	}
9452
9453
	private void computeAlreadyDefinedName(
9454
			FieldBinding[] fields,
9455
			Scope scope,
9456
			boolean onlyStaticFields,
9457
			ReferenceBinding receiverType,
9458
			InvocationSite invocationSite,
9459
			ArrayList result) {
9460
9461
		next : for (int f = fields.length; --f >= 0;) {
9462
			FieldBinding field = fields[f];
9463
9464
			if (field.isSynthetic()) continue next;
9465
9466
			if (onlyStaticFields && !field.isStatic()) continue next;
9467
9359
9468
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
9360
		if(proposeType) {
9469
9361
			int searchFor = IJavaSearchConstants.TYPE;
9470
			result.add(field.name);
9362
			if(this.assistNodeIsClass) {
9363
				searchFor = IJavaSearchConstants.CLASS;
9364
			} else if(this.assistNodeIsInterface) {
9365
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9366
			} else if(this.assistNodeIsEnum) {
9367
				searchFor = IJavaSearchConstants.ENUM;
9368
			} else if(this.assistNodeIsAnnotation) {
9369
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9370
			}
9371
			
9372
			checkTimeout();
9373
			
9374
			this.nameEnvironment.findTypes(
9375
					qualifiedName,
9376
					false,
9377
					this.options.camelCaseMatch,
9378
					searchFor,
9379
					this);
9380
			acceptTypes(scope);
9471
		}
9381
		}
9472
	}
9382
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9473
9383
			this.nameEnvironment.findPackages(qualifiedName, this);
9474
	int computeBaseRelevance(){
9475
		return R_DEFAULT;
9476
	}
9477
	int computeRelevanceForResolution(){
9478
		return computeRelevanceForResolution(true);
9479
	}
9480
	int computeRelevanceForResolution(boolean isResolved){
9481
		if (isResolved) {
9482
			return R_RESOLVED;
9483
		}
9384
		}
9484
		return 0;
9485
	}
9385
	}
9486
	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
9487
9386
9488
		// default filter
9387
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
9489
		this.expectedTypesFilter = SUBTYPE;
9388
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
9490
		this.hasJavaLangObjectAsExpectedType = false;
9389
		for (int i = 0; i < importBindings.length; i++) {
9390
			ImportBinding importBinding = importBindings[i];
9391
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
9392
				Binding binding = importBinding.resolvedImport;
9393
				if(binding != null && binding.isValidBinding()) {
9394
					if(importBinding.onDemand) {
9395
						if((binding.kind() & Binding.TYPE) != 0) {
9396
							this.findMemberTypes(
9397
									token,
9398
									(ReferenceBinding) binding,
9399
									scope,
9400
									scope.enclosingSourceType(),
9401
									true,
9402
									false,
9403
									true,
9404
									true,
9405
									proposeAllMemberTypes,
9406
									null,
9407
									typesFound,
9408
									null,
9409
									null,
9410
									null,
9411
									false);
9412
						}
9413
					} else {
9414
						if ((binding.kind() & Binding.TYPE) != 0) {
9415
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
9416
							int typeLength = token.length;
9491
9417
9492
		// find types from parent
9418
							if (!typeBinding.isStatic()) continue;
9493
		if(parent instanceof AbstractVariableDeclaration) {
9494
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
9495
			TypeBinding binding = variable.type.resolvedType;
9496
			if(binding != null) {
9497
				if(!(variable.initialization instanceof ArrayInitializer)) {
9498
					addExpectedType(binding, scope);
9499
				}
9500
			}
9501
		} else if(parent instanceof Assignment) {
9502
			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
9503
			if(binding != null) {
9504
				addExpectedType(binding, scope);
9505
			}
9506
		} else if(parent instanceof ReturnStatement) {
9507
			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
9508
				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
9509
				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
9510
				if(binding != null) {
9511
					addExpectedType(binding, scope);
9512
				}
9513
			}
9514
		} else if(parent instanceof CastExpression) {
9515
			Expression e = ((CastExpression)parent).type;
9516
			TypeBinding binding = e.resolvedType;
9517
			if(binding != null){
9518
				addExpectedType(binding, scope);
9519
				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
9520
			}
9521
		} else if(parent instanceof MessageSend) {
9522
			MessageSend messageSend = (MessageSend) parent;
9523
9419
9524
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
9420
							if (typeLength > typeBinding.sourceName.length)	continue;
9525
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
9526
				boolean isStatic = messageSend.receiver.isTypeReference();
9527
9421
9528
				while(binding != null) {
9422
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
9529
					computeExpectedTypesForMessageSend(
9423
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
9530
						binding,
9531
						messageSend.selector,
9532
						messageSend.arguments,
9533
						(ReferenceBinding)messageSend.actualReceiverType,
9534
						scope,
9535
						messageSend,
9536
						isStatic);
9537
					computeExpectedTypesForMessageSendForInterface(
9538
						binding,
9539
						messageSend.selector,
9540
						messageSend.arguments,
9541
						(ReferenceBinding)messageSend.actualReceiverType,
9542
						scope,
9543
						messageSend,
9544
						isStatic);
9545
					binding = binding.superclass();
9546
				}
9547
			}
9548
		} else if(parent instanceof AllocationExpression) {
9549
			AllocationExpression allocationExpression = (AllocationExpression) parent;
9550
9424
9551
			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
9425
							if (typesFound.contains(typeBinding))  continue;
9552
9426
9553
			if(binding != null) {
9427
							typesFound.add(typeBinding);
9554
				computeExpectedTypesForAllocationExpression(
9428
9555
					binding,
9429
							if(this.assistNodeIsClass) {
9556
					allocationExpression.arguments,
9430
								if(!typeBinding.isClass()) continue;
9557
					scope,
9431
							} else if(this.assistNodeIsInterface) {
9558
					allocationExpression);
9432
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
9559
			}
9433
							} else if (this.assistNodeIsAnnotation) {
9560
		} else if(parent instanceof OperatorExpression) {
9434
								if(!typeBinding.isAnnotationType()) continue;
9561
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
9435
							}
9562
			if(parent instanceof ConditionalExpression) {
9436
9563
				// for future use
9437
							int relevance = computeBaseRelevance();
9564
			} else if(parent instanceof InstanceOfExpression) {
9438
							relevance += computeRelevanceForResolution();
9565
				InstanceOfExpression e = (InstanceOfExpression) parent;
9439
							relevance += computeRelevanceForInterestingProposal();
9566
				TypeBinding binding = e.expression.resolvedType;
9440
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
9567
				if(binding != null){
9441
							relevance += computeRelevanceForExpectingType(typeBinding);
9568
					addExpectedType(binding, scope);
9442
							relevance += computeRelevanceForQualification(false);
9569
					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
9443
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
9570
				}
9444
9571
			} else if(parent instanceof BinaryExpression) {
9445
							if (typeBinding.isClass()) {
9572
				BinaryExpression binaryExpression = (BinaryExpression) parent;
9446
								relevance += computeRelevanceForClass();
9573
				switch(operator) {
9447
								relevance += computeRelevanceForException(typeBinding.sourceName);
9574
					case OperatorIds.EQUAL_EQUAL :
9448
							} else if(typeBinding.isEnum()) {
9575
						// expected type is not relevant in this case
9449
								relevance += computeRelevanceForEnum();
9576
						TypeBinding binding = binaryExpression.left.resolvedType;
9450
							} else if(typeBinding.isInterface()) {
9577
						if (binding != null) {
9451
								relevance += computeRelevanceForInterface();
9578
							addExpectedType(binding, scope);
9579
							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
9580
						}
9581
						break;
9582
					case OperatorIds.PLUS :
9583
						addExpectedType(TypeBinding.SHORT, scope);
9584
						addExpectedType(TypeBinding.INT, scope);
9585
						addExpectedType(TypeBinding.LONG, scope);
9586
						addExpectedType(TypeBinding.FLOAT, scope);
9587
						addExpectedType(TypeBinding.DOUBLE, scope);
9588
						addExpectedType(TypeBinding.CHAR, scope);
9589
						addExpectedType(TypeBinding.BYTE, scope);
9590
						addExpectedType(scope.getJavaLangString(), scope);
9591
						break;
9592
					case OperatorIds.AND_AND :
9593
					case OperatorIds.OR_OR :
9594
					case OperatorIds.XOR :
9595
						addExpectedType(TypeBinding.BOOLEAN, scope);
9596
						break;
9597
					default :
9598
						addExpectedType(TypeBinding.SHORT, scope);
9599
						addExpectedType(TypeBinding.INT, scope);
9600
						addExpectedType(TypeBinding.LONG, scope);
9601
						addExpectedType(TypeBinding.FLOAT, scope);
9602
						addExpectedType(TypeBinding.DOUBLE, scope);
9603
						addExpectedType(TypeBinding.CHAR, scope);
9604
						addExpectedType(TypeBinding.BYTE, scope);
9605
						break;
9606
				}
9607
				if(operator == OperatorIds.LESS) {
9608
					if(binaryExpression.left instanceof SingleNameReference){
9609
						SingleNameReference name = (SingleNameReference) binaryExpression.left;
9610
						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
9611
						if(b instanceof ReferenceBinding) {
9612
							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
9613
							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
9614
								addExpectedType(typeVariableBindings[0].firstBound, scope);
9615
							}
9452
							}
9616
9453
9454
							this.noProposal = false;
9455
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9456
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9457
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
9458
								proposal.setSignature(getSignature(typeBinding));
9459
								proposal.setPackageName(typeBinding.qualifiedPackageName());
9460
								proposal.setTypeName(typeBinding.qualifiedSourceName());
9461
								proposal.setCompletion(typeBinding.sourceName());
9462
								proposal.setFlags(typeBinding.modifiers);
9463
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9464
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9465
								proposal.setRelevance(relevance);
9466
								this.requestor.accept(proposal);
9467
								if(DEBUG) {
9468
									this.printDebug(proposal);
9469
								}
9470
							}
9617
						}
9471
						}
9618
					}
9472
					}
9619
				}
9473
				}
9620
			} else if(parent instanceof UnaryExpression) {
9474
			}
9621
				switch(operator) {
9475
		}
9622
					case OperatorIds.NOT :
9476
	}
9623
						addExpectedType(TypeBinding.BOOLEAN, scope);
9477
9624
						break;
9478
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
9625
					case OperatorIds.TWIDDLE :
9479
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
9626
						addExpectedType(TypeBinding.SHORT, scope);
9480
		if (foundNames != null && foundNames.length > 1) {
9627
						addExpectedType(TypeBinding.INT, scope);
9481
			int discouragedNamesLength = discouragedNames.length;
9628
						addExpectedType(TypeBinding.LONG, scope);
9482
			int foundNamesLength = foundNames.length;
9629
						addExpectedType(TypeBinding.CHAR, scope);
9483
			int newLength = discouragedNamesLength + foundNamesLength;
9630
						addExpectedType(TypeBinding.BYTE, scope);
9484
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
9631
						break;
9485
			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
9632
					case OperatorIds.PLUS :
9486
		}
9633
					case OperatorIds.MINUS :
9487
		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
9634
					case OperatorIds.PLUS_PLUS :
9488
	}
9635
					case OperatorIds.MINUS_MINUS :
9489
9636
						addExpectedType(TypeBinding.SHORT, scope);
9490
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
9637
						addExpectedType(TypeBinding.INT, scope);
9491
		final ArrayList proposedNames = new ArrayList();
9638
						addExpectedType(TypeBinding.LONG, scope);
9492
9639
						addExpectedType(TypeBinding.FLOAT, scope);
9493
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9640
						addExpectedType(TypeBinding.DOUBLE, scope);
9494
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9641
						addExpectedType(TypeBinding.CHAR, scope);
9495
				public void acceptName(char[] name) {
9642
						addExpectedType(TypeBinding.BYTE, scope);
9496
					CompletionEngine.this.acceptUnresolvedName(name);
9643
						break;
9497
					proposedNames.add(name);
9644
				}
9498
				}
9645
			}
9499
			};
9646
		} else if(parent instanceof ArrayReference) {
9647
			addExpectedType(TypeBinding.SHORT, scope);
9648
			addExpectedType(TypeBinding.INT, scope);
9649
			addExpectedType(TypeBinding.LONG, scope);
9650
		} else if(parent instanceof ParameterizedSingleTypeReference) {
9651
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
9652
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
9653
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
9654
			if(typeVariables != null && typeVariables.length >= length) {
9655
				int index = length - 1;
9656
				while(index > -1 && ref.typeArguments[index] != node) index--;
9657
9500
9658
				TypeBinding bound = typeVariables[index].firstBound;
9501
		ReferenceContext referenceContext = scope.referenceContext();
9659
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9502
		if (referenceContext instanceof AbstractMethodDeclaration) {
9660
			}
9503
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9661
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
9504
9662
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
9505
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9663
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
9506
			nameFinder.findAfter(
9664
			TypeReference[][] arguments = ref.typeArguments;
9507
					this.completionToken,
9665
			if(typeVariables != null) {
9508
					md.scope,
9666
				int iLength = arguments == null ? 0 : arguments.length;
9509
					md.scope.classScope(),
9667
				done: for (int i = 0; i < iLength; i++) {
9510
					from,
9668
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
9511
					md.bodyEnd,
9669
					for (int j = 0; j < jLength; j++) {
9512
					discouragedNames,
9670
						if(arguments[i][j] == node && typeVariables.length > j) {
9513
					nameRequestor);
9671
							TypeBinding bound = typeVariables[j].firstBound;
9514
		} else if (referenceContext instanceof TypeDeclaration) {
9672
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9515
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9516
			FieldDeclaration[] fields = typeDeclaration.fields;
9517
			if (fields != null) {
9518
				done : for (int i = 0; i < fields.length; i++) {
9519
					if (fields[i] instanceof Initializer) {
9520
						Initializer initializer = (Initializer) fields[i];
9521
						if (initializer.block.sourceStart <= from &&
9522
								from < initializer.bodyEnd) {
9523
							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9524
							nameFinder.findAfter(
9525
										this.completionToken,
9526
										typeDeclaration.scope,
9527
										typeDeclaration.scope,
9528
										from,
9529
										initializer.bodyEnd,
9530
										discouragedNames,
9531
										nameRequestor);
9673
							break done;
9532
							break done;
9674
						}
9533
						}
9675
					}
9534
					}
9676
				}
9535
				}
9677
			}
9536
			}
9678
		} else if(parent instanceof MemberValuePair) {
9537
		}
9679
			MemberValuePair memberValuePair = (MemberValuePair) parent;
9538
9680
			if(memberValuePair.binding != null) {
9539
		int proposedNamesCount = proposedNames.size();
9681
				addExpectedType(memberValuePair.binding.returnType, scope);
9540
		if (proposedNamesCount > 0) {
9682
			}
9541
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9683
		} else if (parent instanceof NormalAnnotation) {
9542
		}
9684
			NormalAnnotation annotation = (NormalAnnotation) parent;
9543
9685
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
9544
		return null;
9686
			if(memberValuePairs == null || memberValuePairs.length == 0) {
9545
	}
9687
				if(annotation.resolvedType instanceof ReferenceBinding) {
9546
9688
					MethodBinding[] methodBindings =
9547
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
9689
						((ReferenceBinding)annotation.resolvedType).availableMethods();
9548
		final ArrayList proposedNames = new ArrayList();
9690
					if (methodBindings != null &&
9549
9691
							methodBindings.length > 0 &&
9550
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9692
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
9551
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9693
						boolean canBeSingleMemberAnnotation = true;
9552
				public void acceptName(char[] name) {
9694
						done : for (int i = 1; i < methodBindings.length; i++) {
9553
					CompletionEngine.this.acceptUnresolvedName(name);
9695
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
9554
					proposedNames.add(name);
9696
								canBeSingleMemberAnnotation = false;
9555
				}
9556
			};
9557
9558
		BlockScope upperScope = scope;
9559
		while (upperScope.enclosingMethodScope() != null) {
9560
			upperScope = upperScope.enclosingMethodScope();
9561
		}
9562
9563
		ReferenceContext referenceContext = upperScope.referenceContext();
9564
		if (referenceContext instanceof AbstractMethodDeclaration) {
9565
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9566
9567
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9568
			nameFinder.findBefore(
9569
					this.completionToken,
9570
					md.scope,
9571
					md.scope.classScope(),
9572
					md.bodyStart,
9573
					recordTo,
9574
					parseTo,
9575
					discouragedNames,
9576
					nameRequestor);
9577
		} else if (referenceContext instanceof TypeDeclaration) {
9578
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9579
9580
9581
			done : {
9582
				FieldDeclaration[] fields = typeDeclaration.fields;
9583
				if (fields != null) {
9584
					for (int i = 0; i < fields.length; i++) {
9585
						if (fields[i] instanceof Initializer) {
9586
							Initializer initializer = (Initializer) fields[i];
9587
							if (initializer.block.sourceStart <= recordTo &&
9588
									recordTo < initializer.bodyEnd) {
9589
9590
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9591
								nameFinder.findBefore(
9592
										this.completionToken,
9593
										typeDeclaration.scope,
9594
										typeDeclaration.scope,
9595
										initializer.block.sourceStart,
9596
										recordTo,
9597
										parseTo,
9598
										discouragedNames,
9599
										nameRequestor);
9697
								break done;
9600
								break done;
9698
							}
9601
							}
9699
						}
9602
						}
9700
						if (canBeSingleMemberAnnotation) {
9701
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
9702
							addExpectedType(methodBindings[0].returnType, scope);
9703
						}
9704
					}
9603
					}
9705
				}
9604
				}
9706
			}
9605
			}
9707
		} else if (parent instanceof TryStatement) {
9606
		}
9708
			boolean isException = false;
9607
9709
			if (node instanceof CompletionOnSingleTypeReference) {
9608
		int proposedNamesCount = proposedNames.size();
9710
				isException = ((CompletionOnSingleTypeReference)node).isException();
9609
		if (proposedNamesCount > 0) {
9711
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
9610
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9712
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
9611
		}
9713
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
9612
9714
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
9613
		return null;
9715
			}
9614
	}
9716
			if (isException) {
9615
9717
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
9616
	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
9718
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
9617
		final TypeReference type = variable.type;
9719
				if (bindings != null && bindings.length > 0) {
9618
		if(type != null &&
9720
					for (int i = 0; i < bindings.length; i++) {
9619
				type.resolvedType != null &&
9721
						addExpectedType(bindings[i], scope);
9620
				type.resolvedType.problemId() == ProblemReasons.NoError){
9621
9622
			final ArrayList proposedNames = new ArrayList();
9623
9624
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9625
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9626
					public void acceptName(char[] name) {
9627
						int relevance = computeBaseRelevance();
9628
						relevance += computeRelevanceForInterestingProposal();
9629
						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
9630
						relevance += R_NAME_FIRST_PREFIX;
9631
						relevance += R_NAME_FIRST_SUFFIX;
9632
						relevance += R_NAME_LESS_NEW_CHARACTERS;
9633
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9634
9635
						// accept result
9636
						CompletionEngine.this.noProposal = false;
9637
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9638
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9639
							proposal.setSignature(getSignature(type.resolvedType));
9640
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
9641
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
9642
							proposal.setName(name);
9643
							proposal.setCompletion(name);
9644
							//proposal.setFlags(Flags.AccDefault);
9645
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9646
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9647
							proposal.setRelevance(relevance);
9648
							CompletionEngine.this.requestor.accept(proposal);
9649
							if(DEBUG) {
9650
								CompletionEngine.this.printDebug(proposal);
9651
							}
9652
						}
9653
						proposedNames.add(name);
9722
					}
9654
					}
9723
					this.expectedTypesFilter = SUPERTYPE;
9655
				};
9724
				}
9725
			}
9726
		} else if (parent instanceof SwitchStatement) {
9727
			SwitchStatement switchStatement = (SwitchStatement) parent;
9728
			if (switchStatement.expression != null &&
9729
					switchStatement.expression.resolvedType != null) {
9730
				addExpectedType(switchStatement.expression.resolvedType, scope);
9731
			}
9732
9656
9733
		// Expected types for javadoc
9657
			ReferenceContext referenceContext = scope.referenceContext();
9734
		} else if (parent instanceof Javadoc) {
9658
			if (referenceContext instanceof AbstractMethodDeclaration) {
9735
			if (scope.kind == Scope.METHOD_SCOPE) {
9659
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9736
				MethodScope methodScope = (MethodScope) scope;
9660
9737
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
9661
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9738
				if (methodDecl != null && methodDecl.binding != null) {
9662
				nameFinder.find(
9739
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
9663
						this.completionToken,
9740
					if (exceptions != null) {
9664
						md,
9741
						for (int i = 0; i < exceptions.length; i++) {
9665
						variable.declarationSourceEnd + 1,
9742
							addExpectedType(exceptions[i], scope);
9666
						discouragedNames,
9667
						nameRequestor);
9668
			} else if (referenceContext instanceof TypeDeclaration) {
9669
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9670
				FieldDeclaration[] fields = typeDeclaration.fields;
9671
				if (fields != null) {
9672
					done : for (int i = 0; i < fields.length; i++) {
9673
						if (fields[i] instanceof Initializer) {
9674
							Initializer initializer = (Initializer) fields[i];
9675
							if (initializer.bodyStart <= variable.sourceStart &&
9676
									variable.sourceStart < initializer.bodyEnd) {
9677
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9678
								nameFinder.find(
9679
										this.completionToken,
9680
										initializer,
9681
										typeDeclaration.scope,
9682
										variable.declarationSourceEnd + 1,
9683
										discouragedNames,
9684
										nameRequestor);
9685
								break done;
9686
							}
9743
						}
9687
						}
9744
					}
9688
					}
9745
				}
9689
				}
9746
			}
9690
			}
9747
		}
9748
9691
9749
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
9692
			int proposedNamesCount = proposedNames.size();
9750
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
9693
			if (proposedNamesCount > 0) {
9694
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9695
			}
9751
		}
9696
		}
9697
9698
		return null;
9752
	}
9699
	}
9753
9700
9754
	private void computeExpectedTypesForAllocationExpression(
9701
	private void findVariableName(
9755
		ReferenceBinding binding,
9702
			char[] token,
9756
		Expression[] arguments,
9703
			char[] qualifiedPackageName,
9757
		Scope scope,
9704
			char[] qualifiedSourceName,
9758
		InvocationSite invocationSite) {
9705
			char[] sourceName,
9706
			final TypeBinding typeBinding,
9707
			char[][] discouragedNames,
9708
			final char[][] forbiddenNames,
9709
			boolean forCollection,
9710
			int dim,
9711
			int kind,
9712
			int modifiers){
9759
9713
9760
		MethodBinding[] methods = binding.availableMethods();
9714
		if(sourceName == null || sourceName.length == 0)
9761
		nextMethod : for (int i = 0; i < methods.length; i++) {
9715
			return;
9762
			MethodBinding method = methods[i];
9763
9716
9764
			if (!method.isConstructor()) continue nextMethod;
9717
		// compute variable name for non base type
9718
		final char[] displayName;
9719
		if (!forCollection) {
9720
			if (dim > 0){
9721
				int l = qualifiedSourceName.length;
9722
				displayName = new char[l+(2*dim)];
9723
				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
9724
				for(int i = 0; i < dim; i++){
9725
					displayName[l+(i*2)] = '[';
9726
					displayName[l+(i*2)+1] = ']';
9727
				}
9728
			} else {
9729
				displayName = qualifiedSourceName;
9730
			}
9731
		} else {
9732
			displayName = typeBinding.qualifiedSourceName();
9733
		}
9765
9734
9766
			if (method.isSynthetic()) continue nextMethod;
9735
		final char[] t = token;
9736
		final char[] q = qualifiedPackageName;
9737
		INamingRequestor namingRequestor = new INamingRequestor() {
9738
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
9739
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
9740
				for (int i = 0; i < l; i++) {
9741
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
9742
				}
9767
9743
9768
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
9744
				if (CharOperation.prefixEquals(t, name, false)) {
9745
					int relevance = computeBaseRelevance();
9746
					relevance += computeRelevanceForInterestingProposal();
9747
					relevance += computeRelevanceForCaseMatching(t, name);
9748
					relevance += prefixAndSuffixRelevance;
9749
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
9750
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9769
9751
9770
			TypeBinding[] parameters = method.parameters;
9752
					// accept result
9771
			if(parameters.length < arguments.length)
9753
					CompletionEngine.this.noProposal = false;
9772
				continue nextMethod;
9754
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9755
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9756
						proposal.setSignature(getSignature(typeBinding));
9757
						proposal.setPackageName(q);
9758
						proposal.setTypeName(displayName);
9759
						proposal.setName(name);
9760
						proposal.setCompletion(name);
9761
						//proposal.setFlags(Flags.AccDefault);
9762
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9763
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9764
						proposal.setRelevance(relevance);
9765
						CompletionEngine.this.requestor.accept(proposal);
9766
						if(DEBUG) {
9767
							CompletionEngine.this.printDebug(proposal);
9768
						}
9769
					}
9770
				}
9771
			}
9773
9772
9774
			int length = arguments.length - 1;
9773
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
9774
				accept(name, 0, reusedCharacters);
9775
			}
9775
9776
9776
			for (int j = 0; j < length; j++) {
9777
			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
9777
				Expression argument = arguments[j];
9778
				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
9778
				TypeBinding argType = argument.resolvedType;
9779
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
9780
					continue nextMethod;
9781
			}
9779
			}
9782
9780
9783
			TypeBinding expectedType = method.parameters[arguments.length - 1];
9781
			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
9784
			if(expectedType != null) {
9782
				accept(
9785
				addExpectedType(expectedType, scope);
9783
						name,
9784
						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
9785
						reusedCharacters);
9786
			}
9787
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
9788
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
9786
			}
9789
			}
9790
		};
9791
9792
		switch (kind) {
9793
			case FIELD :
9794
				InternalNamingConventions.suggestFieldNames(
9795
					this.javaProject,
9796
					qualifiedPackageName,
9797
					qualifiedSourceName,
9798
					dim,
9799
					modifiers,
9800
					token,
9801
					discouragedNames,
9802
					namingRequestor);
9803
				break;
9804
			case LOCAL :
9805
				InternalNamingConventions.suggestLocalVariableNames(
9806
					this.javaProject,
9807
					qualifiedPackageName,
9808
					qualifiedSourceName,
9809
					dim,
9810
					token,
9811
					discouragedNames,
9812
					namingRequestor);
9813
				break;
9814
			case ARGUMENT :
9815
				InternalNamingConventions.suggestArgumentNames(
9816
					this.javaProject,
9817
					qualifiedPackageName,
9818
					qualifiedSourceName,
9819
					dim,
9820
					token,
9821
					discouragedNames,
9822
					namingRequestor);
9823
				break;
9787
		}
9824
		}
9788
	}
9825
	}
9789
9826
9790
	private void computeExpectedTypesForMessageSendForInterface(
9827
	// Helper method for private void findVariableNames(char[] name, TypeReference type )
9791
		ReferenceBinding binding,
9828
	private void findVariableName(
9792
		char[] selector,
9829
			char[] token,
9793
		Expression[] arguments,
9830
			char[] qualifiedPackageName,
9794
		ReferenceBinding receiverType,
9831
			char[] qualifiedSourceName,
9795
		Scope scope,
9832
			char[] sourceName,
9796
		InvocationSite invocationSite,
9833
			final TypeBinding typeBinding,
9797
		boolean isStatic) {
9834
			char[][] discouragedNames,
9798
9835
			final char[][] forbiddenNames,
9799
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
9836
			int dim,
9800
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9837
			int kind,
9801
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
9838
			int modifiers){
9802
			int nextPosition = interfacesToVisit.length;
9839
		findVariableName(
9840
				token,
9841
				qualifiedPackageName,
9842
				qualifiedSourceName,
9843
				sourceName,
9844
				typeBinding,
9845
				discouragedNames,
9846
				forbiddenNames,
9847
				false,
9848
				dim,
9849
				kind,
9850
				modifiers);
9851
	}
9852
	private void findVariableNameForCollection(
9853
			char[] token,
9854
			char[] qualifiedPackageName,
9855
			char[] qualifiedSourceName,
9856
			char[] sourceName,
9857
			final TypeBinding typeBinding,
9858
			char[][] discouragedNames,
9859
			final char[][] forbiddenNames,
9860
			int kind,
9861
			int modifiers){
9803
9862
9804
			for (int i = 0; i < nextPosition; i++) {
9863
		findVariableName(
9805
				ReferenceBinding currentType = interfacesToVisit[i];
9864
				token,
9806
				computeExpectedTypesForMessageSend(
9865
				qualifiedPackageName,
9807
					currentType,
9866
				qualifiedSourceName,
9808
					selector,
9867
				sourceName,
9809
					arguments,
9868
				typeBinding,
9810
					receiverType,
9869
				discouragedNames,
9811
					scope,
9870
				forbiddenNames,
9812
					invocationSite,
9871
				false,
9813
					isStatic);
9872
				1,
9873
				kind,
9874
				modifiers);
9875
	}
9876
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
9877
		if(type != null &&
9878
			type.resolvedType != null) {
9879
			TypeBinding tb = type.resolvedType;
9814
9880
9815
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
9881
			if (tb.problemId() == ProblemReasons.NoError &&
9816
					int itsLength = itsInterfaces.length;
9882
					tb != Scope.getBaseType(VOID)) {
9817
					if (nextPosition + itsLength >= interfacesToVisit.length)
9883
				findVariableName(
9818
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9884
					name,
9819
					nextInterface : for (int a = 0; a < itsLength; a++) {
9885
					tb.leafComponentType().qualifiedPackageName(),
9820
						ReferenceBinding next = itsInterfaces[a];
9886
					tb.leafComponentType().qualifiedSourceName(),
9821
						for (int b = 0; b < nextPosition; b++)
9887
					tb.leafComponentType().sourceName(),
9822
							if (next == interfacesToVisit[b]) continue nextInterface;
9888
					tb,
9823
						interfacesToVisit[nextPosition++] = next;
9889
					discouragedNames,
9890
					forbiddenNames,
9891
					type.dimensions(),
9892
					kind,
9893
					modifiers);
9894
				
9895
				if (tb.isParameterizedType() &&
9896
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
9897
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
9898
					TypeBinding[] arguments = ptb.arguments;
9899
					if (arguments != null && arguments.length == 1) {
9900
						TypeBinding argument = arguments[0];
9901
						findVariableNameForCollection(
9902
							name,
9903
							argument.leafComponentType().qualifiedPackageName(),
9904
							argument.leafComponentType().qualifiedSourceName(),
9905
							argument.leafComponentType().sourceName(),
9906
							tb,
9907
							discouragedNames,
9908
							forbiddenNames,
9909
							kind,
9910
							modifiers);
9824
					}
9911
					}
9825
				}
9912
				}
9826
			}
9913
			}
9827
		}
9914
		}
9828
	}
9829
9915
9830
	private void computeExpectedTypesForMessageSend(
9916
	}
9831
		ReferenceBinding binding,
9917
	private void findVariablesAndMethods(
9832
		char[] selector,
9918
		char[] token,
9833
		Expression[] arguments,
9834
		ReferenceBinding receiverType,
9835
		Scope scope,
9919
		Scope scope,
9836
		InvocationSite invocationSite,
9920
		InvocationSite invocationSite,
9837
		boolean isStatic) {
9921
		Scope invocationScope,
9922
		boolean insideTypeAnnotation,
9923
		boolean insideAnnotationAttribute) {
9838
9924
9839
		MethodBinding[] methods = binding.availableMethods();
9925
		if (token == null)
9840
		nextMethod : for (int i = 0; i < methods.length; i++) {
9926
			return;
9841
			MethodBinding method = methods[i];
9842
9927
9843
			if (method.isSynthetic()) continue nextMethod;
9928
		// Should local variables hide fields from the receiver type or any of its enclosing types?
9929
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
9844
9930
9845
			if (method.isDefaultAbstract())	continue nextMethod;
9931
		boolean staticsOnly = false;
9932
		// need to know if we're in a static context (or inside a constructor)
9933
		int tokenLength = token.length;
9846
9934
9847
			if (method.isConstructor()) continue nextMethod;
9935
		ObjectVector localsFound = new ObjectVector();
9936
		ObjectVector fieldsFound = new ObjectVector();
9937
		ObjectVector methodsFound = new ObjectVector();
9848
9938
9849
			if (isStatic && !method.isStatic()) continue nextMethod;
9939
		Scope currentScope = scope;
9850
9940
9851
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
9941
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9942
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9852
9943
9853
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
9944
				switch (currentScope.kind) {
9854
9945
9855
			TypeBinding[] parameters = method.parameters;
9946
					case Scope.METHOD_SCOPE :
9856
			if(parameters.length < arguments.length)
9947
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9857
				continue nextMethod;
9948
						MethodScope methodScope = (MethodScope) currentScope;
9949
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9858
9950
9859
			int length = arguments.length - 1;
9951
					//$FALL-THROUGH$
9952
					case Scope.BLOCK_SCOPE :
9953
						BlockScope blockScope = (BlockScope) currentScope;
9860
9954
9861
			for (int j = 0; j < length; j++) {
9955
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9862
				Expression argument = arguments[j];
9956
							LocalVariableBinding local = blockScope.locals[i];
9863
				TypeBinding argType = argument.resolvedType;
9864
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
9865
					continue nextMethod;
9866
			}
9867
9957
9868
			TypeBinding expectedType = method.parameters[arguments.length - 1];
9958
							if (local == null)
9869
			if(expectedType != null) {
9959
								break next;
9870
				addExpectedType(expectedType, scope);
9960
9961
							if (tokenLength > local.name.length)
9962
								continue next;
9963
9964
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
9965
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
9966
								continue next;
9967
9968
							if (local.isSecret())
9969
								continue next;
9970
9971
							for (int f = 0; f < localsFound.size; f++) {
9972
								LocalVariableBinding otherLocal =
9973
									(LocalVariableBinding) localsFound.elementAt(f);
9974
								if (CharOperation.equals(otherLocal.name, local.name, true))
9975
									continue next;
9976
							}
9977
							localsFound.add(local);
9978
9979
							int relevance = computeBaseRelevance();
9980
							relevance += computeRelevanceForResolution();
9981
							relevance += computeRelevanceForInterestingProposal(local);
9982
							relevance += computeRelevanceForCaseMatching(token, local.name);
9983
							relevance += computeRelevanceForExpectingType(local.type);
9984
							relevance += computeRelevanceForEnumConstant(local.type);
9985
							relevance += computeRelevanceForQualification(false);
9986
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
9987
							this.noProposal = false;
9988
							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9989
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
9990
								proposal.setSignature(
9991
									local.type == null
9992
									? createTypeSignature(
9993
											CharOperation.NO_CHAR,
9994
											local.declaration.type.toString().toCharArray())
9995
									: getSignature(local.type));
9996
								if(local.type == null) {
9997
									//proposal.setPackageName(null);
9998
									proposal.setTypeName(local.declaration.type.toString().toCharArray());
9999
								} else {
10000
									proposal.setPackageName(local.type.qualifiedPackageName());
10001
									proposal.setTypeName(local.type.qualifiedSourceName());
10002
								}
10003
								proposal.setName(local.name);
10004
								proposal.setCompletion(local.name);
10005
								proposal.setFlags(local.modifiers);
10006
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10007
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10008
								proposal.setRelevance(relevance);
10009
								this.requestor.accept(proposal);
10010
								if(DEBUG) {
10011
									this.printDebug(proposal);
10012
								}
10013
							}
10014
						}
10015
						break;
10016
10017
					case Scope.COMPILATION_UNIT_SCOPE :
10018
						break done1;
10019
				}
10020
				currentScope = currentScope.parent;
9871
			}
10021
			}
9872
		}
10022
		}
9873
	}
10023
		
9874
	private void addExpectedType(TypeBinding type, Scope scope){
10024
		checkTimeout();
9875
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
9876
10025
9877
		// do not add twice the same type
10026
		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
9878
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
10027
		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
9879
			if (this.expectedTypes[i] == type) return;
9880
		}
9881
10028
9882
		int length = this.expectedTypes.length;
10029
		staticsOnly = false;
9883
		if (++this.expectedTypesPtr >= length)
10030
		currentScope = scope;
9884
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
9885
		this.expectedTypes[this.expectedTypesPtr] = type;
9886
10031
9887
		if(type == scope.getJavaLangObject()) {
10032
		if(proposeField || proposeMethod) {
9888
			this.hasJavaLangObjectAsExpectedType = true;
10033
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9889
		}
9890
	}
9891
	private void addForbiddenBindings(Binding binding){
9892
		if (binding == null) return;
9893
10034
9894
		int length = this.forbbidenBindings.length;
10035
				switch (currentScope.kind) {
9895
		if (++this.forbbidenBindingsPtr >= length)
10036
					case Scope.METHOD_SCOPE :
9896
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
10037
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9897
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
10038
						MethodScope methodScope = (MethodScope) currentScope;
10039
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
10040
						break;
10041
					case Scope.CLASS_SCOPE :
10042
						ClassScope classScope = (ClassScope) currentScope;
10043
						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
10044
						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
10045
											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
10046
											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
10047
											break done;
10048
										} else { */
10049
						if(!insideTypeAnnotation) {
10050
							if(proposeField) {
10051
								findFields(
10052
									token,
10053
									enclosingType,
10054
									classScope,
10055
									fieldsFound,
10056
									localsFound,
10057
									staticsOnly,
10058
									invocationSite,
10059
									invocationScope,
10060
									true,
10061
									true,
10062
									null,
10063
									null,
10064
									null,
10065
									false,
10066
									null,
10067
									-1,
10068
									-1);
10069
							}
10070
							if(proposeMethod && !insideAnnotationAttribute) {
10071
								findMethods(
10072
									token,
10073
									null,
10074
									null,
10075
									enclosingType,
10076
									classScope,
10077
									methodsFound,
10078
									staticsOnly,
10079
									false,
10080
									invocationSite,
10081
									invocationScope,
10082
									true,
10083
									false,
10084
									true,
10085
									null,
10086
									null,
10087
									null,
10088
									false,
10089
									null,
10090
									-1,
10091
									-1);
10092
							}
10093
						}
10094
						staticsOnly |= enclosingType.isStatic();
10095
						insideTypeAnnotation = false;
10096
						//				}
10097
						break;
10098
10099
					case Scope.COMPILATION_UNIT_SCOPE :
10100
						break done2;
10101
				}
10102
				currentScope = currentScope.parent;
10103
			}
10104
			
10105
			checkTimeout();
10106
			
10107
			findFieldsAndMethodsFromStaticImports(
10108
					token,
10109
					scope,
10110
					invocationSite,
10111
					invocationScope,
10112
					false,
10113
					insideAnnotationAttribute,
10114
					localsFound,
10115
					fieldsFound,
10116
					methodsFound,
10117
					proposeField,
10118
					proposeMethod);
10119
10120
			if (this.assistNodeInJavadoc == 0) {
10121
				
10122
				checkTimeout();
10123
				
10124
				// search in favorites import
10125
				findFieldsAndMethodsFromFavorites(
10126
						token,
10127
						scope,
10128
						invocationSite,
10129
						invocationScope,
10130
						localsFound,
10131
						fieldsFound,
10132
						methodsFound);
10133
			}
10134
			
10135
			checkTimeout();
10136
			
10137
			findEnumConstantsFromExpectedTypes(
10138
					token,
10139
					invocationScope,
10140
					fieldsFound);
10141
		}
9898
	}
10142
	}
9899
	private void addUninterestingBindings(Binding binding){
9900
		if (binding == null) return;
9901
10143
9902
		int length = this.uninterestingBindings.length;
10144
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
9903
		if (++this.uninterestingBindingsPtr >= length)
10145
		char[] result = null;
9904
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
10146
		StringBuffer sig = new StringBuffer(10);
9905
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
10147
		if (!referenceBinding.isMemberType()) {
9906
	}
10148
			char[] typeSig = referenceBinding.genericTypeSignature();
10149
			sig.append(typeSig, 0, typeSig.length);
10150
		} else if (!this.insideQualifiedReference) {
10151
			if (referenceBinding.isStatic()) {
10152
				char[] typeSig = referenceBinding.signature();
10153
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9907
10154
9908
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
10155
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9909
		this.forbbidenBindingsFilter = NONE;
10156
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9910
		if(scope instanceof ClassScope) {
10157
				    sig.append(Signature.C_GENERIC_START);
9911
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
10158
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9912
			if(typeDeclaration.superclass == astNode) {
10159
				        sig.append(typeVariables[i].genericTypeSignature());
9913
				addForbiddenBindings(typeDeclaration.binding);
10160
				    }
9914
				return scope.parent;
10161
				    sig.append(Signature.C_GENERIC_END);
9915
			}
9916
			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
9917
			int length = superInterfaces == null ? 0 : superInterfaces.length;
9918
			for (int i = 0; i < length; i++) {
9919
				if(superInterfaces[i] == astNode) {
9920
					addForbiddenBindings(typeDeclaration.binding);
9921
					return scope.parent;
9922
				}
10162
				}
10163
				sig.append(Signature.C_SEMICOLON);
10164
			} else {
10165
				char[] typeSig = referenceBinding.genericTypeSignature();
10166
				sig.append(typeSig, 0, typeSig.length);
9923
			}
10167
			}
9924
		} else {
10168
		} else {
9925
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
10169
			ReferenceBinding enclosingType = referenceBinding.enclosingType();
9926
				boolean isException = false;
10170
			if (enclosingType.isParameterizedType()) {
9927
				if (astNode instanceof CompletionOnSingleTypeReference) {
10171
				char[] typeSig = referenceBinding.genericTypeSignature();
9928
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
10172
				sig.append(typeSig, 0, typeSig.length-1);
9929
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
10173
9930
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
10174
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9931
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
10175
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9932
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
10176
				    sig.append(Signature.C_GENERIC_START);
10177
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
10178
				        sig.append(typeVariables[i].genericTypeSignature());
10179
				    }
10180
				    sig.append(Signature.C_GENERIC_END);
9933
				}
10181
				}
9934
				if (isException) {
10182
			} else {
9935
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
10183
				char[] typeSig = referenceBinding.signature();
9936
					int length = catchArguments == null ? 0 : catchArguments.length;
10184
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9937
					for (int i = 0; i < length; i++) {
10185
9938
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
10186
				if (referenceBinding.isStatic()) {
9939
						if (caughtException != null) {
10187
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9940
							addForbiddenBindings(caughtException);
10188
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9941
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
10189
					    sig.append(Signature.C_GENERIC_START);
9942
						}
10190
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
10191
					        sig.append(typeVariables[i].genericTypeSignature());
10192
					    }
10193
					    sig.append(Signature.C_GENERIC_END);
9943
					}
10194
					}
9944
					this.forbbidenBindingsFilter = SUBTYPE;
9945
				}
10195
				}
9946
			}
10196
			}
10197
			sig.append(Signature.C_SEMICOLON);
9947
		}
10198
		}
9948
//		else if(scope instanceof MethodScope) {
10199
		int sigLength = sig.length();
9949
//			MethodScope methodScope = (MethodScope) scope;
10200
		result = new char[sigLength];
9950
//			if(methodScope.insideTypeAnnotation) {
10201
		sig.getChars(0, sigLength, result, 0);
9951
//				return methodScope.parent.parent;
10202
		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
9952
//			}
10203
		return result;
9953
//		}
9954
		return scope;
9955
	}
10204
	}
9956
	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
9957
10205
9958
		StringBuffer completion = new StringBuffer(10);
10206
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
10207
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
9959
10208
9960
		if (isStatic) {
10209
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
9961
			completion.append(declarationType.sourceName());
9962
10210
9963
		} else if (declarationType == invocationType) {
10211
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
9964
			completion.append(THIS);
9965
10212
9966
		} else {
10213
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
9967
10214
9968
			if (!declarationType.isNestedType()) {
10215
		int count = 0;
10216
		next : for (int i = 0; i < favoriteReferences.length; i++) {
10217
			String favoriteReference = favoriteReferences[i];
9969
10218
9970
				completion.append(declarationType.sourceName());
10219
			int length;
9971
				completion.append('.');
10220
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
9972
				completion.append(THIS);
9973
10221
9974
			} else if (!declarationType.isAnonymousType()) {
10222
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
9975
10223
9976
				completion.append(declarationType.sourceName());
10224
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
9977
				completion.append('.');
10225
			if (onDemand) {
9978
				completion.append(THIS);
10226
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
10227
			}
10228
10229
			// remove duplicate and conflicting
10230
			for (int j = 0; j < count; j++) {
10231
				ImportReference f = resolvedImports[j].reference;
10232
10233
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
10234
10235
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
10236
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
10237
						continue next;
10238
				}
10239
			}
10240
10241
			boolean isStatic = true;
10242
10243
			ImportReference importReference =
10244
				new ImportReference(
10245
						compoundName,
10246
						new long[compoundName.length],
10247
						onDemand,
10248
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
10249
10250
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
10251
10252
			if (!importBinding.isValidBinding()) {
10253
				continue next;
10254
			}
9979
10255
10256
			if (importBinding instanceof PackageBinding) {
10257
				continue next;
9980
			}
10258
			}
10259
10260
			resolvedImports[count++] =
10261
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
9981
		}
10262
		}
9982
10263
9983
		return completion.toString().toCharArray();
10264
		if (resolvedImports.length > count)
9984
	}
10265
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
9985
10266
9986
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10267
		return this.favoriteReferenceBindings = resolvedImports;
9987
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10268
	}
9988
			int relevance = computeBaseRelevance();
9989
			relevance += computeRelevanceForResolution();
9990
			relevance += computeRelevanceForInterestingProposal();
9991
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
9992
10269
9993
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10270
	public AssistParser getParser() {
9994
			proposal.setDeclarationSignature(getSignature(reference));
9995
			proposal.setSignature(
9996
					createMethodSignature(
9997
							CharOperation.NO_CHAR_CHAR,
9998
							CharOperation.NO_CHAR_CHAR,
9999
							CharOperation.NO_CHAR,
10000
							VOID));
10001
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
10002
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10003
10271
10004
			//proposal.setPackageName(null);
10272
		return this.parser;
10005
			proposal.setTypeName(VOID);
10273
	}
10006
			proposal.setName(token);
10274
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
10007
			//proposal.setParameterPackageNames(null);
10275
		if (this.targetedElement == TagBits.AnnotationForPackage) {
10008
			//proposal.setParameterTypeNames(null);
10276
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
10009
			//proposal.setPackageName(null);
10277
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
10010
			proposal.setCompletion(token);
10278
				return false;
10011
			proposal.setFlags(Flags.AccPublic);
10279
			}
10012
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10280
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
10013
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10281
			if (scope.parent != null &&
10014
			proposal.setRelevance(relevance);
10282
					scope.parent.parent != null &&
10015
			this.requestor.accept(proposal);
10283
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
10016
			if(DEBUG) {
10284
					scope.parent.parent instanceof CompilationUnitScope) {
10017
				this.printDebug(proposal);
10285
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
10286
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
10287
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
10288
						return false;
10289
					}
10290
				} else {
10291
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
10292
						return false;
10293
					}
10294
				}
10018
			}
10295
			}
10019
		}
10296
		}
10297
		return true;
10298
	}
10299
	/**
10300
	 * Returns completion string inserted inside a specified inline tag.
10301
	 * @param completionName
10302
	 * @return char[] Completion text inclunding specified inline tag
10303
	 */
10304
	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
10305
		int tagLength= inlineTag.length;
10306
		int completionLength = completionName.length;
10307
		int inlineLength = 2+tagLength+1+completionLength+1;
10308
		char[] inlineCompletion = new char[inlineLength];
10309
		inlineCompletion[0] = '{';
10310
		inlineCompletion[1] = '@';
10311
		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
10312
		inlineCompletion[tagLength+2] = ' ';
10313
		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
10314
		// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
10315
		//inlineCompletion[inlineLength-2] = ' ';
10316
		inlineCompletion[inlineLength-1] = '}';
10317
		return inlineCompletion;
10020
	}
10318
	}
10021
	private boolean isForbidden(Binding binding) {
10319
	private boolean isForbidden(Binding binding) {
10022
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
10320
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
Lines 10033-10038 Link Here
10033
		}
10331
		}
10034
		return false;
10332
		return false;
10035
	}
10333
	}
10334
10335
	private boolean isIgnored(int kind) {
10336
		return this.requestor.isIgnored(kind);
10337
	}
10338
	private boolean isIgnored(int kind, boolean missingTypes) {
10339
		return this.requestor.isIgnored(kind) ||
10340
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
10341
	}
10342
10343
	private boolean isIgnored(int kind, int requiredProposalKind) {
10344
		return this.requestor.isIgnored(kind) ||
10345
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
10346
	}
10036
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10347
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10037
10348
10038
		if(parent instanceof ParameterizedSingleTypeReference) {
10349
		if(parent instanceof ParameterizedSingleTypeReference) {
Lines 10112-10371 Link Here
10112
		}
10423
		}
10113
		return true;
10424
		return true;
10114
	}
10425
	}
10115
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
10426
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
10116
		return Signature.createCharArrayTypeSignature(
10427
		StringBuffer prefix = new StringBuffer();
10117
				CharOperation.concat(
10428
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
10118
						qualifiedPackageName,
10429
		if(isStatic) {
10119
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
10430
			prefix.append("static "); //$NON-NLS-1$
10120
	}
10431
		}
10121
	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
10432
		prefix.append("{\n"); //$NON-NLS-1$
10122
		char[] name = new char[qualifiedTypeName.length];
10433
		for (int i = 0; i < localVariableTypeNames.length; i++) {
10123
		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
10434
			ASTNode.printModifiers(localVariableModifiers[i], prefix);
10124
10435
			prefix.append(' ');
10125
		int depth = 0;
10436
			prefix.append(localVariableTypeNames[i]);
10126
		int length = name.length;
10437
			prefix.append(' ');
10127
		for (int i = length -1; i >= 0; i--) {
10438
			prefix.append(localVariableNames[i]);
10128
			switch (name[i]) {
10439
			prefix.append(';');
10129
				case '.':
10440
		}
10130
					if (depth == 0 && name[i - 1] != '>') {
10441
10131
						name[i] = '$';
10442
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
10132
					}
10443
		this.offset = prefix.length();
10133
					break;
10444
10134
				case '<':
10445
		String encoding = this.compilerOptions.defaultEncoding;
10135
					depth--;
10446
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
10136
					break;
10447
			fakeSource,
10137
				case '>':
10448
			null,
10138
					depth++;
10449
			"FakeType.java", //$NON-NLS-1$
10139
					break;
10450
			encoding);
10140
			}
10451
10141
		}
10452
		this.actualCompletionPosition = prefix.length() + position - 1;
10142
		return Signature.createCharArrayTypeSignature(
10453
10143
				CharOperation.concat(
10454
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
10144
						qualifiedPackageName,
10455
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
10145
						name, '.'), true);
10456
10146
	}
10457
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
10147
10148
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
10149
		char[] returnTypeSignature =
10150
			returnTypeName == null || returnTypeName.length == 0
10151
			? Signature.createCharArrayTypeSignature(VOID, true)
10152
			: Signature.createCharArrayTypeSignature(
10153
					CharOperation.concat(
10154
							returnPackagename,
10155
							CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
10156
10157
		return createMethodSignature(
10158
				parameterPackageNames,
10159
				parameterTypeNames,
10160
				returnTypeSignature);
10161
	}
10162
10163
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
10164
		char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
10165
		for (int i = 0; i < parameterTypeSignature.length; i++) {
10166
			parameterTypeSignature[i] =
10167
				Signature.createCharArrayTypeSignature(
10168
						CharOperation.concat(
10169
								parameterPackageNames[i],
10170
								CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
10171
		}
10172
10173
		return Signature.createMethodSignature(
10174
				parameterTypeSignature,
10175
				returnTypeSignature);
10176
	}
10177
10178
	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
10179
		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
10180
		proposal.nameLookup = this.nameEnvironment.nameLookup;
10181
		proposal.completionEngine = this;
10182
		return proposal;
10183
	}
10184
10185
	/*
10186
	 * Create a completion proposal for a type.
10187
	 */
10188
	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
10189
10190
		// Create standard type proposal
10191
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
10192
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
10193
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10194
			proposal.completionEngine = this;
10195
			proposal.setDeclarationSignature(packageName);
10196
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
10197
			proposal.setPackageName(packageName);
10198
			proposal.setTypeName(typeName);
10199
			proposal.setCompletion(completionName);
10200
			proposal.setFlags(modifiers);
10201
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10202
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10203
			proposal.setRelevance(relevance);
10204
			proposal.setAccessibility(accessibility);
10205
			this.requestor.accept(proposal);
10206
			if(DEBUG) {
10207
				this.printDebug(proposal);
10208
			}
10209
		}
10210
10211
		// Create javadoc text proposal if necessary
10212
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10213
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10214
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10215
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10216
			proposal.completionEngine = this;
10217
			proposal.setDeclarationSignature(packageName);
10218
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
10219
			proposal.setPackageName(packageName);
10220
			proposal.setTypeName(typeName);
10221
			proposal.setCompletion(javadocCompletion);
10222
			proposal.setFlags(modifiers);
10223
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
10224
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
10225
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10226
			proposal.setRelevance(relevance+R_INLINE_TAG);
10227
			proposal.setAccessibility(accessibility);
10228
			this.requestor.accept(proposal);
10229
			if(DEBUG) {
10230
				this.printDebug(proposal);
10231
			}
10232
		}
10233
	}
10234
10235
	/*
10236
	 * Create a completion proposal for a member type.
10237
	 */
10238
	private void createTypeProposal(
10239
			ReferenceBinding refBinding,
10240
			char[] typeName,
10241
			int accessibility,
10242
			char[] completionName,
10243
			int relevance,
10244
			Binding[] missingElements,
10245
			int[] missingElementsStarts,
10246
			int[] missingElementsEnds,
10247
			boolean missingElementsHaveProblems) {
10248
10249
		// Create standard type proposal
10250
		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
10251
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
10252
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10253
			proposal.completionEngine = this;
10254
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
10255
			proposal.setSignature(getCompletedTypeSignature(refBinding));
10256
			proposal.setPackageName(refBinding.qualifiedPackageName());
10257
			proposal.setTypeName(typeName);
10258
			if (missingElements != null) {
10259
				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
10260
				for (int i = 0; i < missingElements.length; i++) {
10261
					subProposals[i] =
10262
						createRequiredTypeProposal(
10263
								missingElements[i],
10264
								missingElementsStarts[i],
10265
								missingElementsEnds[i],
10266
								relevance);
10267
				}
10268
				proposal.setRequiredProposals(subProposals);
10269
			}
10270
			proposal.setCompletion(completionName);
10271
			proposal.setFlags(refBinding.modifiers);
10272
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10273
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10274
			proposal.setRelevance(relevance);
10275
			this.requestor.accept(proposal);
10276
			if(DEBUG) {
10277
				this.printDebug(proposal);
10278
			}
10279
		}
10280
10281
		// Create javadoc text proposal if necessary
10282
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10283
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10284
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10285
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10286
			proposal.completionEngine = this;
10287
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
10288
			proposal.setSignature(getCompletedTypeSignature(refBinding));
10289
			proposal.setPackageName(refBinding.qualifiedPackageName());
10290
			proposal.setTypeName(typeName);
10291
			proposal.setCompletion(javadocCompletion);
10292
			proposal.setFlags(refBinding.modifiers);
10293
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
10294
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
10295
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10296
			proposal.setRelevance(relevance+R_INLINE_TAG);
10297
			this.requestor.accept(proposal);
10298
			if(DEBUG) {
10299
				this.printDebug(proposal);
10300
			}
10301
		}
10302
	}
10303
10304
	/*
10305
	 * Create a completion proposal for a member type.
10306
	 */
10307
	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
10308
		char[] completionName = typeParameter.name;
10309
10310
		// Create standard type proposal
10311
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10312
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
10313
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10314
			proposal.completionEngine = this;
10315
			proposal.setSignature(getSignature(typeParameter.binding));
10316
			proposal.setTypeName(completionName);
10317
			proposal.setCompletion(completionName);
10318
			proposal.setFlags(typeParameter.modifiers);
10319
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10320
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10321
			proposal.setRelevance(relevance);
10322
			this.requestor.accept(proposal);
10323
			if(DEBUG) {
10324
				this.printDebug(proposal);
10325
			}
10326
		}
10327
10328
		// Create javadoc text proposal if necessary
10329
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10330
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10331
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10332
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10333
			proposal.completionEngine = this;
10334
			proposal.setSignature(getSignature(typeParameter.binding));
10335
			proposal.setTypeName(javadocCompletion);
10336
			proposal.setCompletion(javadocCompletion);
10337
			proposal.setFlags(typeParameter.modifiers);
10338
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10339
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10340
			proposal.setRelevance(relevance+R_INLINE_TAG);
10341
			this.requestor.accept(proposal);
10342
			if(DEBUG) {
10343
				this.printDebug(proposal);
10344
			}
10345
		}
10346
	}
10347
10348
	/**
10349
	 * Returns completion string inserted inside a specified inline tag.
10350
	 * @param completionName
10351
	 * @return char[] Completion text inclunding specified inline tag
10352
	 */
10353
	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
10354
		int tagLength= inlineTag.length;
10355
		int completionLength = completionName.length;
10356
		int inlineLength = 2+tagLength+1+completionLength+1;
10357
		char[] inlineCompletion = new char[inlineLength];
10358
		inlineCompletion[0] = '{';
10359
		inlineCompletion[1] = '@';
10360
		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
10361
		inlineCompletion[tagLength+2] = ' ';
10362
		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
10363
		// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
10364
		//inlineCompletion[inlineLength-2] = ' ';
10365
		inlineCompletion[inlineLength-1] = '}';
10366
		return inlineCompletion;
10367
	}
10368
10458
10459
		return (Initializer)fakeAST.types[0].fields[0];
10460
	}
10369
	protected void printDebug(CategorizedProblem error) {
10461
	protected void printDebug(CategorizedProblem error) {
10370
		if(CompletionEngine.DEBUG) {
10462
		if(CompletionEngine.DEBUG) {
10371
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
10463
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
Lines 10373-10390 Link Here
10373
			System.out.println(")"); //$NON-NLS-1$
10465
			System.out.println(")"); //$NON-NLS-1$
10374
		}
10466
		}
10375
	}
10467
	}
10376
10377
	private void printDebugTab(int tab, StringBuffer buffer) {
10378
		for (int i = 0; i < tab; i++) {
10379
			buffer.append('\t');
10380
		}
10381
	}
10382
10383
	protected void printDebug(CompletionProposal proposal){
10468
	protected void printDebug(CompletionProposal proposal){
10384
		StringBuffer buffer = new StringBuffer();
10469
		StringBuffer buffer = new StringBuffer();
10385
		printDebug(proposal, 0, buffer);
10470
		printDebug(proposal, 0, buffer);
10386
		System.out.println(buffer.toString());
10471
		System.out.println(buffer.toString());
10387
	}
10472
	}
10473
10388
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10474
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10389
		printDebugTab(tab, buffer);
10475
		printDebugTab(tab, buffer);
10390
		buffer.append("COMPLETION - "); //$NON-NLS-1$
10476
		buffer.append("COMPLETION - "); //$NON-NLS-1$
Lines 10509-10550 Link Here
10509
		buffer.append("}\n");//$NON-NLS-1$
10595
		buffer.append("}\n");//$NON-NLS-1$
10510
	}
10596
	}
10511
10597
10512
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10598
	private void printDebugTab(int tab, StringBuffer buffer) {
10513
		char[][] substituedParameterNames = new char[typeVariables.length][];
10599
		for (int i = 0; i < tab; i++) {
10600
			buffer.append('\t');
10601
		}
10602
	}
10514
10603
10515
		for (int i = 0; i < substituedParameterNames.length; i++) {
10604
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10516
			substituedParameterNames[i] = typeVariables[i].sourceName;
10605
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10606
			int relevance = computeBaseRelevance();
10607
			relevance += computeRelevanceForResolution();
10608
			relevance += computeRelevanceForInterestingProposal();
10609
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
10610
10611
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10612
			proposal.setDeclarationSignature(getSignature(reference));
10613
			proposal.setSignature(
10614
					createMethodSignature(
10615
							CharOperation.NO_CHAR_CHAR,
10616
							CharOperation.NO_CHAR_CHAR,
10617
							CharOperation.NO_CHAR,
10618
							VOID));
10619
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
10620
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10621
10622
			//proposal.setPackageName(null);
10623
			proposal.setTypeName(VOID);
10624
			proposal.setName(token);
10625
			//proposal.setParameterPackageNames(null);
10626
			//proposal.setParameterTypeNames(null);
10627
			//proposal.setPackageName(null);
10628
			proposal.setCompletion(token);
10629
			proposal.setFlags(Flags.AccPublic);
10630
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10631
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10632
			proposal.setRelevance(relevance);
10633
			this.requestor.accept(proposal);
10634
			if(DEBUG) {
10635
				this.printDebug(proposal);
10636
			}
10517
		}
10637
		}
10638
	}
10518
10639
10519
		boolean foundConflicts = false;
10640
	private void proposeType(
10641
			char[] packageName,
10642
			char[] simpleTypeName,
10643
			int modifiers,
10644
			int accessibility,
10645
			char[] typeName,
10646
			char[] fullyQualifiedName,
10647
			boolean isQualified,
10648
			boolean isNotOptimum,
10649
			Scope scope) {
10650
		char[] completionName = fullyQualifiedName;
10651
		if(isQualified) {
10652
			if (packageName == null || packageName.length == 0)
10653
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
10654
					return; // ignore types from the default package from outside it
10655
		} else {
10656
			completionName = simpleTypeName;
10657
		}
10520
10658
10521
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10659
		TypeBinding guessedType = null;
10522
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10660
		if (!this.timeoutExceeded &&
10523
			char[] methodParameterName = typeVariableBinding.sourceName;
10661
				(modifiers & ClassFileConstants.AccAnnotation) != 0 &&
10662
				this.assistNodeIsAnnotation &&
10663
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
10664
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
10524
10665
10525
			for (int j = 0; j < excludedNames.length; j++) {
10666
			TypeReference ref;
10526
				char[] typeParameterName = excludedNames[j];
10667
			if (cn.length == 1) {
10527
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10668
				ref = new SingleTypeReference(simpleTypeName, 0);
10528
					char[] substitution;
10669
			} else {
10529
					if(methodParameterName.length == 1) {
10670
				ref = new QualifiedTypeReference(cn,new long[cn.length]);
10530
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10671
			}
10531
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
10532
						} else {
10533
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
10534
						}
10535
					} else {
10536
						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
10537
					}
10538
					substituedParameterNames[i] = substitution;
10539
10672
10540
					foundConflicts = true;
10673
			switch (scope.kind) {
10541
					continue nextTypeParameter;
10674
				case Scope.METHOD_SCOPE :
10542
				}
10675
				case Scope.BLOCK_SCOPE :
10676
					guessedType = ref.resolveType((BlockScope)scope);
10677
					break;
10678
				case Scope.CLASS_SCOPE :
10679
					guessedType = ref.resolveType((ClassScope)scope);
10680
					break;
10543
			}
10681
			}
10682
10683
			if (guessedType == null || !guessedType.isValidBinding()) return;
10684
10685
			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
10544
		}
10686
		}
10545
10687
10546
		if(foundConflicts) return substituedParameterNames;
10688
		int relevance = computeBaseRelevance();
10547
		return null;
10689
		relevance += computeRelevanceForResolution();
10690
		relevance += computeRelevanceForInterestingProposal();
10691
		relevance += computeRelevanceForRestrictions(accessibility);
10692
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
10693
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
10694
		relevance += computeRelevanceForQualification(isQualified);
10695
10696
		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
10697
		switch (kind) {
10698
			case ClassFileConstants.AccAnnotation:
10699
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
10700
				relevance += computeRelevanceForAnnotation();
10701
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
10702
				relevance += computeRelevanceForInterface();
10703
				break;
10704
			case ClassFileConstants.AccEnum:
10705
				relevance += computeRelevanceForEnum();
10706
				break;
10707
			case ClassFileConstants.AccInterface:
10708
				relevance += computeRelevanceForInterface();
10709
				break;
10710
			default:
10711
				relevance += computeRelevanceForClass();
10712
				relevance += computeRelevanceForException(simpleTypeName);
10713
				break;
10714
		}
10715
10716
		this.noProposal = false;
10717
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10718
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance, isNotOptimum);
10719
		}
10720
	}
10721
10722
	protected void reset() {
10723
10724
		super.reset(false);
10725
		this.knownPkgs = new HashtableOfObject(10);
10726
		this.knownTypes = new HashtableOfObject(10);
10727
		this.timeoutExceeded = false;
10728
	}
10729
10730
	private void setSourceAndTokenRange(int start, int end) {
10731
		this.setSourceAndTokenRange(start, end, true);
10732
	}
10733
10734
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10735
		this.setSourceRange(start, end, emptyTokenAdjstment);
10736
		this.setTokenRange(start, end, emptyTokenAdjstment);
10737
	}
10738
10739
	private void setSourceRange(int start, int end) {
10740
		this.setSourceRange(start, end, true);
10741
	}
10742
10743
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
10744
		this.startPosition = start;
10745
		if(emptyTokenAdjstment) {
10746
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10747
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10748
		} else {
10749
			this.endPosition = end + 1;
10750
		}
10751
	}
10752
10753
	private void setTokenRange(int start, int end) {
10754
		this.setTokenRange(start, end, true);
10755
	}
10756
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10757
		this.tokenStart = start;
10758
		if(emptyTokenAdjstment) {
10759
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10760
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10761
		} else {
10762
			this.tokenEnd = end + 1;
10763
		}
10548
	}
10764
	}
10549
10765
10550
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
10766
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
Lines 10596-10599 Link Here
10596
		}
10812
		}
10597
		return name;
10813
		return name;
10598
	}
10814
	}
10815
10816
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10817
		char[][] substituedParameterNames = new char[typeVariables.length][];
10818
10819
		for (int i = 0; i < substituedParameterNames.length; i++) {
10820
			substituedParameterNames[i] = typeVariables[i].sourceName;
10821
		}
10822
10823
		boolean foundConflicts = false;
10824
10825
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10826
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10827
			char[] methodParameterName = typeVariableBinding.sourceName;
10828
10829
			for (int j = 0; j < excludedNames.length; j++) {
10830
				char[] typeParameterName = excludedNames[j];
10831
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10832
					char[] substitution;
10833
					if(methodParameterName.length == 1) {
10834
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10835
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
10836
						} else {
10837
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
10838
						}
10839
					} else {
10840
						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
10841
					}
10842
					substituedParameterNames[i] = substitution;
10843
10844
					foundConflicts = true;
10845
					continue nextTypeParameter;
10846
				}
10847
			}
10848
		}
10849
10850
		if(foundConflicts) return substituedParameterNames;
10851
		return null;
10852
	}
10599
}
10853
}
(-)codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java (+52 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.jdt.internal.codeassist.complete;
12
13
import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
14
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
15
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
16
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
17
18
public class CompletionOnBranchStatementLabel extends BranchStatement {
19
	public static final int BREAK = 1;
20
	public static final int CONTINUE = 2;
21
22
	private int kind;
23
	public char[][] possibleLabels;
24
25
	public CompletionOnBranchStatementLabel(int kind, char[] l, int s, int e, char[][] possibleLabels) {
26
		super(l, s, e);
27
		this.kind = kind;
28
		this.possibleLabels = possibleLabels;
29
	}
30
31
	public FlowInfo analyseCode(BlockScope currentScope,
32
			FlowContext flowContext, FlowInfo flowInfo) {
33
		// Is never called
34
		return null;
35
	}
36
37
	public void resolve(BlockScope scope) {
38
		throw new CompletionNodeFound(this, scope);
39
	}
40
	public StringBuffer printStatement(int indent, StringBuffer output) {
41
		printIndent(indent, output);
42
		if(this.kind == CONTINUE) {
43
			output.append("continue "); //$NON-NLS-1$
44
		} else {
45
			output.append("break "); //$NON-NLS-1$
46
		}
47
		output.append("<CompleteOnLabel:"); //$NON-NLS-1$
48
		output.append(this.label);
49
		return output.append(">;"); //$NON-NLS-1$
50
	}
51
52
}

Return to bug 247433