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

Collapse All | Expand All

(-)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/internal/core/SourceType.java (-1 / +23 lines)
Lines 74-87 Link Here
74
/**
74
/**
75
 * @see IType
75
 * @see IType
76
 */
76
 */
77
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
78
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
79
}
80
/**
81
 * @see IType
82
 */
77
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
83
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
84
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, owner, null);
85
}
86
/**
87
 * @see IType
88
 */
89
public void codeComplete(
90
		char[] snippet,
91
		int insertion,
92
		int position,
93
		char[][] localVariableTypeNames,
94
		char[][] localVariableNames,
95
		int[] localVariableModifiers,
96
		boolean isStatic,
97
		CompletionRequestor requestor,
98
		WorkingCopyOwner owner,
99
		IProgressMonitor monitor) throws JavaModelException {
78
	if (requestor == null) {
100
	if (requestor == null) {
79
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
101
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
80
	}
102
	}
81
103
82
	JavaProject project = (JavaProject) getJavaProject();
104
	JavaProject project = (JavaProject) getJavaProject();
83
	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
105
	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
84
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner);
106
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
85
107
86
	String source = getCompilationUnit().getSource();
108
	String source = getCompilationUnit().getSource();
87
	if (source != null && insertion > -1 && insertion < source.length()) {
109
	if (source != null && insertion > -1 && insertion < source.length()) {
(-)model/org/eclipse/jdt/internal/core/ClassFile.java (-2 / +13 lines)
Lines 122-132 Link Here
122
public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
122
public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
123
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
123
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
124
}
124
}
125
125
/* (non-Javadoc)
126
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.core.runtime.IProgressMonitor)
127
 */
128
public void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
129
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
130
}
126
/* (non-Javadoc)
131
/* (non-Javadoc)
127
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
132
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
128
 */
133
 */
129
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
134
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
135
	codeComplete(offset, requestor, owner, null);
136
}
137
/* (non-Javadoc)
138
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner, org.eclipse.core.runtime.IProgressMonitor)
139
 */
140
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException {
130
	String source = getSource();
141
	String source = getSource();
131
	if (source != null) {
142
	if (source != null) {
132
		BinaryType type = (BinaryType) getType();
143
		BinaryType type = (BinaryType) getType();
Lines 136-142 Link Here
136
				null,
147
				null,
137
				type.sourceFileName((IBinaryType) type.getElementInfo()),
148
				type.sourceFileName((IBinaryType) type.getElementInfo()),
138
				getJavaProject()); // use project to retrieve corresponding .java IFile
149
				getJavaProject()); // use project to retrieve corresponding .java IFile
139
		codeComplete(cu, cu, offset, requestor, owner, null/*extended context isn't computed*/);
150
		codeComplete(cu, cu, offset, requestor, owner, null/*extended context isn't computed*/, monitor);
140
	}
151
	}
141
}
152
}
142
153
(-)model/org/eclipse/jdt/internal/core/Openable.java (-2 / +3 lines)
Lines 101-107 Link Here
101
		org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip,
101
		org.eclipse.jdt.internal.compiler.env.ICompilationUnit unitToSkip,
102
		int position, CompletionRequestor requestor,
102
		int position, CompletionRequestor requestor,
103
		WorkingCopyOwner owner,
103
		WorkingCopyOwner owner,
104
		ITypeRoot typeRoot) throws JavaModelException {
104
		ITypeRoot typeRoot,
105
		IProgressMonitor monitor) throws JavaModelException {
105
	if (requestor == null) {
106
	if (requestor == null) {
106
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
107
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
107
	}
108
	}
Lines 125-131 Link Here
125
	environment.unitToSkip = unitToSkip;
126
	environment.unitToSkip = unitToSkip;
126
127
127
	// code complete
128
	// code complete
128
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner);
129
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
129
	engine.complete(cu, position, 0, typeRoot);
130
	engine.complete(cu, position, 0, typeRoot);
130
	if(performanceStats != null) {
131
	if(performanceStats != null) {
131
		performanceStats.endRun();
132
		performanceStats.endRun();
(-)model/org/eclipse/jdt/internal/core/BinaryType.java (-2 / +23 lines)
Lines 82-98 Link Here
82
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor) throws JavaModelException {
82
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor) throws JavaModelException {
83
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
83
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY);
84
}
84
}
85
85
/*
86
 * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, IProgressMonitor)
87
 */
88
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
89
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
90
}
86
/*
91
/*
87
 * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner)
92
 * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner)
88
 */
93
 */
89
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
94
public void codeComplete(char[] snippet,int insertion,int position,char[][] localVariableTypeNames,char[][] localVariableNames,int[] localVariableModifiers,boolean isStatic,CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
95
	codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, owner, null);
96
}
97
/*
98
 * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner, IProgressMonitor)
99
 */
100
public void codeComplete(
101
		char[] snippet,
102
		int insertion,
103
		int position,
104
		char[][] localVariableTypeNames,
105
		char[][] localVariableNames,
106
		int[] localVariableModifiers,
107
		boolean isStatic,
108
		CompletionRequestor requestor,
109
		WorkingCopyOwner owner,
110
		IProgressMonitor monitor) throws JavaModelException {
90
	if (requestor == null) {
111
	if (requestor == null) {
91
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
112
		throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$
92
	}
113
	}
93
	JavaProject project = (JavaProject) getJavaProject();
114
	JavaProject project = (JavaProject) getJavaProject();
94
	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
115
	SearchableEnvironment environment = project.newSearchableNameEnvironment(owner);
95
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner);
116
	CompletionEngine engine = new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor);
96
117
97
	String source = getClassFile().getSource();
118
	String source = getClassFile().getSource();
98
	if (source != null && insertion > -1 && insertion < source.length()) {
119
	if (source != null && insertion > -1 && insertion < source.length()) {
(-)model/org/eclipse/jdt/internal/core/CompilationUnit.java (-2 / +14 lines)
Lines 336-353 Link Here
336
public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
336
public void codeComplete(int offset, CompletionRequestor requestor) throws JavaModelException {
337
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
337
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY);
338
}
338
}
339
339
/* (non-Javadoc)
340
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.core.runtime.IProgressMonitor)
341
 */
342
public void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
343
	codeComplete(offset, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor);
344
}
340
/* (non-Javadoc)
345
/* (non-Javadoc)
341
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
346
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner)
342
 */
347
 */
343
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner) throws JavaModelException {
348
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner) throws JavaModelException {
349
	codeComplete(offset, requestor, workingCopyOwner, null);
350
}
351
/* (non-Javadoc)
352
 * @see org.eclipse.jdt.core.ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor, org.eclipse.jdt.core.WorkingCopyOwner, org.eclipse.core.runtime.IProgressMonitor)
353
 */
354
public void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner workingCopyOwner, IProgressMonitor monitor) throws JavaModelException {
344
	codeComplete(
355
	codeComplete(
345
			this,
356
			this,
346
			isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
357
			isWorkingCopy() ? (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) getOriginalElement() : this,
347
			offset,
358
			offset,
348
			requestor,
359
			requestor,
349
			workingCopyOwner,
360
			workingCopyOwner,
350
			this);
361
			this,
362
			monitor);
351
}
363
}
352
364
353
/**
365
/**
(-)model/org/eclipse/jdt/core/eval/IEvaluationContext.java (+65 lines)
Lines 177-182 Link Here
177
		int position,
177
		int position,
178
		CompletionRequestor requestor)
178
		CompletionRequestor requestor)
179
		throws JavaModelException;
179
		throws JavaModelException;
180
	
181
	/**
182
	 * Performs a code completion at the given position in the given code snippet,
183
	 * reporting results to the given completion requestor.
184
	 * <p>
185
	 * Note that code completion does not involve evaluation.
186
	 * <p>
187
	 *
188
	 * @param codeSnippet the code snippet to complete in
189
	 * @param position the character position in the code snippet to complete at,
190
	 *   or -1 indicating the beginning of the snippet
191
	 * @param requestor the code completion requestor capable of accepting all
192
	 *    possible types of completions
193
	 * @param monitor the progress monitor used to report progress
194
	 * @exception JavaModelException if code completion could not be performed. Reasons include:
195
	 *  <ul>
196
	 *	  <li>The position specified is less than -1 or is greater than the snippet's
197
	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
198
	 *  </ul>
199
	 * @since 3.5
200
	 */
201
	public void codeComplete(
202
		String codeSnippet,
203
		int position,
204
		CompletionRequestor requestor,
205
		IProgressMonitor monitor)
206
		throws JavaModelException;
207
	
180
	/**
208
	/**
181
	 * Performs a code completion at the given position in the given code snippet,
209
	 * Performs a code completion at the given position in the given code snippet,
182
	 * reporting results to the given completion requestor.
210
	 * reporting results to the given completion requestor.
Lines 210-215 Link Here
210
		CompletionRequestor requestor,
238
		CompletionRequestor requestor,
211
		WorkingCopyOwner owner)
239
		WorkingCopyOwner owner)
212
		throws JavaModelException;
240
		throws JavaModelException;
241
	
242
	/**
243
	 * Performs a code completion at the given position in the given code snippet,
244
	 * reporting results to the given completion requestor.
245
	 * It considers types in the working copies with the given owner first. In other words,
246
	 * the owner's working copies will take precedence over their original compilation units
247
	 * in the workspace.
248
	 * <p>
249
	 * Note that if a working copy is empty, it will be as if the original compilation
250
	 * unit had been deleted.
251
	 * </p>
252
	 * <p>
253
	 * Note that code completion does not involve evaluation.
254
	 * <p>
255
	 *
256
	 * @param codeSnippet the code snippet to complete in
257
	 * @param position the character position in the code snippet to complete at,
258
	 *   or -1 indicating the beginning of the snippet
259
	 * @param requestor the code completion requestor capable of accepting all
260
	 *    possible types of completions
261
	 * @param owner the owner of working copies that take precedence over their original compilation units
262
	 * @param monitor the progress monitor used to report progress
263
	 * @exception JavaModelException if code completion could not be performed. Reasons include:
264
	 *  <ul>
265
	 *	  <li>The position specified is less than -1 or is greater than the snippet's
266
	 *	    length (INDEX_OUT_OF_BOUNDS)</li>
267
	 *  </ul>
268
	 * @since 3.5
269
	 */
270
	public void codeComplete(
271
		String codeSnippet,
272
		int position,
273
		CompletionRequestor requestor,
274
		WorkingCopyOwner owner,
275
		IProgressMonitor monitor)
276
		throws JavaModelException;
277
	
213
	/**
278
	/**
214
	 * Resolves and returns a collection of Java elements corresponding to the source
279
	 * Resolves and returns a collection of Java elements corresponding to the source
215
	 * code at the given positions in the given code snippet.
280
	 * code at the given positions in the given code snippet.
(-)codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java (-8343 / +8555 lines)
Lines 14-19 Link Here
14
import java.util.Locale;
14
import java.util.Locale;
15
import java.util.Map;
15
import java.util.Map;
16
16
17
import org.eclipse.core.runtime.IProgressMonitor;
18
import org.eclipse.core.runtime.OperationCanceledException;
17
import org.eclipse.jdt.core.CompletionContext;
19
import org.eclipse.jdt.core.CompletionContext;
18
import org.eclipse.jdt.core.CompletionFlags;
20
import org.eclipse.jdt.core.CompletionFlags;
19
import org.eclipse.jdt.core.CompletionProposal;
21
import org.eclipse.jdt.core.CompletionProposal;
Lines 64-69 Link Here
64
import org.eclipse.jdt.internal.core.BinaryTypeConverter;
66
import org.eclipse.jdt.internal.core.BinaryTypeConverter;
65
import org.eclipse.jdt.internal.core.SearchableEnvironment;
67
import org.eclipse.jdt.internal.core.SearchableEnvironment;
66
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
68
import org.eclipse.jdt.internal.core.SourceTypeElementInfo;
69
import org.eclipse.jdt.internal.core.util.Messages;
67
70
68
/**
71
/**
69
 * This class is the entry point for source completions.
72
 * This class is the entry point for source completions.
Lines 73-79 Link Here
73
public final class CompletionEngine
76
public final class CompletionEngine
74
	extends Engine
77
	extends Engine
75
	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
78
	implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
79
	
80
	private static class AcceptedType {
81
		public char[] packageName;
82
		public char[] simpleTypeName;
83
		public char[][] enclosingTypeNames;
84
		public int modifiers;
85
		public int accessibility;
86
		public boolean mustBeQualified = false;
87
88
		public char[] fullyQualifiedName = null;
89
		public char[] qualifiedTypeName = null;
90
		public AcceptedType(
91
			char[] packageName,
92
			char[] simpleTypeName,
93
			char[][] enclosingTypeNames,
94
			int modifiers,
95
			int accessibility) {
96
			this.packageName = packageName;
97
			this.simpleTypeName = simpleTypeName;
98
			this.enclosingTypeNames = enclosingTypeNames;
99
			this.modifiers = modifiers;
100
			this.accessibility = accessibility;
101
		}
76
102
103
		public String toString() {
104
			StringBuffer buffer = new StringBuffer();
105
			buffer.append('{');
106
			buffer.append(this.packageName);
107
			buffer.append(',');
108
			buffer.append(this.simpleTypeName);
109
			buffer.append(',');
110
			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
111
			buffer.append('}');
112
			return buffer.toString();
113
		}
114
	}
115
	
77
	public class CompletionProblemFactory extends DefaultProblemFactory {
116
	public class CompletionProblemFactory extends DefaultProblemFactory {
78
		private int lastErrorStart;
117
		private int lastErrorStart;
79
118
Lines 133-138 Link Here
133
				char[] originatingFileName,
172
				char[] originatingFileName,
134
				int problemId,
173
				int problemId,
135
				String[] problemArguments,
174
				String[] problemArguments,
175
				int elaborationId,
136
				String[] messageArguments,
176
				String[] messageArguments,
137
				int severity,
177
				int severity,
138
				int start,
178
				int start,
Lines 144-149 Link Here
144
						originatingFileName,
184
						originatingFileName,
145
						problemId,
185
						problemId,
146
						problemArguments,
186
						problemArguments,
187
						elaborationId,
147
						messageArguments,
188
						messageArguments,
148
						severity,
189
						severity,
149
						start,
190
						start,
Lines 156-162 Link Here
156
				char[] originatingFileName,
197
				char[] originatingFileName,
157
				int problemId,
198
				int problemId,
158
				String[] problemArguments,
199
				String[] problemArguments,
159
				int elaborationId,
160
				String[] messageArguments,
200
				String[] messageArguments,
161
				int severity,
201
				int severity,
162
				int start,
202
				int start,
Lines 168-174 Link Here
168
						originatingFileName,
208
						originatingFileName,
169
						problemId,
209
						problemId,
170
						problemArguments,
210
						problemArguments,
171
						elaborationId,
172
						messageArguments,
211
						messageArguments,
173
						severity,
212
						severity,
174
						start,
213
						start,
Lines 188-237 Link Here
188
		}
227
		}
189
	}
228
	}
190
229
191
	private static class AcceptedType {
230
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
192
		public AcceptedType(
231
		char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
193
			char[] packageName,
232
		for (int i = 0; i < parameterTypeSignature.length; i++) {
194
			char[] simpleTypeName,
233
			parameterTypeSignature[i] =
195
			char[][] enclosingTypeNames,
234
				Signature.createCharArrayTypeSignature(
196
			int modifiers,
235
						CharOperation.concat(
197
			int accessibility) {
236
								parameterPackageNames[i],
198
			this.packageName = packageName;
237
								CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
199
			this.simpleTypeName = simpleTypeName;
200
			this.enclosingTypeNames = enclosingTypeNames;
201
			this.modifiers = modifiers;
202
			this.accessibility = accessibility;
203
		}
238
		}
204
		public char[] packageName;
205
		public char[] simpleTypeName;
206
		public char[][] enclosingTypeNames;
207
		public int modifiers;
208
		public int accessibility;
209
239
210
		public boolean mustBeQualified = false;
240
		return Signature.createMethodSignature(
211
		public char[] fullyQualifiedName = null;
241
				parameterTypeSignature,
212
		public char[] qualifiedTypeName = null;
242
				returnTypeSignature);
243
	}
213
244
214
		public String toString() {
245
	public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
215
			StringBuffer buffer = new StringBuffer();
246
		char[] returnTypeSignature =
216
			buffer.append('{');
247
			returnTypeName == null || returnTypeName.length == 0
217
			buffer.append(this.packageName);
248
			? Signature.createCharArrayTypeSignature(VOID, true)
218
			buffer.append(',');
249
			: Signature.createCharArrayTypeSignature(
219
			buffer.append(this.simpleTypeName);
250
					CharOperation.concat(
220
			buffer.append(',');
251
							returnPackagename,
221
			buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
252
							CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
222
			buffer.append('}');
253
223
			return buffer.toString();
254
		return createMethodSignature(
255
				parameterPackageNames,
256
				parameterTypeNames,
257
				returnTypeSignature);
258
	}
259
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
260
		return Signature.createCharArrayTypeSignature(
261
				CharOperation.concat(
262
						qualifiedPackageName,
263
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
264
	}
265
266
	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
267
		char[] name = new char[qualifiedTypeName.length];
268
		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
269
270
		int depth = 0;
271
		int length = name.length;
272
		for (int i = length -1; i >= 0; i--) {
273
			switch (name[i]) {
274
				case '.':
275
					if (depth == 0 && name[i - 1] != '>') {
276
						name[i] = '$';
277
					}
278
					break;
279
				case '<':
280
					depth--;
281
					break;
282
				case '>':
283
					depth++;
284
					break;
285
			}
224
		}
286
		}
287
		return Signature.createCharArrayTypeSignature(
288
				CharOperation.concat(
289
						qualifiedPackageName,
290
						name, '.'), true);
225
	}
291
	}
226
292
227
	public HashtableOfObject typeCache;
293
	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
294
		char[] result = null;
295
		StringBuffer sig = new StringBuffer(10);
296
297
		sig.append(typeBinding.signature());
228
298
299
		int sigLength = sig.length();
300
		result = new char[sigLength];
301
		sig.getChars(0, sigLength, result, 0);
302
		result = CharOperation.replaceOnCopy(result, '/', '.');
303
		return result;
304
	}
305
	public HashtableOfObject typeCache;
306
	
229
	public static boolean DEBUG = false;
307
	public static boolean DEBUG = false;
230
	public static boolean PERF = false;
308
	public static boolean PERF = false;
231
309
	
310
	private final static int CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES = 50;
311
	
232
	// temporary constants to quickly disabled polish features if necessary
312
	// temporary constants to quickly disabled polish features if necessary
233
	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
313
	public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
234
314
	
235
	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
315
	private final static char[] ERROR_PATTERN = "*error*".toCharArray();  //$NON-NLS-1$
236
	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
316
	private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray();  //$NON-NLS-1$
237
	private final static char[] SEMICOLON = new char[] { ';' };
317
	private final static char[] SEMICOLON = new char[] { ';' };
Lines 243-253 Link Here
243
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
323
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
244
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
324
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
245
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
325
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
246
326
	
247
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
327
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
248
328
249
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
329
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
250
330
	
251
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
331
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
252
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
332
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
253
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
333
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
Lines 257-271 Link Here
257
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
337
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
258
	private final static char[] JAVA_LANG_NAME =
338
	private final static char[] JAVA_LANG_NAME =
259
		CharOperation.concatWith(JAVA_LANG, '.');
339
		CharOperation.concatWith(JAVA_LANG, '.');
260
340
	
261
	private final static int NONE = 0;
341
	private final static int NONE = 0;
262
	private final static int SUPERTYPE = 1;
342
	private final static int SUPERTYPE = 1;
263
	private final static int SUBTYPE = 2;
343
	private final static int SUBTYPE = 2;
264
344
	
265
	private final static int FIELD = 0;
345
	private final static int FIELD = 0;
266
	private final static int LOCAL = 1;
346
	private final static int LOCAL = 1;
267
	private final static int ARGUMENT = 2;
347
	private final static int ARGUMENT = 2;
268
348
	
269
	int expectedTypesPtr = -1;
349
	int expectedTypesPtr = -1;
270
	TypeBinding[] expectedTypes = new TypeBinding[1];
350
	TypeBinding[] expectedTypes = new TypeBinding[1];
271
	int expectedTypesFilter;
351
	int expectedTypesFilter;
Lines 275-283 Link Here
275
	int forbbidenBindingsPtr = -1;
355
	int forbbidenBindingsPtr = -1;
276
	Binding[] forbbidenBindings = new Binding[1];
356
	Binding[] forbbidenBindings = new Binding[1];
277
	int forbbidenBindingsFilter;
357
	int forbbidenBindingsFilter;
278
358
	
279
	ImportBinding[] favoriteReferenceBindings;
359
	ImportBinding[] favoriteReferenceBindings;
280
360
	
281
	boolean assistNodeIsClass;
361
	boolean assistNodeIsClass;
282
	boolean assistNodeIsEnum;
362
	boolean assistNodeIsEnum;
283
	boolean assistNodeIsException;
363
	boolean assistNodeIsException;
Lines 287-296 Link Here
287
	boolean assistNodeIsSuperType;
367
	boolean assistNodeIsSuperType;
288
	int  assistNodeInJavadoc = 0;
368
	int  assistNodeInJavadoc = 0;
289
	boolean assistNodeCanBeSingleMemberAnnotation = false;
369
	boolean assistNodeCanBeSingleMemberAnnotation = false;
290
370
	
291
	long targetedElement;
371
	long targetedElement;
292
372
	
293
	WorkingCopyOwner owner;
373
	WorkingCopyOwner owner;
374
	IProgressMonitor monitor;
294
	IJavaProject javaProject;
375
	IJavaProject javaProject;
295
	ITypeRoot typeRoot;
376
	ITypeRoot typeRoot;
296
	CompletionParser parser;
377
	CompletionParser parser;
Lines 312-319 Link Here
312
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
393
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
313
	HashtableOfObject knownTypes = new HashtableOfObject(10);
394
	HashtableOfObject knownTypes = new HashtableOfObject(10);
314
	Scanner nameScanner;
395
	Scanner nameScanner;
315
396
	
316
	/*
397
 	/*
317
		static final char[][] mainDeclarations =
398
		static final char[][] mainDeclarations =
318
			new char[][] {
399
			new char[][] {
319
				"package".toCharArray(),
400
				"package".toCharArray(),
Lines 353-359 Link Here
353
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
434
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
354
	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
435
	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][];
436
	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
356
 	static {
437
	static {
357
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
438
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
358
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
439
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
359
 		}
440
 		}
Lines 361-367 Link Here
361
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
442
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
362
		}
443
		}
363
 	}
444
 	}
364
445
	
365
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
446
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
366
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
447
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
367
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
448
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
Lines 375-384 Link Here
375
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
456
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
376
		public void setDepth(int depth){/* empty */}
457
		public void setDepth(int depth){/* empty */}
377
		public void setFieldIndex(int depth){/* empty */}
458
		public void setFieldIndex(int depth){/* empty */}
378
		public int sourceStart() { return 0; 	}
379
		public int sourceEnd() { return 0; 	}
459
		public int sourceEnd() { return 0; 	}
460
		public int sourceStart() { return 0; 	}
380
	};
461
	};
381
462
463
	private int foundTypesCount;
382
	private ObjectVector acceptedTypes;
464
	private ObjectVector acceptedTypes;
383
465
384
	/**
466
	/**
Lines 403-409 Link Here
403
			CompletionRequestor requestor,
485
			CompletionRequestor requestor,
404
			Map settings,
486
			Map settings,
405
			IJavaProject javaProject,
487
			IJavaProject javaProject,
406
			WorkingCopyOwner owner) {
488
			WorkingCopyOwner owner,
489
			IProgressMonitor monitor) {
407
		super(settings);
490
		super(settings);
408
		this.javaProject = javaProject;
491
		this.javaProject = javaProject;
409
		this.requestor = requestor;
492
		this.requestor = requestor;
Lines 429-434 Link Here
429
				null/*taskPriorities*/,
512
				null/*taskPriorities*/,
430
				true/*taskCaseSensitive*/);
513
				true/*taskCaseSensitive*/);
431
		this.owner = owner;
514
		this.owner = owner;
515
		this.monitor = monitor;
516
	}
517
518
	/**
519
	 * One result of the search consists of a new package.
520
	 *
521
	 * NOTE - All package names are presented in their readable form:
522
	 *    Package names are in the form "a.b.c".
523
	 *    The default package is represented by an empty array.
524
	 */
525
	public void acceptPackage(char[] packageName) {
526
527
		if (this.knownPkgs.containsKey(packageName)) return;
528
529
		this.knownPkgs.put(packageName, this);
530
531
		char[] completion;
532
		if(this.resolvingImports) {
533
			if(this.resolvingStaticImports) {
534
				completion = CharOperation.concat(packageName, new char[] { '.' });
535
			} else {
536
				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
537
			}
538
		} else {
539
			completion = packageName;
540
		}
541
542
		int relevance = computeBaseRelevance();
543
		relevance += computeRelevanceForResolution();
544
		relevance += computeRelevanceForInterestingProposal();
545
		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
546
		if(!this.resolvingImports) {
547
			relevance += computeRelevanceForQualification(true);
548
		}
549
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
550
551
		this.noProposal = false;
552
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
553
			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
554
			proposal.setDeclarationSignature(packageName);
555
			proposal.setPackageName(packageName);
556
			proposal.setCompletion(completion);
557
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
558
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
559
			proposal.setRelevance(relevance);
560
			this.requestor.accept(proposal);
561
			if(DEBUG) {
562
				this.printDebug(proposal);
563
			}
564
		}
432
	}
565
	}
433
566
434
	/**
567
	/**
Lines 445-451 Link Here
445
		char[][] enclosingTypeNames,
578
		char[][] enclosingTypeNames,
446
		int modifiers,
579
		int modifiers,
447
		AccessRestriction accessRestriction) {
580
		AccessRestriction accessRestriction) {
448
581
		
582
		// does not check cancellation for every types to avoid performance loss
583
		if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
584
		this.foundTypesCount++;
585
		
449
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
586
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
450
587
451
		if (this.options.checkVisibility) {
588
		if (this.options.checkVisibility) {
Lines 489-555 Link Here
489
		if(length == 0) return;
626
		if(length == 0) return;
490
627
491
		HashtableOfObject onDemandFound = new HashtableOfObject();
628
		HashtableOfObject onDemandFound = new HashtableOfObject();
492
629
		
493
		next : for (int i = 0; i < length; i++) {
630
		try {
494
			AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
631
			next : for (int i = 0; i < length; i++) {
495
			char[] packageName = acceptedType.packageName;
632
				
496
			char[] simpleTypeName = acceptedType.simpleTypeName;
633
				// does not check cancellation for every types to avoid performance loss
497
			char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
634
				if ((i % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
498
			int modifiers = acceptedType.modifiers;
635
				
499
			int accessibility = acceptedType.accessibility;
636
				AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
500
637
				char[] packageName = acceptedType.packageName;
501
			char[] typeName;
638
				char[] simpleTypeName = acceptedType.simpleTypeName;
502
			char[] flatEnclosingTypeNames;
639
				char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
503
			if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
640
				int modifiers = acceptedType.modifiers;
504
				flatEnclosingTypeNames = null;
641
				int accessibility = acceptedType.accessibility;
505
				typeName = simpleTypeName;
642
	
506
			} else {
643
				char[] typeName;
507
				flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
644
				char[] flatEnclosingTypeNames;
508
				typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
645
				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
509
			}
646
					flatEnclosingTypeNames = null;
510
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
647
					typeName = simpleTypeName;
511
648
				} else {
512
			if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
649
					flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
513
650
					typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
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
				}
651
				}
520
652
				char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
521
				char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
653
	
522
654
				if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
523
				if(this.resolvingStaticImports) {
655
	
524
					if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
656
				this.knownTypes.put(fullyQualifiedName, this);
525
						completionName = CharOperation.concat(completionName, new char[] { '.' });
657
	
526
					} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
658
				if (this.resolvingImports) {
527
						continue next;
659
					if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
660
						continue next; // import of default package is forbidden when compliance is 1.4 or higher
661
					}
662
	
663
					char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
664
	
665
					if(this.resolvingStaticImports) {
666
						if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
667
							completionName = CharOperation.concat(completionName, new char[] { '.' });
668
						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
669
							continue next;
670
						} else {
671
							completionName = CharOperation.concat(completionName, new char[] { ';' });
672
						}
528
					} else {
673
					} else {
529
						completionName = CharOperation.concat(completionName, new char[] { ';' });
674
						completionName = CharOperation.concat(completionName, new char[] { ';' });
530
					}
675
					}
676
	
677
					int relevance = computeBaseRelevance();
678
					relevance += computeRelevanceForResolution();
679
					relevance += computeRelevanceForInterestingProposal();
680
					relevance += computeRelevanceForRestrictions(accessibility);
681
					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
682
	
683
					this.noProposal = false;
684
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
685
						createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
686
					}
531
				} else {
687
				} else {
532
					completionName = CharOperation.concat(completionName, new char[] { ';' });
688
					if(!this.importCachesInitialized) {
533
				}
689
						initializeImportCaches();
534
690
					}
535
				int relevance = computeBaseRelevance();
691
	
536
				relevance += computeRelevanceForResolution();
692
					for (int j = 0; j < this.importCacheCount; j++) {
537
				relevance += computeRelevanceForInterestingProposal();
693
						char[][] importName = this.importsCache[j];
538
				relevance += computeRelevanceForRestrictions(accessibility);
694
						if(CharOperation.equals(typeName, importName[0])) {
539
				relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
695
							proposeType(
540
696
									packageName,
541
				this.noProposal = false;
697
									simpleTypeName,
542
				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
698
									modifiers,
543
					createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
699
									accessibility,
544
				}
700
									typeName,
545
			} else {
701
									fullyQualifiedName,
546
				if(!this.importCachesInitialized) {
702
									!CharOperation.equals(fullyQualifiedName, importName[1]),
547
					initializeImportCaches();
703
									scope);
548
				}
704
							continue next;
549
705
						}
550
				for (int j = 0; j < this.importCacheCount; j++) {
706
					}
551
					char[][] importName = this.importsCache[j];
707
	
552
					if(CharOperation.equals(typeName, importName[0])) {
708
	
709
					if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
553
						proposeType(
710
						proposeType(
554
								packageName,
711
								packageName,
555
								simpleTypeName,
712
								simpleTypeName,
Lines 557-606 Link Here
557
								accessibility,
714
								accessibility,
558
								typeName,
715
								typeName,
559
								fullyQualifiedName,
716
								fullyQualifiedName,
560
								!CharOperation.equals(fullyQualifiedName, importName[1]),
717
								false,
561
								scope);
718
								scope);
562
						continue next;
719
						continue next;
563
					}
720
					} else {
564
				}
721
						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
565
722
	
566
723
						AcceptedType foundType = null;
567
				if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
724
						if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
568
					proposeType(
725
							for (int j = 0; j < this.onDemandImportCacheCount; j++) {
569
							packageName,
726
								ImportBinding importBinding = this.onDemandImportsCache[j];
570
							simpleTypeName,
727
	
571
							modifiers,
728
								char[][] importName = importBinding.compoundName;
572
							accessibility,
729
								char[] importFlatName = CharOperation.concatWith(importName, '.');
573
							typeName,
730
	
574
							fullyQualifiedName,
731
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
575
							false,
732
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
576
							scope);
733
										fullyQualifiedEnclosingTypeOrPackageName =
577
					continue next;
734
											CharOperation.concat(
578
				} else {
735
													packageName,
579
					char[] fullyQualifiedEnclosingTypeOrPackageName = null;
736
													flatEnclosingTypeNames,
580
737
													'.');
581
					AcceptedType foundType = null;
738
									} else {
582
					if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
739
										fullyQualifiedEnclosingTypeOrPackageName =
583
						for (int j = 0; j < this.onDemandImportCacheCount; j++) {
740
											packageName;
584
							ImportBinding importBinding = this.onDemandImportsCache[j];
741
									}
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
								}
742
								}
600
							}
743
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
601
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
744
									if(importBinding.isStatic()) {
602
								if(importBinding.isStatic()) {
745
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
603
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
746
											acceptedType.qualifiedTypeName = typeName;
747
											acceptedType.fullyQualifiedName = fullyQualifiedName;
748
											onDemandFound.put(
749
													simpleTypeName,
750
													acceptedType);
751
											continue next;
752
										}
753
									} else {
604
										acceptedType.qualifiedTypeName = typeName;
754
										acceptedType.qualifiedTypeName = typeName;
605
										acceptedType.fullyQualifiedName = fullyQualifiedName;
755
										acceptedType.fullyQualifiedName = fullyQualifiedName;
606
										onDemandFound.put(
756
										onDemandFound.put(
Lines 608-689 Link Here
608
												acceptedType);
758
												acceptedType);
609
										continue next;
759
										continue next;
610
									}
760
									}
611
								} else {
612
									acceptedType.qualifiedTypeName = typeName;
613
									acceptedType.fullyQualifiedName = fullyQualifiedName;
614
									onDemandFound.put(
615
											simpleTypeName,
616
											acceptedType);
617
									continue next;
618
								}
761
								}
619
							}
762
							}
620
						}
763
						} else if(!foundType.mustBeQualified){
621
					} else if(!foundType.mustBeQualified){
764
							done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
622
						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
765
								ImportBinding importBinding = this.onDemandImportsCache[j];
623
							ImportBinding importBinding = this.onDemandImportsCache[j];
766
	
624
767
								char[][] importName = importBinding.compoundName;
625
							char[][] importName = importBinding.compoundName;
768
								char[] importFlatName = CharOperation.concatWith(importName, '.');
626
							char[] importFlatName = CharOperation.concatWith(importName, '.');
769
	
627
770
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
628
							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
771
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
629
								if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
772
										fullyQualifiedEnclosingTypeOrPackageName =
630
									fullyQualifiedEnclosingTypeOrPackageName =
773
											CharOperation.concat(
631
										CharOperation.concat(
774
													packageName,
632
												packageName,
775
													flatEnclosingTypeNames,
633
												flatEnclosingTypeNames,
776
													'.');
634
												'.');
777
									} else {
635
								} else {
778
										fullyQualifiedEnclosingTypeOrPackageName =
636
									fullyQualifiedEnclosingTypeOrPackageName =
779
											packageName;
637
										packageName;
780
									}
638
								}
781
								}
639
							}
782
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
640
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
783
									if(importBinding.isStatic()) {
641
								if(importBinding.isStatic()) {
784
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
642
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
785
											foundType.mustBeQualified = true;
786
											break done;
787
										}
788
									} else {
643
										foundType.mustBeQualified = true;
789
										foundType.mustBeQualified = true;
644
										break done;
790
										break done;
645
									}
791
									}
646
								} else {
647
									foundType.mustBeQualified = true;
648
									break done;
649
								}
792
								}
650
							}
793
							}
651
						}
794
						}
795
						proposeType(
796
								packageName,
797
								simpleTypeName,
798
								modifiers,
799
								accessibility,
800
								typeName,
801
								fullyQualifiedName,
802
								true,
803
								scope);
652
					}
804
					}
653
					proposeType(
654
							packageName,
655
							simpleTypeName,
656
							modifiers,
657
							accessibility,
658
							typeName,
659
							fullyQualifiedName,
660
							true,
661
							scope);
662
				}
805
				}
663
			}
806
			}
664
		}
807
		
665
		char[][] keys = onDemandFound.keyTable;
808
			char[][] keys = onDemandFound.keyTable;
666
		Object[] values = onDemandFound.valueTable;
809
			Object[] values = onDemandFound.valueTable;
667
		int max = keys.length;
810
			int max = keys.length;
668
		for (int i = 0; i < max; i++) {
811
			for (int i = 0; i < max; i++) {
669
			if(keys[i] != null) {
812
				if(keys[i] != null) {
670
				AcceptedType value = (AcceptedType) values[i];
813
					AcceptedType value = (AcceptedType) values[i];
671
				if(value != null) {
814
					if(value != null) {
672
					proposeType(
815
						proposeType(
673
							value.packageName,
816
								value.packageName,
674
							value.simpleTypeName,
817
								value.simpleTypeName,
675
							value.modifiers,
818
								value.modifiers,
676
							value.accessibility,
819
								value.accessibility,
677
							value.qualifiedTypeName,
820
								value.qualifiedTypeName,
678
							value.fullyQualifiedName,
821
								value.fullyQualifiedName,
679
							value.mustBeQualified,
822
								value.mustBeQualified,
680
							scope);
823
								scope);
824
					}
681
				}
825
				}
682
			}
826
			}
827
		} finally {
828
			this.acceptedTypes = null; // reset
683
		}
829
		}
684
		this.acceptedTypes = null; // reset
685
	}
830
	}
686
831
	
687
	public void acceptUnresolvedName(char[] name) {
832
	public void acceptUnresolvedName(char[] name) {
688
		int relevance = computeBaseRelevance();
833
		int relevance = computeBaseRelevance();
689
		relevance += computeRelevanceForResolution(false);
834
		relevance += computeRelevanceForResolution(false);
Lines 709-714 Link Here
709
			}
854
			}
710
		}
855
		}
711
	}
856
	}
857
	private void addExpectedType(TypeBinding type, Scope scope){
858
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
859
860
		// do not add twice the same type
861
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
862
			if (this.expectedTypes[i] == type) return;
863
		}
864
865
		int length = this.expectedTypes.length;
866
		if (++this.expectedTypesPtr >= length)
867
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
868
		this.expectedTypes[this.expectedTypesPtr] = type;
869
870
		if(type == scope.getJavaLangObject()) {
871
			this.hasJavaLangObjectAsExpectedType = true;
872
		}
873
	}
874
875
	private void addForbiddenBindings(Binding binding){
876
		if (binding == null) return;
877
878
		int length = this.forbbidenBindings.length;
879
		if (++this.forbbidenBindingsPtr >= length)
880
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
881
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
882
	}
883
884
	private void addUninterestingBindings(Binding binding){
885
		if (binding == null) return;
886
887
		int length = this.uninterestingBindings.length;
888
		if (++this.uninterestingBindingsPtr >= length)
889
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
890
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
891
	}
712
892
713
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
893
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
714
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
894
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
Lines 741-867 Link Here
741
		return true;
921
		return true;
742
	}
922
	}
743
923
744
	private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope) {
745
		char[] completionName = fullyQualifiedName;
746
		if(isQualified) {
747
			if (packageName == null || packageName.length == 0)
748
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
749
					return; // ignore types from the default package from outside it
750
		} else {
751
			completionName = simpleTypeName;
752
		}
753
754
		TypeBinding guessedType = null;
755
		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
756
				this.assistNodeIsAnnotation &&
757
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
758
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
759
760
			TypeReference ref;
761
			if (cn.length == 1) {
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
			}
776
777
			if (guessedType == null || !guessedType.isValidBinding()) return;
778
779
			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
780
		}
781
782
		int relevance = computeBaseRelevance();
783
		relevance += computeRelevanceForResolution();
784
		relevance += computeRelevanceForInterestingProposal();
785
		relevance += computeRelevanceForRestrictions(accessibility);
786
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
787
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
788
		relevance += computeRelevanceForQualification(isQualified);
789
790
		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
791
		switch (kind) {
792
			case ClassFileConstants.AccAnnotation:
793
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
794
				relevance += computeRelevanceForAnnotation();
795
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
796
				relevance += computeRelevanceForInterface();
797
				break;
798
			case ClassFileConstants.AccEnum:
799
				relevance += computeRelevanceForEnum();
800
				break;
801
			case ClassFileConstants.AccInterface:
802
				relevance += computeRelevanceForInterface();
803
				break;
804
			default:
805
				relevance += computeRelevanceForClass();
806
				relevance += computeRelevanceForException(simpleTypeName);
807
				break;
808
		}
809
810
		this.noProposal = false;
811
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
812
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
813
		}
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(
924
	private void buildContext(
866
			ASTNode astNode,
925
			ASTNode astNode,
867
			ASTNode astNodeParent,
926
			ASTNode astNodeParent,
Lines 991-996 Link Here
991
		}
1050
		}
992
	}
1051
	}
993
1052
1053
	private void checkCancel() {
1054
		if (this.monitor != null && this.monitor.isCanceled()) {
1055
			throw new OperationCanceledException();
1056
		}
1057
	}
1058
994
	private boolean complete(
1059
	private boolean complete(
995
			ASTNode astNode,
1060
			ASTNode astNode,
996
			ASTNode astNodeParent,
1061
			ASTNode astNodeParent,
Lines 1012-1512 Link Here
1012
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1077
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1013
1078
1014
		if (astNode instanceof CompletionOnFieldType) {
1079
		if (astNode instanceof CompletionOnFieldType) {
1015
1080
			completionOnFieldType(astNode, scope);
1016
			CompletionOnFieldType field = (CompletionOnFieldType) astNode;
1017
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
1018
			this.completionToken = type.token;
1019
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1020
1021
			findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
1022
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1023
				findKeywordsForMember(this.completionToken, field.modifiers);
1024
			}
1025
1026
			if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
1027
				SourceTypeBinding enclosingType = scope.enclosingSourceType();
1028
				if (!enclosingType.isAnnotationType()) {
1029
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1030
						findMethods(
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
				}
1057
			}
1058
		} else if (astNode instanceof CompletionOnMethodReturnType) {
1081
		} else if (astNode instanceof CompletionOnMethodReturnType) {
1059
1082
			completionOnMethodReturnType(astNode, scope);
1060
			CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
1083
		} else if (astNode instanceof CompletionOnSingleNameReference) {
1061
			SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
1084
			completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
1062
			this.completionToken = type.token;
1085
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1063
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1086
			completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1064
			findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
1087
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
1065
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1088
			completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1066
				findKeywordsForMember(this.completionToken, method.modifiers);
1089
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1090
			completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1091
		} else if (astNode instanceof CompletionOnMemberAccess) {
1092
			completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1093
		} else if (astNode instanceof CompletionOnMessageSend) {
1094
			completionOnMessageSend(astNode, qualifiedBinding, scope);
1095
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1096
			completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
1097
		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
1098
			completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
1099
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1100
			completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
1101
		} else if (astNode instanceof CompletionOnMethodName) {
1102
			completionOnMethodName(astNode, scope);
1103
		} else if (astNode instanceof CompletionOnFieldName) {
1104
			completionOnFieldName(astNode, scope);
1105
		} else if (astNode instanceof CompletionOnLocalName) {
1106
			completionOnLocalOrArgumentName(astNode, scope);
1107
		} else if (astNode instanceof CompletionOnArgumentName) {
1108
			completionOnLocalOrArgumentName(astNode, scope);
1109
		} else if (astNode instanceof CompletionOnKeyword) {
1110
			completionOnKeyword(astNode);
1111
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1112
			completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1113
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1114
			completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
1115
		} else if (astNode instanceof CompletionOnMemberValueName) {
1116
			completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
1117
		} else if(astNode instanceof CompletionOnBranchStatementLabel) {
1118
			completionOnBranchStatementLabel(astNode);
1119
		} else if(astNode instanceof CompletionOnMessageSendName) {
1120
			completionOnMessageSendName(astNode, qualifiedBinding, scope);
1121
		// Completion on Javadoc nodes
1122
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
1123
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
1124
				completionOnJavadocSingleTypeReference(astNode, scope);
1125
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
1126
				completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
1127
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
1128
				completionOnJavadocFieldReference(astNode, scope);
1129
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
1130
				completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
1131
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
1132
				completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
1133
			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
1134
				completionOnJavadocParamNameReference(astNode);
1135
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
1136
				completionOnJavadocTypeParamReference(astNode);
1137
			} else if (astNode instanceof CompletionOnJavadocTag) {
1138
				completionOnJavadocTag(astNode);
1067
			}
1139
			}
1140
		}
1141
		return true;
1142
	}
1068
1143
1069
			if (method.modifiers == ClassFileConstants.AccDefault) {
1144
	/**
1070
				SourceTypeBinding enclosingType = scope.enclosingSourceType();
1145
	 * Ask the engine to compute a completion at the specified position
1071
				if (!enclosingType.isAnnotationType()) {
1146
	 * of the given compilation unit.
1072
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1147
	 *
1073
						findMethods(
1148
	 *  No return
1074
								this.completionToken,
1149
	 *      completion results are answered through a requestor.
1075
								null,null,
1150
	 *
1076
								scope.enclosingSourceType(),
1151
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
1077
								scope,
1152
	 *      the source of the current compilation unit.
1078
								new ObjectVector(),
1153
	 *
1079
								false,
1154
	 *  @param completionPosition int
1080
								false,
1155
	 *      a position in the source where the completion is taking place.
1081
								true,
1156
	 *      This position is relative to the source provided.
1082
								null,
1157
	 */
1083
								null,
1158
	public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
1084
								false,
1085
								false,
1086
								true,
1087
								null,
1088
								null,
1089
								null,
1090
								false,
1091
								null,
1092
								-1,
1093
								-1);
1094
					}
1095
					if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1096
						proposeNewMethod(this.completionToken, scope.enclosingSourceType());
1097
					}
1098
				}
1099
			}
1100
		} else if (astNode instanceof CompletionOnSingleNameReference) {
1101
1159
1102
			CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
1160
		if(DEBUG) {
1103
			this.completionToken = singleNameReference.token;
1161
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
1104
			SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
1162
			System.out.print(sourceUnit.getFileName());
1105
			if (switchStatement != null
1163
			System.out.print(" AT POSITION "); //$NON-NLS-1$
1106
					&& switchStatement.expression.resolvedType != null
1164
			System.out.println(completionPosition);
1107
					&& switchStatement.expression.resolvedType.isEnum()) {
1165
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
1108
				if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1166
			System.out.println(sourceUnit.getContents());
1109
					this.assistNodeIsEnum = true;
1167
		}
1110
					findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
1168
		if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
1111
				}
1169
		this.requestor.beginReporting();
1112
			} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1170
		boolean contextAccepted = false;
1113
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1171
		try {
1114
			} else {
1172
			this.fileName = sourceUnit.getFileName();
1115
				if (this.expectedTypesPtr > -1) {
1173
			this.actualCompletionPosition = completionPosition - 1;
1116
					this.assistNodeIsEnum = true;
1174
			this.offset = pos;
1117
					done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1175
			this.typeRoot = root;
1118
						if (!this.expectedTypes[i].isEnum()) {
1176
			
1119
							this.assistNodeIsEnum = false;
1177
			this.checkCancel();
1120
							break done;
1178
			
1121
						}
1179
			// for now until we can change the UI.
1122
					}
1180
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1181
			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
1123
1182
1183
			//		boolean completionNodeFound = false;
1184
			if (parsedUnit != null) {
1185
				if(DEBUG) {
1186
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
1187
					System.out.println(parsedUnit.toString());
1124
				}
1188
				}
1125
				if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1126
					char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
1127
1189
1128
					findUnresolvedReference(
1190
				// scan the package & import statements first
1129
							singleNameReference.sourceStart,
1191
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
1130
							singleNameReference.sourceEnd,
1192
					contextAccepted = true;
1131
							(BlockScope)scope,
1193
					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
1132
							alreadyDefinedName);
1194
					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
1133
				}
1195
						findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
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
					}
1196
					}
1149
				}
1197
					if(this.noProposal && this.problem != null) {
1150
				if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
1198
						this.requestor.completionFailure(this.problem);
1151
					if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
1199
						if(DEBUG) {
1152
						ReferenceBinding ref = scope.enclosingSourceType();
1200
							this.printDebug(this.problem);
1153
						findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
1201
						}
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
					}
1202
					}
1203
					return;
1158
				}
1204
				}
1159
			}
1160
1161
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1162
1205
1163
			CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
1206
				ImportReference[] imports = parsedUnit.imports;
1164
1207
				if (imports != null) {
1165
			this.completionToken = singleRef.token;
1208
					for (int i = 0, length = imports.length; i < length; i++) {
1166
1209
						ImportReference importReference = imports[i];
1167
			this.assistNodeIsClass = singleRef.isClass();
1210
						if (importReference instanceof CompletionOnImportReference) {
1168
			this.assistNodeIsException = singleRef.isException();
1211
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1169
			this.assistNodeIsInterface = singleRef.isInterface();
1212
							if ((this.unitScope = parsedUnit.scope) != null) {
1170
			this.assistNodeIsConstructor = singleRef.isConstructorType;
1213
								contextAccepted = true;
1171
			this.assistNodeIsSuperType = singleRef.isSuperType();
1214
								buildContext(importReference, null, parsedUnit, null, null);
1172
1173
			// can be the start of a qualified type name
1174
			if (qualifiedBinding == null) {
1175
				if (this.completionToken.length == 0 &&
1176
						(astNodeParent instanceof ParameterizedSingleTypeReference ||
1177
								astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
1178
					this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
1179
1215
1180
					findParameterizedType((TypeReference)astNodeParent, scope);
1216
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
1181
				} else {
1217
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
1182
					ObjectVector typesFound = new ObjectVector();
1183
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1184
						findExceptionFromTryStatement(
1185
								this.completionToken,
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
1218
1213
			this.insideQualifiedReference = true;
1219
								char[][] oldTokens = importReference.tokens;
1214
			CompletionOnQualifiedNameReference ref =
1220
								int tokenCount = oldTokens.length;
1215
				(CompletionOnQualifiedNameReference) astNode;
1221
								if (tokenCount == 1) {
1216
			this.completionToken = ref.completionIdentifier;
1222
									findImports((CompletionOnImportReference)importReference, true);
1217
			long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
1223
								} else if(tokenCount > 1){
1224
									this.insideQualifiedReference = true;
1218
1225
1219
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1226
									char[] lastToken = oldTokens[tokenCount - 1];
1220
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1227
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
1221
				// complete field members with missing fields type
1222
				// class X {
1223
				//   Missing f;
1224
				//   void foo() {
1225
				//     f.|
1226
				//   }
1227
				// }
1228
				if (this.assistNodeInJavadoc == 0 &&
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
1228
1235
						if (!foundSomeFields) {
1229
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
1236
							findMembersFromMissingType(
1230
									if(binding != null) {
1237
									ref.tokens[0],
1231
										if(binding instanceof PackageBinding) {
1238
									ref.sourcePositions[0],
1232
											findImports((CompletionOnImportReference)importReference, false);
1239
									null,
1233
										} else {
1240
									scope,
1234
											ReferenceBinding ref = (ReferenceBinding) binding;
1241
									ref,
1242
									ref.isInsideAnnotationAttribute);
1243
						}
1244
					}
1245
				}
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
1235
1253
					findFieldsAndMethods(
1236
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1254
							this.completionToken,
1237
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
1255
							receiverType.capture(scope, ref.sourceEnd),
1238
											}
1256
							scope,
1239
											if(importReference.isStatic()) {
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
1240
1271
					findFieldsAndMethodsFromCastedReceiver(
1241
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1272
							enclosingNode,
1242
													findImportsOfStaticFields(lastToken, ref);
1273
							qualifiedBinding,
1243
												}
1274
							scope,
1244
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
1275
							fieldsFound,
1245
													findImportsOfStaticMethods(lastToken, ref);
1276
							methodsFound,
1246
												}
1277
							ref,
1247
											}
1278
							scope,
1248
										}
1279
							ref);
1249
									}
1250
								}
1280
1251
1281
				} else if (this.assistNodeInJavadoc == 0 &&
1252
								if(this.noProposal && this.problem != null) {
1282
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1253
									this.requestor.completionFailure(this.problem);
1283
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1254
									if(DEBUG) {
1284
					boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
1255
										this.printDebug(this.problem);
1285
					boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
1256
									}
1286
					if (proposeField || proposeMethod) {
1257
								}
1287
						if(ref.tokens.length == 1) {
1288
							if (qualifiedBinding instanceof LocalVariableBinding) {
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
							}
1258
							}
1312
1259
							return;
1260
						} else if(importReference instanceof CompletionOnKeyword) {
1261
							contextAccepted = true;
1262
							buildContext(importReference, null, parsedUnit, null, null);
1263
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1264
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
1265
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
1266
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
1267
							}
1268
							if(this.noProposal && this.problem != null) {
1269
								this.requestor.completionFailure(this.problem);
1270
								if(DEBUG) {
1271
									this.printDebug(this.problem);
1272
								}
1273
							}
1274
							return;
1313
						}
1275
						}
1314
					}
1276
					}
1315
				}
1277
				}
1316
1278
1317
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1279
				if (parsedUnit.types != null) {
1318
				boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
1280
					try {
1319
				ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
1281
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1320
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1321
1282
1322
				findMembers(
1283
						if ((this.unitScope = parsedUnit.scope) != null) {
1323
						this.completionToken,
1284
							this.source = sourceUnit.getContents();
1324
						receiverType,
1285
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
1325
						scope,
1286
							parsedUnit.scope.faultInTypes();
1326
						ref,
1287
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
1327
						isInsideAnnotationAttribute,
1288
							if(DEBUG) {
1328
						null,
1289
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
1329
						null,
1290
								System.out.println(parsedUnit.toString());
1330
						null,
1291
							}
1331
						false);
1292
							parsedUnit.resolve();
1332
1293
						}
1333
			} else if (qualifiedBinding instanceof PackageBinding) {
1294
					} catch (CompletionNodeFound e) {
1334
1295
						//					completionNodeFound = true;
1335
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1296
						if (e.astNode != null) {
1336
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1297
							// if null then we found a problem in the completion node
1298
							if(DEBUG) {
1299
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
1300
								System.out.println(e.astNode.toString());
1301
								if(this.parser.assistNodeParent != null) {
1302
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
1303
									System.out.println(this.parser.assistNodeParent);
1304
								}
1305
							}
1306
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
1307
							contextAccepted =
1308
								complete(
1309
									e.astNode,
1310
									this.parser.assistNodeParent,
1311
									this.parser.enclosingNode,
1312
									parsedUnit,
1313
									e.qualifiedBinding,
1314
									e.scope,
1315
									e.insideTypeAnnotation);
1316
						}
1317
					}
1318
				}
1319
			}
1337
1320
1338
				// replace to the end of the completion identifier
1321
			if(this.noProposal && this.problem != null) {
1339
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1322
				if(!contextAccepted) {
1323
					contextAccepted = true;
1324
					InternalCompletionContext context = new InternalCompletionContext();
1325
					context.setOffset(completionPosition - this.offset);
1326
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1327
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
1328
					this.requestor.acceptContext(context);
1329
				}
1330
				this.requestor.completionFailure(this.problem);
1331
				if(DEBUG) {
1332
					this.printDebug(this.problem);
1333
				}
1340
			}
1334
			}
1341
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1335
			/* Ignore package, import, class & interface keywords for now...
1336
					if (!completionNodeFound) {
1337
						if (parsedUnit == null || parsedUnit.types == null) {
1338
							// this is not good enough... can still be trying to define a second type
1339
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
1340
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
1341
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
1342
						}
1343
						// currently have no way to know if extends/implements are possible keywords
1344
					}
1345
			*/
1346
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
1347
			if(DEBUG) {
1348
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1349
				e.printStackTrace(System.out);
1350
			}
1351
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
1352
			if(DEBUG) {
1353
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1354
				e.printStackTrace(System.out);
1355
			}
1356
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
1357
			if(DEBUG) {
1358
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1359
				e.printStackTrace(System.out);
1360
			}
1361
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
1362
			if(DEBUG) {
1363
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1364
				e.printStackTrace(System.out);
1365
			}
1366
		} finally {
1367
			if(!contextAccepted) {
1368
				contextAccepted = true;
1369
				InternalCompletionContext context = new InternalCompletionContext();
1370
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1371
				context.setOffset(completionPosition - this.offset);
1372
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
1373
				this.requestor.acceptContext(context);
1374
			}
1375
			this.requestor.endReporting();
1376
			if (this.monitor != null) this.monitor.done();
1377
			reset();
1378
		}
1379
	}
1342
1380
1343
			this.insideQualifiedReference = true;
1381
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
1382
		if(this.requestor != null){
1383
			this.requestor.beginReporting();
1384
		}
1385
		boolean contextAccepted = false;
1386
		IType topLevelType = type;
1387
		while(topLevelType.getDeclaringType() != null) {
1388
			topLevelType = topLevelType.getDeclaringType();
1389
		}
1344
1390
1345
			CompletionOnQualifiedTypeReference ref =
1391
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
1346
				(CompletionOnQualifiedTypeReference) astNode;
1392
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1347
1393
1348
			this.assistNodeIsClass = ref.isClass();
1394
		CompilationUnitDeclaration compilationUnit = null;
1349
			this.assistNodeIsException = ref.isException();
1350
			this.assistNodeIsInterface = ref.isInterface();
1351
			this.assistNodeIsSuperType = ref.isSuperType();
1352
1395
1353
			this.completionToken = ref.completionIdentifier;
1396
		try {
1354
			long completionPosition = ref.sourcePositions[ref.tokens.length];
1397
			// TypeConverter is used instead of SourceTypeConverter because the type
1398
			// to convert can be a binary type or a source type
1399
			TypeDeclaration typeDeclaration = null;
1400
			if (type instanceof SourceType) {
1401
				SourceType sourceType = (SourceType) type;
1402
				ISourceType info = (ISourceType) sourceType.getElementInfo();
1403
				compilationUnit = SourceTypeConverter.buildCompilationUnit(
1404
					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
1405
					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
1406
					| SourceTypeConverter.MEMBER_TYPE, // need member types
1407
					// no need for field initialization
1408
					this.problemReporter,
1409
					compilationResult);
1410
				if (compilationUnit.types != null)
1411
					typeDeclaration = compilationUnit.types[0];
1412
			} else {
1413
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
1414
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
1415
			}
1355
1416
1356
			// get the source positions of the completion identifier
1417
			if(typeDeclaration != null) {
1357
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1418
				// build AST from snippet
1358
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1419
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
1359
				if (this.assistNodeInJavadoc == 0 &&
1360
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1361
					if(ref.tokens.length == 1) {
1362
						findMemberTypesFromMissingType(
1363
								ref.tokens[0],
1364
								ref.sourcePositions[0],
1365
								scope);
1366
					}
1367
				}
1368
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1369
				if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1370
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
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
1420
1383
					findMemberTypes(
1421
				// merge AST
1384
						this.completionToken,
1422
				FieldDeclaration[] oldFields = typeDeclaration.fields;
1385
						(ReferenceBinding) qualifiedBinding,
1423
				FieldDeclaration[] newFields = null;
1386
						scope,
1424
				if (oldFields != null) {
1387
						scope.enclosingSourceType(),
1425
					newFields = new FieldDeclaration[oldFields.length + 1];
1388
						false,
1426
					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
1389
						false,
1427
					newFields[oldFields.length] = fakeInitializer;
1390
						typesFound,
1428
				} else {
1391
						null,
1429
					newFields = new FieldDeclaration[] {fakeInitializer};
1392
						null,
1393
						null,
1394
						false);
1395
				}
1430
				}
1396
			} else if (qualifiedBinding instanceof PackageBinding) {
1431
				typeDeclaration.fields = newFields;
1397
1432
1398
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1433
				if(DEBUG) {
1399
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1434
					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
1400
				// replace to the end of the completion identifier
1435
					System.out.println(compilationUnit.toString());
1401
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1436
				}
1402
			}
1403
		} else if (astNode instanceof CompletionOnMemberAccess) {
1404
			this.insideQualifiedReference = true;
1405
			CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1406
			long completionPosition = access.nameSourcePosition;
1407
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1408
1437
1409
			this.completionToken = access.token;
1438
				if (compilationUnit.types != null) {
1439
					try {
1440
						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
1410
1441
1411
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1442
						if ((this.unitScope = compilationUnit.scope) != null) {
1412
				// complete method members with missing return type
1443
							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
1413
				// class X {
1444
							compilationUnit.scope.faultInTypes();
1414
				//   Missing f() {return null;}
1445
							compilationUnit.resolve();
1415
				//   void foo() {
1446
						}
1416
				//     f().|
1447
					} catch (CompletionNodeFound e) {
1417
				//   }
1448
						//					completionNodeFound = true;
1418
				// }
1449
						if (e.astNode != null) {
1419
				if (this.assistNodeInJavadoc == 0 &&
1450
							// if null then we found a problem in the completion node
1420
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1451
							contextAccepted =
1421
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1452
								complete(
1422
					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1453
									e.astNode,
1423
					findFieldsAndMethodsFromMissingReturnType(
1454
									this.parser.assistNodeParent,
1424
							problemMethodBinding.selector,
1455
									this.parser.enclosingNode,
1425
							problemMethodBinding.parameters,
1456
									compilationUnit,
1426
							scope,
1457
									e.qualifiedBinding,
1427
							access,
1458
									e.scope,
1428
							insideTypeAnnotation);
1459
									e.insideTypeAnnotation);
1460
						}
1461
					}
1429
				}
1462
				}
1430
			} else {
1463
				if(this.noProposal && this.problem != null) {
1431
				if (!access.isInsideAnnotation) {
1464
					if(!contextAccepted) {
1432
					if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1465
						contextAccepted = true;
1433
						findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
1466
						InternalCompletionContext context = new InternalCompletionContext();
1467
						if (this.requestor.isExtendedContextRequired()) context.setExtended();
1468
						this.requestor.acceptContext(context);
1434
					}
1469
					}
1435
1470
					this.requestor.completionFailure(this.problem);
1436
					ObjectVector fieldsFound = new ObjectVector();
1471
					if(DEBUG) {
1437
					ObjectVector methodsFound = new ObjectVector();
1472
						this.printDebug(this.problem);
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
					}
1473
					}
1470
				}
1474
				}
1471
			}
1475
			}
1472
1476
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
1473
		} else if (astNode instanceof CompletionOnMessageSend) {
1477
			if(DEBUG) {
1478
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1479
				e.printStackTrace(System.out);
1480
			}
1481
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
1482
			if(DEBUG) {
1483
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1484
				e.printStackTrace(System.out);
1485
			}
1486
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
1487
			if(DEBUG) {
1488
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1489
				e.printStackTrace(System.out);
1490
			}
1491
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
1492
			if(DEBUG) {
1493
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1494
				e.printStackTrace(System.out);
1495
			}
1496
		} catch(JavaModelException e) {
1497
			// Do nothing
1498
		}
1499
		if(!contextAccepted) {
1500
			contextAccepted = true;
1501
			InternalCompletionContext context = new InternalCompletionContext();
1502
			if (this.requestor.isExtendedContextRequired()) context.setExtended();
1503
			this.requestor.acceptContext(context);
1504
		}
1505
		if(this.requestor != null){
1506
			this.requestor.endReporting();
1507
		}
1508
	}
1509
	
1510
	private void completionOnBranchStatementLabel(ASTNode astNode) {
1511
		if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1512
			CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
1513
			this.completionToken = label.label;
1514
			findLabels(this.completionToken, label.possibleLabels);
1515
		}
1516
	}
1517
	
1518
	private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1519
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1520
			CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1521
			setSourceAndTokenRange(access.classStart, access.sourceEnd);
1522
			this.completionToken = access.completionIdentifier;
1523
			findClassField(
1524
					this.completionToken,
1525
					(TypeBinding) qualifiedBinding,
1526
					scope,
1527
					null,
1528
					null,
1529
					null,
1530
					false);
1531
		}
1532
	}
1533
	
1534
	private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1535
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1474
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1536
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1537
			CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
1538
			TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1539
			findConstructors(
1540
				(ReferenceBinding) qualifiedBinding,
1541
				argTypes,
1542
				scope,
1543
				constructorCall,
1544
				false);
1545
		}
1546
	}
1547
	
1548
	private void completionOnFieldName(ASTNode astNode, Scope scope) {
1549
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1550
			CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1475
1551
1476
			CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1552
			FieldBinding[] fields = scope.enclosingSourceType().fields();
1477
			TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1553
			char[][] excludeNames = new char[fields.length][];
1478
			this.completionToken = messageSend.selector;
1554
			for(int i = 0 ; i < fields.length ; i++){
1479
			if (qualifiedBinding == null) {
1555
				excludeNames[i] = fields[i].name;
1480
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1556
			}
1481
					ObjectVector methodsFound = new ObjectVector();
1482
1557
1483
					findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
1558
			this.completionToken = field.realName;
1484
1559
1485
					findLocalMethodsFromStaticImports(
1560
			findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1561
		}
1562
	}
1563
	
1564
	private void completionOnFieldType(ASTNode astNode, Scope scope) {
1565
		CompletionOnFieldType field = (CompletionOnFieldType) astNode;
1566
		CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
1567
		this.completionToken = type.token;
1568
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1569
1570
		findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
1571
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1572
			findKeywordsForMember(this.completionToken, field.modifiers);
1573
		}
1574
1575
		if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
1576
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
1577
			if (!enclosingType.isAnnotationType()) {
1578
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1579
					findMethodDeclarations(
1486
							this.completionToken,
1580
							this.completionToken,
1581
							enclosingType,
1487
							scope,
1582
							scope,
1488
							messageSend,
1583
							new ObjectVector(),
1489
							scope,
1584
							null,
1490
							true,
1585
							null,
1491
							methodsFound,
1586
							null,
1492
							true);
1587
							false);
1588
				}
1589
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1590
					proposeNewMethod(this.completionToken, enclosingType);
1591
				}
1592
			}
1593
		}
1594
	}
1595
	//TODO
1596
	private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1597
		// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1598
		
1599
		CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
1600
		this.javadocTagPosition = allocExpression.tagSourceStart;
1601
		int rangeStart = astNode.sourceStart;
1602
		if (allocExpression.type.isThis()) {
1603
			if (allocExpression.completeInText()) {
1604
				rangeStart = allocExpression.separatorPosition;
1605
			}
1606
		} else if (allocExpression.completeInText()) {
1607
			rangeStart = allocExpression.type.sourceStart;
1608
		}
1609
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1610
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1611
1612
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1613
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
1614
			findConstructors(ref, argTypes, scope, allocExpression, false);
1615
		}
1616
	}
1617
	//TODO
1618
	private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
1619
		this.insideQualifiedReference = true;
1620
		CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1621
		this.completionToken = fieldRef.token;
1622
		long completionPosition = fieldRef.nameSourcePosition;
1623
		this.javadocTagPosition = fieldRef.tagSourceStart;
1624
1625
		if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1626
				ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1627
			int rangeStart = (int) (completionPosition >>> 32);
1628
			if (fieldRef.receiver.isThis()) {
1629
				if (fieldRef.completeInText()) {
1630
					rangeStart = fieldRef.separatorPosition;
1493
				}
1631
				}
1494
			} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1632
			} else if (fieldRef.completeInText()) {
1633
				rangeStart = fieldRef.receiver.sourceStart;
1634
			}
1635
			setSourceAndTokenRange(rangeStart, (int) completionPosition);
1636
1637
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1638
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1639
				findFields(this.completionToken,
1640
					receiverType,
1641
					scope,
1642
					new ObjectVector(),
1643
					new ObjectVector(),
1644
					false, /*not only static */
1645
					fieldRef,
1646
					scope,
1647
					false,
1648
					true,
1649
					null,
1650
					null,
1651
					null,
1652
					false,
1653
					null,
1654
					-1,
1655
					-1);
1656
			}
1657
1658
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1659
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
1495
				findMethods(
1660
				findMethods(
1496
					this.completionToken,
1661
					this.completionToken,
1497
					null,
1662
					null,
1498
					argTypes,
1663
					null,
1499
					(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1664
					receiverType,
1500
					scope,
1665
					scope,
1501
					new ObjectVector(),
1666
					new ObjectVector(),
1667
					false, /*not only static */
1502
					false,
1668
					false,
1503
					true,
1669
					fieldRef,
1504
					false,
1505
					messageSend,
1506
					scope,
1670
					scope,
1507
					false,
1671
					false,
1508
					messageSend.receiver instanceof SuperReference,
1509
					false,
1672
					false,
1673
					true,
1510
					null,
1674
					null,
1511
					null,
1675
					null,
1512
					null,
1676
					null,
Lines 1514-1956 Link Here
1514
					null,
1678
					null,
1515
					-1,
1679
					-1,
1516
					-1);
1680
					-1);
1681
				if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
1682
					ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
1683
					if (this.completionToken == null
1684
							|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1685
							|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1686
						findConstructors(refBinding, null, scope, fieldRef, false);
1687
					}
1688
				}
1517
			}
1689
			}
1518
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1690
		}
1519
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1691
	}
1520
				setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1692
	//TODO
1521
1693
	private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1522
				CompletionOnExplicitConstructorCall constructorCall =
1694
		CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
1523
					(CompletionOnExplicitConstructorCall) astNode;
1695
		TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
1524
				TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1696
		this.completionToken = messageSend.selector;
1525
				findConstructors(
1697
		this.javadocTagPosition = messageSend.tagSourceStart;
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
1698
1535
			CompletionOnQualifiedAllocationExpression allocExpression =
1699
		// Set source range
1536
				(CompletionOnQualifiedAllocationExpression) astNode;
1700
		int rangeStart = astNode.sourceStart;
1537
			TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1701
		if (messageSend.receiver.isThis()) {
1702
			if (messageSend.completeInText()) {
1703
				rangeStart = messageSend.separatorPosition;
1704
			}
1705
		} else if (messageSend.completeInText()) {
1706
			rangeStart = messageSend.receiver.sourceStart;
1707
		}
1708
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1538
1709
1539
			ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1710
		if (qualifiedBinding == null) {
1540
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1711
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1541
					&& ref.isClass()
1712
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
1542
					&& !ref.isAbstract()) {
1543
					findConstructors(
1544
						ref,
1545
						argTypes,
1546
						scope,
1547
						allocExpression,
1548
						false);
1549
			}
1713
			}
1550
			if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
1714
		} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1551
					&& !ref.isFinal()
1715
			findMethods(
1552
					&& !ref.isEnum()){
1716
				this.completionToken,
1553
				findAnonymousType(
1717
				null,
1554
					ref,
1718
				argTypes,
1555
					argTypes,
1719
				(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1720
				scope,
1721
				new ObjectVector(),
1722
				false,
1723
				false/* prefix match */,
1724
				messageSend,
1725
				scope,
1726
				false,
1727
				messageSend.receiver instanceof SuperReference,
1728
				true,
1729
				null,
1730
				null,
1731
				null,
1732
				false,
1733
				null,
1734
				-1,
1735
				-1);
1736
		}
1737
	}
1738
	//TODO
1739
	private void completionOnJavadocParamNameReference(ASTNode astNode) {
1740
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1741
			CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
1742
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1743
			findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
1744
			findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
1745
		}
1746
	}
1747
	//TODO
1748
	private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1749
		this.insideQualifiedReference = true;
1750
1751
		CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
1752
		this.completionToken = typeRef.completionIdentifier;
1753
		long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
1754
		this.javadocTagPosition = typeRef.tagSourceStart;
1755
1756
		// get the source positions of the completion identifier
1757
		if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1758
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
1759
					((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
1760
				int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1761
				setSourceAndTokenRange(rangeStart, (int) completionPosition);
1762
				findMemberTypes(
1763
					this.completionToken,
1764
					(ReferenceBinding) qualifiedBinding,
1556
					scope,
1765
					scope,
1557
					allocExpression);
1766
					scope.enclosingSourceType(),
1767
					false,
1768
					false,
1769
					new ObjectVector(),
1770
					null,
1771
					null,
1772
					null,
1773
					false);
1558
			}
1774
			}
1559
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1775
		} else if (qualifiedBinding instanceof PackageBinding) {
1560
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1561
				CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1562
				setSourceAndTokenRange(access.classStart, access.sourceEnd);
1563
1776
1564
				this.completionToken = access.completionIdentifier;
1777
			setSourceRange(astNode.sourceStart, (int) completionPosition);
1565
1778
			int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1566
				findClassField(
1779
			setTokenRange(rangeStart, (int) completionPosition);
1567
						this.completionToken,
1780
			// replace to the end of the completion identifier
1568
						(TypeBinding) qualifiedBinding,
1781
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1569
						scope,
1782
		}
1570
						null,
1783
	}
1571
						null,
1784
	//TODO
1572
						null,
1785
	private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
1573
						false);
1786
		CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
1787
		this.completionToken = typeRef.token;
1788
		this.javadocTagPosition = typeRef.tagSourceStart;
1789
		setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
1790
		findTypesAndPackages(
1791
				this.completionToken,
1792
				scope,
1793
				(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
1794
				false,
1795
				new ObjectVector());
1796
	}
1797
	//TODO
1798
	private void completionOnJavadocTag(ASTNode astNode) {
1799
		CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
1800
		setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
1801
		findJavadocBlockTags(javadocTag);
1802
		findJavadocInlineTags(javadocTag);
1803
	}
1804
	//TODO
1805
	private void completionOnJavadocTypeParamReference(ASTNode astNode) {
1806
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1807
			CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
1808
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1809
			findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
1810
		}
1811
	}
1812
	
1813
	private void completionOnKeyword(ASTNode astNode) {
1814
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1815
			CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1816
			findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1817
		}
1818
	}
1819
	
1820
	private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
1821
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1822
			LocalDeclaration variable = (LocalDeclaration) astNode;
1823
1824
			int kind;
1825
			if (variable instanceof CompletionOnLocalName){
1826
				this.completionToken = ((CompletionOnLocalName) variable).realName;
1827
				kind = LOCAL;
1828
			} else {
1829
				CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1830
				this.completionToken = arg.realName;
1831
				kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1574
			}
1832
			}
1575
		} else if (astNode instanceof CompletionOnMethodName) {
1576
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1577
				CompletionOnMethodName method = (CompletionOnMethodName) astNode;
1578
1833
1579
				setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
1834
			char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1580
1835
1581
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1836
			char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1582
				char[][] excludeNames = new char[fields.length][];
1583
				for(int i = 0 ; i < fields.length ; i++){
1584
					excludeNames[i] = fields[i].name;
1585
				}
1586
1587
				this.completionToken = method.selector;
1588
1837
1589
				findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
1838
			LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1839
			char[][] discouragedNames = new char[locals.length][];
1840
			int localCount = 0;
1841
			for(int i = 0 ; i < locals.length ; i++){
1842
				if (locals[i] != null) {
1843
					discouragedNames[localCount++] = locals[i].name;
1844
				}
1590
			}
1845
			}
1591
		} else if (astNode instanceof CompletionOnFieldName) {
1592
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1593
				CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1594
1846
1595
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1847
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1596
				char[][] excludeNames = new char[fields.length][];
1597
				for(int i = 0 ; i < fields.length ; i++){
1598
					excludeNames[i] = fields[i].name;
1599
				}
1600
1848
1601
				this.completionToken = field.realName;
1849
			findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1850
		}
1851
	}
1852
	
1853
	private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1854
		CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1602
1855
1603
				findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1856
		CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1857
		if (fakeType.annotations[0] == annot) {
1858
			// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1859
			// So 'targetedElement' is not computed in this case.
1860
			if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1861
				this.targetedElement = computeTargetedElement(fakeType);
1604
			}
1862
			}
1605
		} else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) {
1606
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1607
				LocalDeclaration variable = (LocalDeclaration) astNode;
1608
1863
1609
				int kind;
1864
		}
1610
				if (variable instanceof CompletionOnLocalName){
1865
1611
					this.completionToken = ((CompletionOnLocalName) variable).realName;
1866
		this.assistNodeIsAnnotation = true;
1612
					kind = LOCAL;
1867
		if (annot.type instanceof CompletionOnSingleTypeReference) {
1613
				} else {
1868
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1614
					CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1869
			this.completionToken = type.token;
1615
					this.completionToken = arg.realName;
1870
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1616
					kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1617
				}
1618
1871
1619
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1872
			if (scope.parent.parent != null &&
1873
					!(scope.parent.parent instanceof MethodScope) &&
1874
					!fakeType.isParameter) {
1620
1875
1621
				char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1876
				if (this.completionToken.length <= Keywords.INTERFACE.length
1877
					&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
1878
				)){
1879
					int relevance = computeBaseRelevance();
1880
					relevance += computeRelevanceForResolution();
1881
					relevance += computeRelevanceForInterestingProposal();
1882
					relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
1883
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1884
					relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
1622
1885
1623
				LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1886
					this.noProposal = false;
1624
				char[][] discouragedNames = new char[locals.length][];
1887
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1625
				int localCount = 0;
1888
						CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1626
				for(int i = 0 ; i < locals.length ; i++){
1889
						proposal.setName(Keywords.INTERFACE);
1627
					if (locals[i] != null) {
1890
						proposal.setCompletion(Keywords.INTERFACE);
1628
						discouragedNames[localCount++] = locals[i].name;
1891
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1892
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
1893
						proposal.setRelevance(relevance);
1894
						this.requestor.accept(proposal);
1895
						if(DEBUG) {
1896
							this.printDebug(proposal);
1897
						}
1629
					}
1898
					}
1630
				}
1899
				}
1631
1632
				System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1633
1634
				findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
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
			}
1900
			}
1641
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1642
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1643
				CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
1644
1901
1645
				this.insideQualifiedReference = true;
1902
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1903
		} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1904
			this.insideQualifiedReference = true;
1646
1905
1647
				this.assistNodeIsClass = ref.isClass();
1906
			CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1648
				this.assistNodeIsException = ref.isException();
1907
			this.completionToken = type.completionIdentifier;
1649
				this.assistNodeIsInterface = ref.isInterface();
1908
			long completionPosition = type.sourcePositions[type.tokens.length];
1650
				this.assistNodeIsSuperType = ref.isSuperType();
1909
			if (qualifiedBinding instanceof PackageBinding) {
1651
1910
1652
				this.completionToken = ref.completionIdentifier;
1911
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1653
				long completionPosition = ref.sourcePositions[ref.tokens.length];
1912
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1913
				// replace to the end of the completion identifier
1914
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1915
			} else {
1654
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1916
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1655
1917
1656
				if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
1918
				findMemberTypes(
1657
						(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
1919
					this.completionToken,
1658
					if (this.assistNodeInJavadoc == 0 &&
1920
					(ReferenceBinding) qualifiedBinding,
1659
							(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1921
					scope,
1660
						if(ref.tokens.length == 1) {
1922
					scope.enclosingSourceType(),
1661
							findMemberTypesFromMissingType(
1923
					false,
1662
									ref,
1924
					false,
1663
									ref.sourcePositions[0],
1925
					new ObjectVector(),
1664
									scope);
1926
					null,
1665
						}
1927
					null,
1666
					}
1928
					null,
1667
				} else {
1929
					false);
1668
					ObjectVector typesFound = new ObjectVector();
1930
			}
1669
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1931
		}
1670
						findExceptionFromTryStatement(
1932
	}
1671
								this.completionToken,
1933
	
1672
								(ReferenceBinding)qualifiedBinding,
1934
	private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
1673
								scope.enclosingSourceType(),
1935
			Scope scope, boolean insideTypeAnnotation) {
1674
								(BlockScope)scope,
1936
		this.insideQualifiedReference = true;
1675
								typesFound);
1937
		CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1676
					}
1938
		long completionPosition = access.nameSourcePosition;
1677
1939
		setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1678
					findMemberTypes(
1940
1679
						this.completionToken,
1941
		this.completionToken = access.token;
1680
						(ReferenceBinding) qualifiedBinding,
1942
1943
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1944
			// complete method members with missing return type
1945
			// class X {
1946
			//   Missing f() {return null;}
1947
			//   void foo() {
1948
			//     f().|
1949
			//   }
1950
			// }
1951
			if (this.assistNodeInJavadoc == 0 &&
1952
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1953
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1954
				ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1955
				findFieldsAndMethodsFromMissingReturnType(
1956
						problemMethodBinding.selector,
1957
						problemMethodBinding.parameters,
1681
						scope,
1958
						scope,
1682
						scope.enclosingSourceType(),
1959
						access,
1683
						false,
1960
						insideTypeAnnotation);
1684
						false,
1685
						typesFound,
1686
						null,
1687
						null,
1688
						null,
1689
						false);
1690
				}
1691
			}
1961
			}
1692
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1962
		} else {
1693
			CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1963
			if (!access.isInsideAnnotation) {
1694
1964
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1695
			CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1965
					findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
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
				}
1966
				}
1702
1967
1703
			}
1968
				ObjectVector fieldsFound = new ObjectVector();
1704
1969
				ObjectVector methodsFound = new ObjectVector();
1705
			this.assistNodeIsAnnotation = true;
1706
			if (annot.type instanceof CompletionOnSingleTypeReference) {
1707
				CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1708
				this.completionToken = type.token;
1709
				setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
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
1970
1725
						this.noProposal = false;
1971
				boolean superCall = access.receiver instanceof SuperReference;
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
1972
1741
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1973
				findFieldsAndMethods(
1742
			} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1974
					this.completionToken,
1743
				this.insideQualifiedReference = true;
1975
					((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
1744
1976
					scope,
1745
				CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1977
					fieldsFound,
1746
				this.completionToken = type.completionIdentifier;
1978
					methodsFound,
1747
				long completionPosition = type.sourcePositions[type.tokens.length];
1979
					access,
1748
				if (qualifiedBinding instanceof PackageBinding) {
1980
					scope,
1749
1981
					false,
1750
					setSourceRange(astNode.sourceStart, (int) completionPosition);
1982
					superCall,
1751
					setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1983
					null,
1752
					// replace to the end of the completion identifier
1984
					null,
1753
					findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1985
					null,
1754
				} else {
1986
					false,
1755
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1987
					null,
1988
					-1,
1989
					-1);
1756
1990
1757
					findMemberTypes(
1991
				if (!superCall) {
1758
						this.completionToken,
1992
					
1759
						(ReferenceBinding) qualifiedBinding,
1993
					checkCancel();
1760
						scope,
1994
					
1761
						scope.enclosingSourceType(),
1995
					findFieldsAndMethodsFromCastedReceiver(
1762
						false,
1996
							enclosingNode,
1763
						false,
1997
							qualifiedBinding,
1764
						new ObjectVector(),
1998
							scope,
1765
						null,
1999
							fieldsFound,
1766
						null,
2000
							methodsFound,
1767
						null,
2001
							access,
1768
						false);
2002
							scope,
2003
							access.receiver);
1769
				}
2004
				}
1770
			}
2005
			}
1771
		} else if (astNode instanceof CompletionOnMemberValueName) {
2006
		}
1772
			CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
2007
	}
1773
			Annotation annotation = (Annotation) astNodeParent;
2008
	
2009
	private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
2010
			boolean insideTypeAnnotation) {
2011
		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
2012
		Annotation annotation = (Annotation) astNodeParent;
1774
2013
1775
			this.completionToken = memberValuePair.name;
2014
		this.completionToken = memberValuePair.name;
1776
2015
1777
			ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
2016
		ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
1778
2017
1779
			if (annotationType != null && annotationType.isAnnotationType()) {
2018
		if (annotationType != null && annotationType.isAnnotationType()) {
1780
				if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2019
			if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
1781
					findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
2020
				findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
1782
				}
2021
			}
1783
				if (this.assistNodeCanBeSingleMemberAnnotation) {
2022
			if (this.assistNodeCanBeSingleMemberAnnotation) {
1784
					if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
2023
				if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1785
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2024
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1786
					} else {
2025
				} else {
1787
						if (this.expectedTypesPtr > -1) {
2026
					if (this.expectedTypesPtr > -1) {
1788
							this.assistNodeIsEnum = true;
2027
						this.assistNodeIsEnum = true;
1789
							done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2028
						done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1790
								if (!this.expectedTypes[i].isEnum()) {
2029
							if (!this.expectedTypes[i].isEnum()) {
1791
									this.assistNodeIsEnum = false;
2030
								this.assistNodeIsEnum = false;
1792
									break done;
2031
								break done;
1793
								}
1794
							}
2032
							}
1795
1796
						}
2033
						}
1797
						if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1798
							char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
1799
2034
1800
							findUnresolvedReference(
1801
									memberValuePair.sourceStart,
1802
									memberValuePair.sourceEnd,
1803
									(BlockScope)scope,
1804
									alreadyDefinedName);
1805
						}
1806
						findVariablesAndMethods(
1807
							this.completionToken,
1808
							scope,
1809
							FakeInvocationSite,
1810
							scope,
1811
							insideTypeAnnotation,
1812
							true);
1813
						// can be the start of a qualified type name
1814
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1815
					}
2035
					}
1816
				}
2036
					if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1817
			}
2037
						char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
1818
		} else if(astNode instanceof CompletionOnBrankStatementLabel) {
1819
			if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1820
				CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode;
1821
1822
				this.completionToken = label.label;
1823
1824
				findLabels(this.completionToken, label.possibleLabels);
1825
			}
1826
		} else if(astNode instanceof CompletionOnMessageSendName) {
1827
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1828
				CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
1829
2038
1830
				this.insideQualifiedReference = true;
2039
						findUnresolvedReference(
1831
				this.completionToken = messageSend.selector;
2040
								memberValuePair.sourceStart,
1832
				boolean onlyStatic = false;
2041
								memberValuePair.sourceEnd,
1833
				if (messageSend.receiver instanceof NameReference) {
2042
								(BlockScope)scope,
1834
					onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
2043
								alreadyDefinedName);
1835
				} else if (!(messageSend.receiver instanceof MessageSend) &&
1836
						!(messageSend.receiver instanceof FieldReference) &&
1837
						!(messageSend.receiver.isThis())) {
1838
					onlyStatic = true;
1839
				}
1840
1841
				TypeBinding receiverType = (TypeBinding)qualifiedBinding;
1842
1843
				if(receiverType != null && receiverType instanceof ReferenceBinding) {
1844
					TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
1845
					if(typeArgTypes != null) {
1846
						findMethods(
1847
								this.completionToken,
1848
								typeArgTypes,
1849
								null,
1850
								(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
1851
								scope,
1852
								new ObjectVector(),
1853
								onlyStatic,
1854
								false,
1855
								false,
1856
								messageSend,
1857
								scope,
1858
								false,
1859
								false,
1860
								false,
1861
								null,
1862
								null,
1863
								null,
1864
								false,
1865
								null,
1866
								-1,
1867
								-1);
1868
					}
2044
					}
2045
					findVariablesAndMethods(
2046
						this.completionToken,
2047
						scope,
2048
						FakeInvocationSite,
2049
						scope,
2050
						insideTypeAnnotation,
2051
						true);
2052
					// can be the start of a qualified type name
2053
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1869
				}
2054
				}
1870
			}
2055
			}
1871
		// Completion on Javadoc nodes
2056
		}
1872
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
2057
	}
1873
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
2058
	
2059
	private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2060
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1874
2061
1875
				CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
2062
		CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1876
				this.completionToken = typeRef.token;
2063
		TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1877
				this.javadocTagPosition = typeRef.tagSourceStart;
2064
		this.completionToken = messageSend.selector;
1878
				setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
2065
		if (qualifiedBinding == null) {
1879
				findTypesAndPackages(
2066
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2067
				ObjectVector methodsFound = new ObjectVector();
2068
2069
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
2070
				
2071
				checkCancel();
2072
				
2073
				findLocalMethodsFromStaticImports(
1880
						this.completionToken,
2074
						this.completionToken,
1881
						scope,
2075
						scope,
1882
						(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
2076
						messageSend,
1883
						false,
2077
						scope,
1884
						new ObjectVector());
2078
						true,
1885
2079
						methodsFound,
1886
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
2080
						true);
2081
			}
2082
		} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2083
			findMethods(
2084
				this.completionToken,
2085
				null,
2086
				argTypes,
2087
				(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
2088
				scope,
2089
				new ObjectVector(),
2090
				false,
2091
				true,
2092
				messageSend,
2093
				scope,
2094
				false,
2095
				messageSend.receiver instanceof SuperReference,
2096
				false,
2097
				null,
2098
				null,
2099
				null,
2100
				false,
2101
				null,
2102
				-1,
2103
				-1);
2104
		}
2105
	}
2106
	
2107
	private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2108
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2109
			CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
1887
2110
1888
				this.insideQualifiedReference = true;
2111
			this.insideQualifiedReference = true;
2112
			this.completionToken = messageSend.selector;
2113
			boolean onlyStatic = false;
2114
			if (messageSend.receiver instanceof NameReference) {
2115
				onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
2116
			} else if (!(messageSend.receiver instanceof MessageSend) &&
2117
					!(messageSend.receiver instanceof FieldReference) &&
2118
					!(messageSend.receiver.isThis())) {
2119
				onlyStatic = true;
2120
			}
1889
2121
1890
				CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
2122
			TypeBinding receiverType = (TypeBinding)qualifiedBinding;
1891
				this.completionToken = typeRef.completionIdentifier;
2123
1892
				long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
2124
			if(receiverType != null && receiverType instanceof ReferenceBinding) {
1893
				this.javadocTagPosition = typeRef.tagSourceStart;
2125
				TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
1894
2126
				if(typeArgTypes != null) {
1895
				// get the source positions of the completion identifier
2127
					findMethods(
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,
2128
							this.completionToken,
1903
							(ReferenceBinding) qualifiedBinding,
2129
							typeArgTypes,
1904
							scope,
1905
							scope.enclosingSourceType(),
1906
							false,
1907
							false,
1908
							new ObjectVector(),
1909
							null,
1910
							null,
1911
							null,
2130
							null,
1912
							false);
2131
							(ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
1913
					}
1914
				} else if (qualifiedBinding instanceof PackageBinding) {
1915
1916
					setSourceRange(astNode.sourceStart, (int) completionPosition);
1917
					int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1918
					setTokenRange(rangeStart, (int) completionPosition);
1919
					// replace to the end of the completion identifier
1920
					findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1921
				}
1922
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
1923
1924
				this.insideQualifiedReference = true;
1925
				CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1926
				this.completionToken = fieldRef.token;
1927
				long completionPosition = fieldRef.nameSourcePosition;
1928
				this.javadocTagPosition = fieldRef.tagSourceStart;
1929
1930
				if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1931
					ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1932
					int rangeStart = (int) (completionPosition >>> 32);
1933
					if (fieldRef.receiver.isThis()) {
1934
						if (fieldRef.completeInText()) {
1935
							rangeStart = fieldRef.separatorPosition;
1936
						}
1937
					} else if (fieldRef.completeInText()) {
1938
						rangeStart = fieldRef.receiver.sourceStart;
1939
					}
1940
					setSourceAndTokenRange(rangeStart, (int) completionPosition);
1941
1942
					if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1943
							|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1944
						findFields(this.completionToken,
1945
							receiverType,
1946
							scope,
2132
							scope,
1947
							new ObjectVector(),
2133
							new ObjectVector(),
1948
							new ObjectVector(),
2134
							onlyStatic,
1949
							false, /*not only static */
2135
							false,
1950
							fieldRef,
2136
							messageSend,
1951
							scope,
2137
							scope,
1952
							false,
2138
							false,
1953
							true,
2139
							false,
2140
							false,
1954
							null,
2141
							null,
1955
							null,
2142
							null,
1956
							null,
2143
							null,
Lines 1958-5072 Link Here
1958
							null,
2145
							null,
1959
							-1,
2146
							-1,
1960
							-1);
2147
							-1);
1961
					}
2148
				}
2149
			}
2150
		}
2151
	}
2152
	
2153
	private void completionOnMethodName(ASTNode astNode, Scope scope) {
2154
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
2155
			CompletionOnMethodName method = (CompletionOnMethodName) astNode;
2156
2157
			setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
2158
2159
			FieldBinding[] fields = scope.enclosingSourceType().fields();
2160
			char[][] excludeNames = new char[fields.length][];
2161
			for(int i = 0 ; i < fields.length ; i++){
2162
				excludeNames[i] = fields[i].name;
2163
			}
1962
2164
1963
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2165
			this.completionToken = method.selector;
1964
							|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
2166
1965
						findMethods(
2167
			findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
2168
		}
2169
	}
2170
	
2171
	private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
2172
		CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
2173
		SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
2174
		this.completionToken = type.token;
2175
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
2176
		findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
2177
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2178
			findKeywordsForMember(this.completionToken, method.modifiers);
2179
		}
2180
2181
		if (method.modifiers == ClassFileConstants.AccDefault) {
2182
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
2183
			if (!enclosingType.isAnnotationType()) {
2184
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
2185
					findMethodDeclarations(
1966
							this.completionToken,
2186
							this.completionToken,
1967
							null,
2187
							scope.enclosingSourceType(),
1968
							null,
1969
							receiverType,
1970
							scope,
2188
							scope,
1971
							new ObjectVector(),
2189
							new ObjectVector(),
1972
							false, /*not only static */
1973
							false,
1974
							false,
1975
							fieldRef,
1976
							scope,
1977
							false,
1978
							false,
1979
							true,
1980
							null,
2190
							null,
1981
							null,
2191
							null,
1982
							null,
2192
							null,
1983
							false,
2193
							false);
1984
							null,
1985
							-1,
1986
							-1);
1987
						if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
1988
							ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
1989
							if (this.completionToken == null
1990
									|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1991
									|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1992
								findConstructors(refBinding, null, scope, fieldRef, false);
1993
							}
1994
						}
1995
					}
1996
				}
1997
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
1998
1999
				CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
2000
				TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
2001
				this.completionToken = messageSend.selector;
2002
				this.javadocTagPosition = messageSend.tagSourceStart;
2003
2004
				// Set source range
2005
				int rangeStart = astNode.sourceStart;
2006
				if (messageSend.receiver.isThis()) {
2007
					if (messageSend.completeInText()) {
2008
						rangeStart = messageSend.separatorPosition;
2009
					}
2010
				} else if (messageSend.completeInText()) {
2011
					rangeStart = messageSend.receiver.sourceStart;
2012
				}
2013
				setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
2014
2015
				if (qualifiedBinding == null) {
2016
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2017
						findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
2018
					}
2019
				} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2020
					findMethods(
2021
						this.completionToken,
2022
						null,
2023
						argTypes,
2024
						(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
2025
						scope,
2026
						new ObjectVector(),
2027
						false,
2028
						false/* prefix match */,
2029
						false,
2030
						messageSend,
2031
						scope,
2032
						false,
2033
						messageSend.receiver instanceof SuperReference,
2034
						true,
2035
						null,
2036
						null,
2037
						null,
2038
						false,
2039
						null,
2040
						-1,
2041
						-1);
2042
				}
2043
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
2044
//				setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
2045
2046
				CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
2047
				this.javadocTagPosition = allocExpression.tagSourceStart;
2048
				int rangeStart = astNode.sourceStart;
2049
				if (allocExpression.type.isThis()) {
2050
					if (allocExpression.completeInText()) {
2051
						rangeStart = allocExpression.separatorPosition;
2052
					}
2053
				} else if (allocExpression.completeInText()) {
2054
					rangeStart = allocExpression.type.sourceStart;
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
				}
2194
				}
2070
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
2195
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
2071
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
2196
					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
2072
					CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
2073
					setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
2074
					findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
2075
				}
2197
				}
2076
			} else if (astNode instanceof CompletionOnJavadocTag) {
2077
				CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
2078
				setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
2079
				findJavadocBlockTags(javadocTag);
2080
				findJavadocInlineTags(javadocTag);
2081
			}
2198
			}
2082
		}
2199
		}
2083
		return true;
2084
	}
2200
	}
2201
	
2202
	private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2203
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2204
			CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
2085
2205
2086
	private void findFieldsAndMethodsFromCastedReceiver(
2206
			this.insideQualifiedReference = true;
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
2207
2100
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
2208
			this.assistNodeIsClass = ref.isClass();
2209
			this.assistNodeIsException = ref.isException();
2210
			this.assistNodeIsInterface = ref.isInterface();
2211
			this.assistNodeIsSuperType = ref.isSuperType();
2101
2212
2102
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
2213
			this.completionToken = ref.completionIdentifier;
2214
			long completionPosition = ref.sourcePositions[ref.tokens.length];
2215
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2103
2216
2104
		TypeReference instanceOfType = instanceOfExpression.type;
2217
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
2105
2218
					(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
2106
		if (instanceOfType.resolvedType == null) return;
2219
				if (this.assistNodeInJavadoc == 0 &&
2107
2220
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2108
		boolean findFromAnotherReceiver = false;
2221
					if(ref.tokens.length == 1) {
2109
2222
						findMemberTypesFromMissingType(
2110
		char[][] receiverName = null;
2223
								ref,
2111
		int receiverStart = -1;
2224
								ref.sourcePositions[0],
2112
		int receiverEnd = -1;
2225
								scope);
2113
2226
					}
2114
		if (receiver instanceof QualifiedNameReference) {
2227
				}
2115
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
2228
			} else {
2229
				ObjectVector typesFound = new ObjectVector();
2230
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2231
					findExceptionFromTryStatement(
2232
							this.completionToken,
2233
							(ReferenceBinding)qualifiedBinding,
2234
							scope.enclosingSourceType(),
2235
							(BlockScope)scope,
2236
							typesFound);
2237
				}
2238
				
2239
				checkCancel();
2240
				
2241
				findMemberTypes(
2242
					this.completionToken,
2243
					(ReferenceBinding) qualifiedBinding,
2244
					scope,
2245
					scope.enclosingSourceType(),
2246
					false,
2247
					false,
2248
					typesFound,
2249
					null,
2250
					null,
2251
					null,
2252
					false);
2253
			}
2254
		}
2255
	}
2256
	
2257
	private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2258
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
2116
2259
2117
			receiverName = qualifiedNameReference.tokens;
2260
		CompletionOnQualifiedAllocationExpression allocExpression =
2261
			(CompletionOnQualifiedAllocationExpression) astNode;
2262
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
2263
2264
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
2265
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2266
				&& ref.isClass()
2267
				&& !ref.isAbstract()) {
2268
				findConstructors(
2269
					ref,
2270
					argTypes,
2271
					scope,
2272
					allocExpression,
2273
					false);
2274
		}
2275
		
2276
		checkCancel();
2277
		
2278
		if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
2279
				&& !ref.isFinal()
2280
				&& !ref.isEnum()){
2281
			findAnonymousType(
2282
				ref,
2283
				argTypes,
2284
				scope,
2285
				allocExpression);
2286
		}
2287
	}
2288
	
2289
	private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
2290
			Scope scope, boolean insideTypeAnnotation) {
2291
		this.insideQualifiedReference = true;
2292
		CompletionOnQualifiedNameReference ref =
2293
			(CompletionOnQualifiedNameReference) astNode;
2294
		this.completionToken = ref.completionIdentifier;
2295
		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
2118
2296
2119
			if (receiverName.length != 1) return;
2297
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2298
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2299
			// complete field members with missing fields type
2300
			// class X {
2301
			//   Missing f;
2302
			//   void foo() {
2303
			//     f.|
2304
			//   }
2305
			// }
2306
			if (this.assistNodeInJavadoc == 0 &&
2307
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2308
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
2309
							this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2310
				if(ref.tokens.length == 1) {
2311
					boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2312
2313
					if (!foundSomeFields) {
2314
						
2315
						checkCancel();
2316
						
2317
						findMembersFromMissingType(
2318
								ref.tokens[0],
2319
								ref.sourcePositions[0],
2320
								null,
2321
								scope,
2322
								ref,
2323
								ref.isInsideAnnotationAttribute);
2324
					}
2325
				}
2326
			}
2327
		} else if (qualifiedBinding instanceof VariableBinding) {
2328
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2329
			TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
2330
			if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
2331
				ObjectVector fieldsFound = new ObjectVector();
2332
				ObjectVector methodsFound = new ObjectVector();
2120
2333
2121
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
2334
				findFieldsAndMethods(
2122
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
2335
						this.completionToken,
2336
						receiverType.capture(scope, ref.sourceEnd),
2337
						scope,
2338
						fieldsFound,
2339
						methodsFound,
2340
						ref,
2341
						scope,
2342
						false,
2343
						false,
2344
						null,
2345
						null,
2346
						null,
2347
						false,
2348
						null,
2349
						-1,
2350
						-1);
2351
				
2352
				checkCancel();
2123
2353
2124
			// if (local instanceof X) local.|
2354
				findFieldsAndMethodsFromCastedReceiver(
2125
			// if (field instanceof X) field.|
2355
						enclosingNode,
2126
			if (instanceOfExpression.expression instanceof SingleNameReference &&
2356
						qualifiedBinding,
2127
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
2357
						scope,
2128
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
2358
						fieldsFound,
2129
				findFromAnotherReceiver = true;
2359
						methodsFound,
2130
			}
2360
						ref,
2361
						scope,
2362
						ref);
2131
2363
2132
			// if (this.field instanceof X) field.|
2364
			} else if (this.assistNodeInJavadoc == 0 &&
2133
			if (instanceOfExpression.expression instanceof FieldReference) {
2365
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2134
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
2366
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
2367
				boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
2368
				boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
2369
				if (proposeField || proposeMethod) {
2370
					if(ref.tokens.length == 1) {
2371
						if (qualifiedBinding instanceof LocalVariableBinding) {
2372
							// complete local variable members with missing variables type
2373
							// class X {
2374
							//   void foo() {
2375
							//     Missing f;
2376
							//     f.|
2377
							//   }
2378
							// }
2379
							LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
2380
							findFieldsAndMethodsFromMissingType(
2381
									localVariableBinding.declaration.type,
2382
									localVariableBinding.declaringScope,
2383
									ref,
2384
									scope);
2385
						} else {
2386
							// complete field members with missing fields type
2387
							// class X {
2388
							//   Missing f;
2389
							//   void foo() {
2390
							//     f.|
2391
							//   }
2392
							// }
2393
							findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2394
						}
2135
2395
2136
				if (fieldReference.receiver instanceof ThisReference &&
2396
					}
2137
						qualifiedBinding instanceof FieldBinding &&
2138
						fieldReference.binding == qualifiedBinding) {
2139
							findFromAnotherReceiver = true;
2140
				}
2397
				}
2141
			}
2398
			}
2142
		} else if (receiver instanceof FieldReference) {
2143
			FieldReference fieldReference1 = (FieldReference) receiver;
2144
2145
			receiverStart = fieldReference1.sourceStart;
2146
			receiverEnd = fieldReference1.sourceEnd + 1;
2147
2399
2148
			if (fieldReference1.receiver instanceof ThisReference) {
2400
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2401
			boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
2402
			ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
2403
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2149
2404
2150
				receiverName = new char[][] {THIS, fieldReference1.token};
2405
			findMembers(
2406
					this.completionToken,
2407
					receiverType,
2408
					scope,
2409
					ref,
2410
					isInsideAnnotationAttribute,
2411
					null,
2412
					null,
2413
					null,
2414
					false);
2151
2415
2152
				// if (field instanceof X) this.field.|
2416
		} else if (qualifiedBinding instanceof PackageBinding) {
2153
				if (instanceOfExpression.expression instanceof SingleNameReference &&
2154
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
2155
					findFromAnotherReceiver = true;
2156
				}
2157
2417
2158
				// if (this.field instanceof X) this.field.|
2418
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2159
				if (instanceOfExpression.expression instanceof FieldReference) {
2419
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2160
					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
2161
2420
2162
					if (fieldReference2.receiver instanceof ThisReference &&
2421
			// replace to the end of the completion identifier
2163
							fieldReference2.binding == fieldReference1.binding) {
2422
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2164
								findFromAnotherReceiver = true;
2165
					}
2166
				}
2167
			}
2168
		}
2423
		}
2424
	}
2425
	
2426
	private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
2427
			Scope scope) {
2428
		this.insideQualifiedReference = true;
2169
2429
2170
		if (findFromAnotherReceiver) {
2430
		CompletionOnQualifiedTypeReference ref =
2171
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
2431
			(CompletionOnQualifiedTypeReference) astNode;
2172
			char[] castedReceiver = null;
2173
2432
2174
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
2433
		this.assistNodeIsClass = ref.isClass();
2175
			if(this.source != null) {
2434
		this.assistNodeIsException = ref.isException();
2176
				int memberRefStart = this.startPosition;
2435
		this.assistNodeIsInterface = ref.isInterface();
2436
		this.assistNodeIsSuperType = ref.isSuperType();
2177
2437
2178
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
2438
		this.completionToken = ref.completionIdentifier;
2179
				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
2439
		long completionPosition = ref.sourcePositions[ref.tokens.length];
2180
2440
2181
				castedReceiver =
2441
		// get the source positions of the completion identifier
2182
					CharOperation.concat(
2442
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2183
						CharOperation.concat(
2443
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2184
							'(',
2444
			if (this.assistNodeInJavadoc == 0 &&
2185
							CharOperation.concat(
2445
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2186
								CharOperation.concat('(', castedTypeChars, ')'),
2446
				if(ref.tokens.length == 1) {
2187
								receiverChars),
2447
					findMemberTypesFromMissingType(
2188
							')'),
2448
							ref.tokens[0],
2189
						dotChars);
2449
							ref.sourcePositions[0],
2190
			} else {
2450
							scope);
2191
				castedReceiver =
2451
				}
2192
					CharOperation.concat(
2193
						CharOperation.concat(
2194
							'(',
2195
							CharOperation.concat(
2196
								CharOperation.concat('(', castedTypeChars, ')'),
2197
								CharOperation.concatWith(receiverName, '.')),
2198
							')'),
2199
						DOT);
2200
			}
2452
			}
2453
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2454
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2455
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2201
2456
2202
			if (castedReceiver == null) return;
2457
				ObjectVector typesFound = new ObjectVector();
2203
2458
2204
			int oldStartPosition = this.startPosition;
2459
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2205
			this.startPosition = receiverStart;
2460
					findExceptionFromTryStatement(
2461
							this.completionToken,
2462
							(ReferenceBinding)qualifiedBinding,
2463
							scope.enclosingSourceType(),
2464
							(BlockScope)scope,
2465
							typesFound);
2466
				}
2467
				
2468
				checkCancel();
2206
2469
2207
			findFieldsAndMethods(
2470
				findMemberTypes(
2208
					this.completionToken,
2471
					this.completionToken,
2209
					receiverTypeBinding,
2472
					(ReferenceBinding) qualifiedBinding,
2210
					scope,
2473
					scope,
2211
					fieldsFound,
2474
					scope.enclosingSourceType(),
2212
					methodsFound,
2213
					invocationSite,
2214
					invocationScope,
2215
					false,
2475
					false,
2216
					false,
2476
					false,
2477
					typesFound,
2217
					null,
2478
					null,
2218
					null,
2479
					null,
2219
					null,
2480
					null,
2220
					false,
2481
					false);
2221
					castedReceiver,
2482
			}
2222
					receiverStart,
2483
		} else if (qualifiedBinding instanceof PackageBinding) {
2223
					receiverEnd);
2224
2484
2225
			this.startPosition = oldStartPosition;
2485
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2486
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2487
			// replace to the end of the completion identifier
2488
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2226
		}
2489
		}
2227
	}
2490
	}
2491
	
2492
	private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
2493
			boolean insideTypeAnnotation) {
2494
		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
2495
		this.completionToken = singleNameReference.token;
2496
		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
2497
		if (switchStatement != null
2498
				&& switchStatement.expression.resolvedType != null
2499
				&& switchStatement.expression.resolvedType.isEnum()) {
2500
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2501
				this.assistNodeIsEnum = true;
2502
				findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
2503
			}
2504
		} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
2505
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2506
		} else {
2507
			if (this.expectedTypesPtr > -1) {
2508
				this.assistNodeIsEnum = true;
2509
				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2510
					if (!this.expectedTypes[i].isEnum()) {
2511
						this.assistNodeIsEnum = false;
2512
						break done;
2513
					}
2514
				}
2228
2515
2229
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2516
			}
2230
		if(this.requestor != null){
2517
			if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
2231
			this.requestor.beginReporting();
2518
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
2232
		}
2519
2233
		boolean contextAccepted = false;
2520
				findUnresolvedReference(
2234
		IType topLevelType = type;
2521
						singleNameReference.sourceStart,
2235
		while(topLevelType.getDeclaringType() != null) {
2522
						singleNameReference.sourceEnd,
2236
			topLevelType = topLevelType.getDeclaringType();
2523
						(BlockScope)scope,
2524
						alreadyDefinedName);
2525
			}
2526
			
2527
			checkCancel();
2528
			
2529
			findVariablesAndMethods(
2530
				this.completionToken,
2531
				scope,
2532
				singleNameReference,
2533
				scope,
2534
				insideTypeAnnotation,
2535
				singleNameReference.isInsideAnnotationAttribute);
2536
			
2537
			checkCancel();
2538
			
2539
			// can be the start of a qualified type name
2540
			findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
2541
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2542
				if (this.completionToken != null && this.completionToken.length != 0) {
2543
					findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
2544
				} else {
2545
					findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
2546
				}
2547
			}
2548
			if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
2549
				if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
2550
					ReferenceBinding ref = scope.enclosingSourceType();
2551
					findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
2552
				} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
2553
					ReferenceBinding ref = scope.enclosingSourceType();
2554
					findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
2555
				}
2556
			}
2237
		}
2557
		}
2558
	}
2559
	
2560
	private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2561
		CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
2238
2562
2239
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
2563
		this.completionToken = singleRef.token;
2240
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2241
2564
2242
		CompilationUnitDeclaration compilationUnit = null;
2565
		this.assistNodeIsClass = singleRef.isClass();
2566
		this.assistNodeIsException = singleRef.isException();
2567
		this.assistNodeIsInterface = singleRef.isInterface();
2568
		this.assistNodeIsConstructor = singleRef.isConstructorType;
2569
		this.assistNodeIsSuperType = singleRef.isSuperType();
2570
2571
		// can be the start of a qualified type name
2572
		if (qualifiedBinding == null) {
2573
			if (this.completionToken.length == 0 &&
2574
					(astNodeParent instanceof ParameterizedSingleTypeReference ||
2575
							astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
2576
				this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
2243
2577
2244
		try {
2578
				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 {
2579
			} else {
2261
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
2580
				ObjectVector typesFound = new ObjectVector();
2262
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
2581
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2263
			}
2582
					findExceptionFromTryStatement(
2264
2583
							this.completionToken,
2265
			if(typeDeclaration != null) {
2584
							null,
2266
				// build AST from snippet
2585
							scope.enclosingSourceType(),
2267
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
2586
							(BlockScope)scope,
2268
2587
							typesFound);
2269
				// merge AST
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
2281
				if(DEBUG) {
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
2290
						if ((this.unitScope = compilationUnit.scope) != null) {
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
				}
2588
				}
2589
				
2590
				checkCancel();
2591
				
2592
				findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
2323
			}
2593
			}
2324
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
2594
		} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2325
			if(DEBUG) {
2595
			findMemberTypes(
2326
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2596
				this.completionToken,
2327
				e.printStackTrace(System.out);
2597
				(ReferenceBinding) qualifiedBinding,
2328
			}
2598
				scope,
2329
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
2599
				scope.enclosingSourceType(),
2330
			if(DEBUG) {
2600
				false,
2331
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2601
				false,
2332
				e.printStackTrace(System.out);
2602
				false,
2333
			}
2603
				false,
2334
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
2604
				!this.assistNodeIsConstructor,
2335
			if(DEBUG) {
2605
				null,
2336
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2606
				new ObjectVector(),
2337
				e.printStackTrace(System.out);
2607
				null,
2338
			}
2608
				null,
2339
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
2609
				null,
2340
			if(DEBUG) {
2610
				false);
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
		}
2611
		}
2356
	}
2612
	}
2357
2613
2358
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2614
	private char[][] computeAlreadyDefinedName(
2359
		StringBuffer prefix = new StringBuffer();
2615
			BlockScope scope,
2360
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
2616
			InvocationSite invocationSite) {
2361
		if(isStatic) {
2617
		ArrayList result = new ArrayList();
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
2618
2374
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
2619
		boolean staticsOnly = false;
2375
		this.offset = prefix.length();
2376
2620
2377
		String encoding = this.compilerOptions.defaultEncoding;
2621
		Scope currentScope = scope;
2378
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
2379
			fakeSource,
2380
			null,
2381
			"FakeType.java", //$NON-NLS-1$
2382
			encoding);
2383
2622
2384
		this.actualCompletionPosition = prefix.length() + position - 1;
2623
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
2385
2624
2386
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2625
			switch (currentScope.kind) {
2387
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
2388
2626
2389
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
2627
				case Scope.METHOD_SCOPE :
2628
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
2629
					MethodScope methodScope = (MethodScope) currentScope;
2630
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
2390
2631
2391
		return (Initializer)fakeAST.types[0].fields[0];
2632
				//$FALL-THROUGH$
2392
	}
2633
				case Scope.BLOCK_SCOPE :
2634
					BlockScope blockScope = (BlockScope) currentScope;
2393
2635
2394
	/**
2636
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
2395
	 * Ask the engine to compute a completion at the specified position
2637
						LocalVariableBinding local = blockScope.locals[i];
2396
	 * of the given compilation unit.
2397
	 *
2398
	 *  No return
2399
	 *      completion results are answered through a requestor.
2400
	 *
2401
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
2402
	 *      the source of the current compilation unit.
2403
	 *
2404
	 *  @param completionPosition int
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
2638
2410
		if(DEBUG) {
2639
						if (local == null)
2411
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
2640
							break next;
2412
			System.out.print(sourceUnit.getFileName());
2413
			System.out.print(" AT POSITION "); //$NON-NLS-1$
2414
			System.out.println(completionPosition);
2415
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
2416
			System.out.println(sourceUnit.getContents());
2417
		}
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
2641
2429
			//		boolean completionNodeFound = false;
2642
						if (local.isSecret())
2430
			if (parsedUnit != null) {
2643
							continue next;
2431
				if(DEBUG) {
2432
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
2433
					System.out.println(parsedUnit.toString());
2434
				}
2435
2644
2436
				// scan the package & import statements first
2645
						result.add(local.name);
2437
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
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
					}
2646
					}
2449
					return;
2647
					break;
2450
				}
2451
2452
				ImportReference[] imports = parsedUnit.imports;
2453
				if (imports != null) {
2454
					for (int i = 0, length = imports.length; i < length; i++) {
2455
						ImportReference importReference = imports[i];
2456
						if (importReference instanceof CompletionOnImportReference) {
2457
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2458
							if ((this.unitScope = parsedUnit.scope) != null) {
2459
								contextAccepted = true;
2460
								buildContext(importReference, null, parsedUnit, null, null);
2461
2648
2462
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
2649
				case Scope.CLASS_SCOPE :
2463
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
2650
					ClassScope classScope = (ClassScope) currentScope;
2651
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
2652
					computeAlreadyDefinedName(
2653
							enclosingType,
2654
							classScope,
2655
							staticsOnly,
2656
							invocationSite,
2657
							result);
2658
					staticsOnly |= enclosingType.isStatic();
2659
					break;
2464
2660
2465
								char[][] oldTokens = importReference.tokens;
2661
				case Scope.COMPILATION_UNIT_SCOPE :
2466
								int tokenCount = oldTokens.length;
2662
					break done1;
2467
								if (tokenCount == 1) {
2663
			}
2468
									findImports((CompletionOnImportReference)importReference, true);
2664
			currentScope = currentScope.parent;
2469
								} else if(tokenCount > 1){
2665
		}
2470
									this.insideQualifiedReference = true;
2471
2666
2472
									char[] lastToken = oldTokens[tokenCount - 1];
2667
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
2473
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
2474
2668
2475
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
2669
		return (char[][])result.toArray(new char[result.size()][]);
2476
									if(binding != null) {
2670
	}
2477
										if(binding instanceof PackageBinding) {
2478
											findImports((CompletionOnImportReference)importReference, false);
2479
										} else {
2480
											ReferenceBinding ref = (ReferenceBinding) binding;
2481
2671
2482
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2672
	private void computeAlreadyDefinedName(
2483
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
2673
			FieldBinding[] fields,
2484
											}
2674
			Scope scope,
2485
											if(importReference.isStatic()) {
2675
			boolean onlyStaticFields,
2676
			ReferenceBinding receiverType,
2677
			InvocationSite invocationSite,
2678
			ArrayList result) {
2486
2679
2487
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2680
		next : for (int f = fields.length; --f >= 0;) {
2488
													findImportsOfStaticFields(lastToken, ref);
2681
			FieldBinding field = fields[f];
2489
												}
2490
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
2491
													findImportsOfStaticMethods(lastToken, ref);
2492
												}
2493
											}
2494
										}
2495
									}
2496
								}
2497
2682
2498
								if(this.noProposal && this.problem != null) {
2683
			if (field.isSynthetic()) continue next;
2499
									this.requestor.completionFailure(this.problem);
2500
									if(DEBUG) {
2501
										this.printDebug(this.problem);
2502
									}
2503
								}
2504
							}
2505
							return;
2506
						} else if(importReference instanceof CompletionOnKeyword) {
2507
							contextAccepted = true;
2508
							buildContext(importReference, null, parsedUnit, null, null);
2509
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2510
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
2511
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
2512
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
2513
							}
2514
							if(this.noProposal && this.problem != null) {
2515
								this.requestor.completionFailure(this.problem);
2516
								if(DEBUG) {
2517
									this.printDebug(this.problem);
2518
								}
2519
							}
2520
							return;
2521
						}
2522
					}
2523
				}
2524
2684
2525
				if (parsedUnit.types != null) {
2685
			if (onlyStaticFields && !field.isStatic()) continue next;
2526
					try {
2527
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2528
2686
2529
						if ((this.unitScope = parsedUnit.scope) != null) {
2687
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
2530
							this.source = sourceUnit.getContents();
2688
2531
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
2689
			result.add(field.name);
2532
							parsedUnit.scope.faultInTypes();
2690
		}
2533
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
2691
	}
2534
							if(DEBUG) {
2692
2535
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
2693
	private void computeAlreadyDefinedName(
2536
								System.out.println(parsedUnit.toString());
2694
			SourceTypeBinding receiverType,
2537
							}
2695
			ClassScope scope,
2538
							parsedUnit.resolve();
2696
			boolean onlyStaticFields,
2539
						}
2697
			InvocationSite invocationSite,
2540
					} catch (CompletionNodeFound e) {
2698
			ArrayList result) {
2541
						//					completionNodeFound = true;
2699
2542
						if (e.astNode != null) {
2700
		ReferenceBinding currentType = receiverType;
2543
							// if null then we found a problem in the completion node
2701
		ReferenceBinding[] interfacesToVisit = null;
2544
							if(DEBUG) {
2702
		int nextPosition = 0;
2545
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
2703
		do {
2546
								System.out.println(e.astNode.toString());
2704
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
2547
								if(this.parser.assistNodeParent != null) {
2705
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2548
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
2706
				if (interfacesToVisit == null) {
2549
									System.out.println(this.parser.assistNodeParent);
2707
					interfacesToVisit = itsInterfaces;
2550
								}
2708
					nextPosition = interfacesToVisit.length;
2551
							}
2709
				} else {
2552
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
2710
					int itsLength = itsInterfaces.length;
2553
							contextAccepted =
2711
					if (nextPosition + itsLength >= interfacesToVisit.length)
2554
								complete(
2712
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2555
									e.astNode,
2713
					nextInterface : for (int a = 0; a < itsLength; a++) {
2556
									this.parser.assistNodeParent,
2714
						ReferenceBinding next = itsInterfaces[a];
2557
									this.parser.enclosingNode,
2715
						for (int b = 0; b < nextPosition; b++)
2558
									parsedUnit,
2716
							if (next == interfacesToVisit[b]) continue nextInterface;
2559
									e.qualifiedBinding,
2717
						interfacesToVisit[nextPosition++] = next;
2560
									e.scope,
2561
									e.insideTypeAnnotation);
2562
						}
2563
					}
2718
					}
2564
				}
2719
				}
2565
			}
2720
			}
2566
2721
2567
			if(this.noProposal && this.problem != null) {
2722
			FieldBinding[] fields = currentType.availableFields();
2568
				if(!contextAccepted) {
2723
			if(fields != null && fields.length > 0) {
2569
					contextAccepted = true;
2724
				computeAlreadyDefinedName(
2570
					InternalCompletionContext context = new InternalCompletionContext();
2725
					fields,
2571
					context.setOffset(completionPosition - this.offset);
2726
					scope,
2572
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2727
					onlyStaticFields,
2573
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
2728
					receiverType,
2574
					this.requestor.acceptContext(context);
2729
					invocationSite,
2575
				}
2730
					result);
2576
				this.requestor.completionFailure(this.problem);
2577
				if(DEBUG) {
2578
					this.printDebug(this.problem);
2579
				}
2580
			}
2581
			/* Ignore package, import, class & interface keywords for now...
2582
					if (!completionNodeFound) {
2583
						if (parsedUnit == null || parsedUnit.types == null) {
2584
							// this is not good enough... can still be trying to define a second type
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
			}
2607
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
2608
			if(DEBUG) {
2609
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2610
				e.printStackTrace(System.out);
2611
			}
2612
		} finally {
2613
			reset();
2614
			if(!contextAccepted) {
2615
				contextAccepted = true;
2616
				InternalCompletionContext context = new InternalCompletionContext();
2617
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2618
				context.setOffset(completionPosition - this.offset);
2619
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
2620
				this.requestor.acceptContext(context);
2621
			}
2731
			}
2622
			this.requestor.endReporting();
2732
			currentType = currentType.superclass();
2623
		}
2733
		} while ( currentType != null);
2624
	}
2625
2734
2626
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
2735
		if (interfacesToVisit != null) {
2627
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
2736
			for (int i = 0; i < nextPosition; i++) {
2737
				ReferenceBinding anInterface = interfacesToVisit[i];
2738
				FieldBinding[] fields = anInterface.availableFields();
2739
				if(fields !=  null) {
2740
					computeAlreadyDefinedName(
2741
						fields,
2742
						scope,
2743
						onlyStaticFields,
2744
						receiverType,
2745
						invocationSite,
2746
						result);
2747
				}
2628
2748
2629
		if (annotatedElement instanceof TypeDeclaration) {
2749
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
2630
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
2750
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2631
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
2751
					int itsLength = itsInterfaces.length;
2632
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
2752
					if (nextPosition + itsLength >= interfacesToVisit.length)
2633
			}
2753
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2634
			return TagBits.AnnotationForType;
2754
					nextInterface : for (int a = 0; a < itsLength; a++) {
2635
		} else if (annotatedElement instanceof FieldDeclaration) {
2755
						ReferenceBinding next = itsInterfaces[a];
2636
			if (fakeNode.isParameter) {
2756
						for (int b = 0; b < nextPosition; b++)
2637
				return TagBits.AnnotationForParameter;
2757
							if (next == interfacesToVisit[b]) continue nextInterface;
2758
						interfacesToVisit[nextPosition++] = next;
2759
					}
2760
				}
2638
			}
2761
			}
2639
			return TagBits.AnnotationForField;
2640
		} else if (annotatedElement instanceof MethodDeclaration) {
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
		}
2762
		}
2651
		return 0;
2652
	}
2763
	}
2653
2764
2654
	private TypeBinding[] computeTypes(Expression[] arguments) {
2765
	int computeBaseRelevance(){
2655
		if (arguments == null) return null;
2766
		return R_DEFAULT;
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
	}
2767
	}
2663
2768
2664
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
2769
	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
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
2770
2676
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
2771
		// default filter
2677
		MethodBinding[] methods = annotation.availableMethods();
2772
		this.expectedTypesFilter = SUBTYPE;
2678
		nextAttribute: for (int i = 0; i < methods.length; i++) {
2773
		this.hasJavaLangObjectAsExpectedType = false;
2679
			MethodBinding method = methods[i];
2680
2681
			if(!CharOperation.prefixEquals(token, method.selector, false)
2682
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
2683
2774
2684
			int length = attributesFound == null ? 0 : attributesFound.length;
2775
		// find types from parent
2685
			for (int j = 0; j < length; j++) {
2776
		if(parent instanceof AbstractVariableDeclaration) {
2686
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
2777
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
2778
			TypeBinding binding = variable.type.resolvedType;
2779
			if(binding != null) {
2780
				if(!(variable.initialization instanceof ArrayInitializer)) {
2781
					addExpectedType(binding, scope);
2782
				}
2687
			}
2783
			}
2688
2784
		} else if(parent instanceof Assignment) {
2689
			int relevance = computeBaseRelevance();
2785
			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
2690
			relevance += computeRelevanceForResolution();
2786
			if(binding != null) {
2691
			relevance += computeRelevanceForInterestingProposal(method);
2787
				addExpectedType(binding, scope);
2692
			relevance += computeRelevanceForCaseMatching(token, method.selector);
2788
			}
2693
			relevance += computeRelevanceForQualification(false);
2789
		} else if(parent instanceof ReturnStatement) {
2694
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2790
			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
2695
2791
				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
2696
			this.noProposal = false;
2792
				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
2697
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2793
				if(binding != null) {
2698
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
2794
					addExpectedType(binding, scope);
2699
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
2700
				proposal.setSignature(getSignature(method.returnType));
2701
				proposal.setName(method.selector);
2702
				proposal.setCompletion(method.selector);
2703
				proposal.setFlags(method.modifiers);
2704
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2705
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2706
				proposal.setRelevance(relevance);
2707
				this.requestor.accept(proposal);
2708
				if(DEBUG) {
2709
					this.printDebug(proposal);
2710
				}
2795
				}
2711
			}
2796
			}
2712
		}
2797
		} else if(parent instanceof CastExpression) {
2713
	}
2798
			Expression e = ((CastExpression)parent).type;
2714
	private void findAnonymousType(
2799
			TypeBinding binding = e.resolvedType;
2715
		ReferenceBinding currentType,
2800
			if(binding != null){
2716
		TypeBinding[] argTypes,
2801
				addExpectedType(binding, scope);
2717
		Scope scope,
2802
				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2718
		InvocationSite invocationSite) {
2803
			}
2804
		} else if(parent instanceof MessageSend) {
2805
			MessageSend messageSend = (MessageSend) parent;
2719
2806
2720
		if (currentType.isInterface()) {
2807
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
2721
			char[] completion = CharOperation.NO_CHAR;
2808
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
2722
			int relevance = computeBaseRelevance();
2809
				boolean isStatic = messageSend.receiver.isTypeReference();
2723
			relevance += computeRelevanceForResolution();
2724
			relevance += computeRelevanceForInterestingProposal();
2725
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2726
2810
2727
			this.noProposal = false;
2811
				while(binding != null) {
2728
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
2812
					computeExpectedTypesForMessageSend(
2729
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
2813
						binding,
2730
				proposal.setDeclarationSignature(getSignature(currentType));
2814
						messageSend.selector,
2731
				proposal.setDeclarationKey(currentType.computeUniqueKey());
2815
						messageSend.arguments,
2732
				proposal.setSignature(
2816
						(ReferenceBinding)messageSend.actualReceiverType,
2733
						createMethodSignature(
2817
						scope,
2734
								CharOperation.NO_CHAR_CHAR,
2818
						messageSend,
2735
								CharOperation.NO_CHAR_CHAR,
2819
						isStatic);
2736
								CharOperation.NO_CHAR,
2820
					computeExpectedTypesForMessageSendForInterface(
2737
								CharOperation.NO_CHAR));
2821
						binding,
2738
				//proposal.setOriginalSignature(null);
2822
						messageSend.selector,
2739
				//proposal.setUniqueKey(null);
2823
						messageSend.arguments,
2740
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2824
						(ReferenceBinding)messageSend.actualReceiverType,
2741
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2825
						scope,
2742
				//proposal.setParameterPackageNames(null);
2826
						messageSend,
2743
				//proposal.setParameterTypeNames(null);
2827
						isStatic);
2744
				//proposal.setPackageName(null);
2828
					binding = binding.superclass();
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
				}
2829
				}
2755
			}
2830
			}
2756
		} else {
2831
		} else if(parent instanceof AllocationExpression) {
2757
			findConstructors(
2832
			AllocationExpression allocationExpression = (AllocationExpression) parent;
2758
				currentType,
2759
				argTypes,
2760
				scope,
2761
				invocationSite,
2762
				true);
2763
		}
2764
	}
2765
2766
	private void findClassField(
2767
			char[] token,
2768
			TypeBinding receiverType,
2769
			Scope scope,
2770
			Binding[] missingElements,
2771
			int[] missingElementsStarts,
2772
			int[] missingElementsEnds,
2773
			boolean missingElementsHaveProblems) {
2774
2775
		if (token == null) return;
2776
2833
2777
		if (token.length <= classField.length
2834
			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
2778
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
2779
		)) {
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
2835
2788
			if (missingElements != null) {
2836
			if(binding != null) {
2789
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
2837
				computeExpectedTypesForAllocationExpression(
2838
					binding,
2839
					allocationExpression.arguments,
2840
					scope,
2841
					allocationExpression);
2790
			}
2842
			}
2791
2843
		} else if(parent instanceof OperatorExpression) {
2792
			this.noProposal = false;
2844
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
2793
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
2845
			if(parent instanceof ConditionalExpression) {
2794
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2846
				// for future use
2795
				//proposal.setDeclarationSignature(null);
2847
			} else if(parent instanceof InstanceOfExpression) {
2796
				char[] signature =
2848
				InstanceOfExpression e = (InstanceOfExpression) parent;
2797
					createNonGenericTypeSignature(
2849
				TypeBinding binding = e.expression.resolvedType;
2798
						CharOperation.concatWith(JAVA_LANG, '.'),
2850
				if(binding != null){
2799
						CLASS);
2851
					addExpectedType(binding, scope);
2800
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
2852
					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
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
				}
2853
				}
2812
				proposal.setSignature(signature);
2854
			} else if(parent instanceof BinaryExpression) {
2813
				//proposal.setDeclarationPackageName(null);
2855
				BinaryExpression binaryExpression = (BinaryExpression) parent;
2814
				//proposal.setDeclarationTypeName(null);
2856
				switch(operator) {
2815
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
2857
					case OperatorIds.EQUAL_EQUAL :
2816
				proposal.setTypeName(CLASS);
2858
						// expected type is not relevant in this case
2817
				proposal.setName(classField);
2859
						TypeBinding binding = binaryExpression.left.resolvedType;
2818
				if (missingElements != null) {
2860
						if (binding != null) {
2819
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
2861
							addExpectedType(binding, scope);
2820
					for (int i = 0; i < missingElements.length; i++) {
2862
							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2821
						subProposals[i] =
2863
						}
2822
							createRequiredTypeProposal(
2864
						break;
2823
									missingElements[i],
2865
					case OperatorIds.PLUS :
2824
									missingElementsStarts[i],
2866
						addExpectedType(TypeBinding.SHORT, scope);
2825
									missingElementsEnds[i],
2867
						addExpectedType(TypeBinding.INT, scope);
2826
									relevance);
2868
						addExpectedType(TypeBinding.LONG, scope);
2869
						addExpectedType(TypeBinding.FLOAT, scope);
2870
						addExpectedType(TypeBinding.DOUBLE, scope);
2871
						addExpectedType(TypeBinding.CHAR, scope);
2872
						addExpectedType(TypeBinding.BYTE, scope);
2873
						addExpectedType(scope.getJavaLangString(), scope);
2874
						break;
2875
					case OperatorIds.AND_AND :
2876
					case OperatorIds.OR_OR :
2877
					case OperatorIds.XOR :
2878
						addExpectedType(TypeBinding.BOOLEAN, scope);
2879
						break;
2880
					default :
2881
						addExpectedType(TypeBinding.SHORT, scope);
2882
						addExpectedType(TypeBinding.INT, scope);
2883
						addExpectedType(TypeBinding.LONG, scope);
2884
						addExpectedType(TypeBinding.FLOAT, scope);
2885
						addExpectedType(TypeBinding.DOUBLE, scope);
2886
						addExpectedType(TypeBinding.CHAR, scope);
2887
						addExpectedType(TypeBinding.BYTE, scope);
2888
						break;
2889
				}
2890
				if(operator == OperatorIds.LESS) {
2891
					if(binaryExpression.left instanceof SingleNameReference){
2892
						SingleNameReference name = (SingleNameReference) binaryExpression.left;
2893
						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
2894
						if(b instanceof ReferenceBinding) {
2895
							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
2896
							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
2897
								addExpectedType(typeVariableBindings[0].firstBound, scope);
2898
							}
2899
2900
						}
2827
					}
2901
					}
2828
					proposal.setRequiredProposals(subProposals);
2829
				}
2902
				}
2830
				proposal.setCompletion(classField);
2903
			} else if(parent instanceof UnaryExpression) {
2831
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
2904
				switch(operator) {
2832
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2905
					case OperatorIds.NOT :
2833
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2906
						addExpectedType(TypeBinding.BOOLEAN, scope);
2834
				proposal.setRelevance(relevance);
2907
						break;
2835
				this.requestor.accept(proposal);
2908
					case OperatorIds.TWIDDLE :
2836
				if(DEBUG) {
2909
						addExpectedType(TypeBinding.SHORT, scope);
2837
					this.printDebug(proposal);
2910
						addExpectedType(TypeBinding.INT, scope);
2911
						addExpectedType(TypeBinding.LONG, scope);
2912
						addExpectedType(TypeBinding.CHAR, scope);
2913
						addExpectedType(TypeBinding.BYTE, scope);
2914
						break;
2915
					case OperatorIds.PLUS :
2916
					case OperatorIds.MINUS :
2917
					case OperatorIds.PLUS_PLUS :
2918
					case OperatorIds.MINUS_MINUS :
2919
						addExpectedType(TypeBinding.SHORT, scope);
2920
						addExpectedType(TypeBinding.INT, scope);
2921
						addExpectedType(TypeBinding.LONG, scope);
2922
						addExpectedType(TypeBinding.FLOAT, scope);
2923
						addExpectedType(TypeBinding.DOUBLE, scope);
2924
						addExpectedType(TypeBinding.CHAR, scope);
2925
						addExpectedType(TypeBinding.BYTE, scope);
2926
						break;
2927
				}
2928
			}
2929
		} else if(parent instanceof ArrayReference) {
2930
			addExpectedType(TypeBinding.SHORT, scope);
2931
			addExpectedType(TypeBinding.INT, scope);
2932
			addExpectedType(TypeBinding.LONG, scope);
2933
		} else if(parent instanceof ParameterizedSingleTypeReference) {
2934
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
2935
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2936
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
2937
			if(typeVariables != null && typeVariables.length >= length) {
2938
				int index = length - 1;
2939
				while(index > -1 && ref.typeArguments[index] != node) index--;
2940
2941
				TypeBinding bound = typeVariables[index].firstBound;
2942
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2943
			}
2944
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
2945
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
2946
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2947
			TypeReference[][] arguments = ref.typeArguments;
2948
			if(typeVariables != null) {
2949
				int iLength = arguments == null ? 0 : arguments.length;
2950
				done: for (int i = 0; i < iLength; i++) {
2951
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
2952
					for (int j = 0; j < jLength; j++) {
2953
						if(arguments[i][j] == node && typeVariables.length > j) {
2954
							TypeBinding bound = typeVariables[j].firstBound;
2955
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2956
							break done;
2957
						}
2958
					}
2959
				}
2960
			}
2961
		} else if(parent instanceof MemberValuePair) {
2962
			MemberValuePair memberValuePair = (MemberValuePair) parent;
2963
			if(memberValuePair.binding != null) {
2964
				addExpectedType(memberValuePair.binding.returnType, scope);
2965
			}
2966
		} else if (parent instanceof NormalAnnotation) {
2967
			NormalAnnotation annotation = (NormalAnnotation) parent;
2968
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
2969
			if(memberValuePairs == null || memberValuePairs.length == 0) {
2970
				if(annotation.resolvedType instanceof ReferenceBinding) {
2971
					MethodBinding[] methodBindings =
2972
						((ReferenceBinding)annotation.resolvedType).availableMethods();
2973
					if (methodBindings != null &&
2974
							methodBindings.length > 0 &&
2975
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
2976
						boolean canBeSingleMemberAnnotation = true;
2977
						done : for (int i = 1; i < methodBindings.length; i++) {
2978
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
2979
								canBeSingleMemberAnnotation = false;
2980
								break done;
2981
							}
2982
						}
2983
						if (canBeSingleMemberAnnotation) {
2984
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
2985
							addExpectedType(methodBindings[0].returnType, scope);
2986
						}
2987
					}
2988
				}
2989
			}
2990
		} else if (parent instanceof TryStatement) {
2991
			boolean isException = false;
2992
			if (node instanceof CompletionOnSingleTypeReference) {
2993
				isException = ((CompletionOnSingleTypeReference)node).isException();
2994
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
2995
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
2996
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
2997
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
2998
			}
2999
			if (isException) {
3000
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
3001
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
3002
				if (bindings != null && bindings.length > 0) {
3003
					for (int i = 0; i < bindings.length; i++) {
3004
						addExpectedType(bindings[i], scope);
3005
					}
3006
					this.expectedTypesFilter = SUPERTYPE;
3007
				}
3008
			}
3009
		} else if (parent instanceof SwitchStatement) {
3010
			SwitchStatement switchStatement = (SwitchStatement) parent;
3011
			if (switchStatement.expression != null &&
3012
					switchStatement.expression.resolvedType != null) {
3013
				addExpectedType(switchStatement.expression.resolvedType, scope);
3014
			}
3015
3016
		// Expected types for javadoc
3017
		} else if (parent instanceof Javadoc) {
3018
			if (scope.kind == Scope.METHOD_SCOPE) {
3019
				MethodScope methodScope = (MethodScope) scope;
3020
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
3021
				if (methodDecl != null && methodDecl.binding != null) {
3022
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
3023
					if (exceptions != null) {
3024
						for (int i = 0; i < exceptions.length; i++) {
3025
							addExpectedType(exceptions[i], scope);
3026
						}
3027
					}
2838
				}
3028
				}
2839
			}
3029
			}
2840
		}
3030
		}
3031
3032
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
3033
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
3034
		}
2841
	}
3035
	}
2842
3036
2843
	private void findEnumConstants(
3037
	private void computeExpectedTypesForAllocationExpression(
2844
			char[] enumConstantName,
3038
		ReferenceBinding binding,
2845
			ReferenceBinding enumType,
3039
		Expression[] arguments,
2846
			Scope invocationScope,
3040
		Scope scope,
2847
			ObjectVector fieldsFound,
3041
		InvocationSite invocationSite) {
2848
			char[][] alreadyUsedConstants,
2849
			int alreadyUsedConstantCount,
2850
			boolean needQualification) {
2851
3042
2852
		FieldBinding[] fields = enumType.fields();
3043
		MethodBinding[] methods = binding.availableMethods();
3044
		nextMethod : for (int i = 0; i < methods.length; i++) {
3045
			MethodBinding method = methods[i];
2853
3046
2854
		int enumConstantLength = enumConstantName.length;
3047
			if (!method.isConstructor()) continue nextMethod;
2855
		next : for (int f = fields.length; --f >= 0;) {
2856
			FieldBinding field = fields[f];
2857
3048
2858
			if (field.isSynthetic()) continue next;
3049
			if (method.isSynthetic()) continue nextMethod;
2859
3050
2860
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
3051
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
2861
3052
2862
			if (enumConstantLength > field.name.length) continue next;
3053
			TypeBinding[] parameters = method.parameters;
3054
			if(parameters.length < arguments.length)
3055
				continue nextMethod;
2863
3056
2864
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
3057
			int length = arguments.length - 1;
2865
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
2866
3058
2867
			char[] fieldName = field.name;
3059
			for (int j = 0; j < length; j++) {
3060
				Expression argument = arguments[j];
3061
				TypeBinding argType = argument.resolvedType;
3062
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
3063
					continue nextMethod;
3064
			}
2868
3065
2869
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
3066
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2870
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
3067
			if(expectedType != null) {
3068
				addExpectedType(expectedType, scope);
2871
			}
3069
			}
3070
		}
3071
	}
3072
	private void computeExpectedTypesForMessageSend(
3073
		ReferenceBinding binding,
3074
		char[] selector,
3075
		Expression[] arguments,
3076
		ReferenceBinding receiverType,
3077
		Scope scope,
3078
		InvocationSite invocationSite,
3079
		boolean isStatic) {
2872
3080
2873
			int relevance = computeBaseRelevance();
3081
		MethodBinding[] methods = binding.availableMethods();
2874
			relevance += computeRelevanceForResolution();
3082
		nextMethod : for (int i = 0; i < methods.length; i++) {
2875
			relevance += computeRelevanceForInterestingProposal(field);
3083
			MethodBinding method = methods[i];
2876
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
2877
			relevance += computeRelevanceForExpectingType(field.type);
2878
			relevance += computeRelevanceForEnumConstant(field.type);
2879
			relevance += computeRelevanceForQualification(needQualification);
2880
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2881
3084
2882
			this.noProposal = false;
3085
			if (method.isSynthetic()) continue nextMethod;
2883
			if (!needQualification) {
2884
				char[] completion = fieldName;
2885
3086
2886
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3087
			if (method.isDefaultAbstract())	continue nextMethod;
2887
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2888
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
2889
					proposal.setSignature(getSignature(field.type));
2890
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
2891
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
2892
					proposal.setPackageName(field.type.qualifiedPackageName());
2893
					proposal.setTypeName(field.type.qualifiedSourceName());
2894
					proposal.setName(field.name);
2895
					proposal.setCompletion(completion);
2896
					proposal.setFlags(field.modifiers);
2897
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2898
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2899
					proposal.setRelevance(relevance);
2900
					this.requestor.accept(proposal);
2901
					if(DEBUG) {
2902
						this.printDebug(proposal);
2903
					}
2904
				}
2905
3088
2906
			} else {
3089
			if (method.isConstructor()) continue nextMethod;
2907
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
2908
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
2909
3090
2910
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
3091
			if (isStatic && !method.isStatic()) continue nextMethod;
2911
3092
2912
				if (!needImport) {
3093
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
2913
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2914
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2915
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
2916
						proposal.setSignature(getSignature(field.type));
2917
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
2918
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
2919
						proposal.setPackageName(field.type.qualifiedPackageName());
2920
						proposal.setTypeName(field.type.qualifiedSourceName());
2921
						proposal.setName(field.name);
2922
						proposal.setCompletion(completion);
2923
						proposal.setFlags(field.modifiers);
2924
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2925
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2926
						proposal.setRelevance(relevance);
2927
						this.requestor.accept(proposal);
2928
						if(DEBUG) {
2929
							this.printDebug(proposal);
2930
						}
2931
					}
2932
				} else {
2933
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
2934
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
2935
						int importStart = cu.types[0].declarationSourceStart;
2936
						int importEnd = importStart;
2937
2938
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
2939
2940
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
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
3094
2954
						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
3095
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
2955
3096
2956
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
3097
			TypeBinding[] parameters = method.parameters;
2957
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
3098
			if(parameters.length < arguments.length)
2958
						typeImportProposal.completionEngine = this;
3099
				continue nextMethod;
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
3100
2971
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
3101
			int length = arguments.length - 1;
2972
3102
2973
						this.requestor.accept(proposal);
3103
			for (int j = 0; j < length; j++) {
2974
						if(DEBUG) {
3104
				Expression argument = arguments[j];
2975
							this.printDebug(proposal);
3105
				TypeBinding argType = argument.resolvedType;
2976
						}
3106
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
2977
					}
3107
					continue nextMethod;
2978
				}
2979
			}
3108
			}
2980
		}
2981
	}
2982
3109
2983
	private void findEnumConstantsFromExpectedTypes(
3110
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2984
			char[] token,
3111
			if(expectedType != null) {
2985
			Scope invocationScope,
3112
				addExpectedType(expectedType, scope);
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
			}
3113
			}
2999
		}
3114
		}
3000
3001
	}
3115
	}
3116
	private void computeExpectedTypesForMessageSendForInterface(
3117
		ReferenceBinding binding,
3118
		char[] selector,
3119
		Expression[] arguments,
3120
		ReferenceBinding receiverType,
3121
		Scope scope,
3122
		InvocationSite invocationSite,
3123
		boolean isStatic) {
3002
3124
3003
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
3125
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
3004
		TypeBinding expressionType = switchStatement.expression.resolvedType;
3126
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3005
		if(expressionType != null && expressionType.isEnum()) {
3127
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
3006
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
3128
			int nextPosition = interfacesToVisit.length;
3007
3129
3008
			CaseStatement[] cases = switchStatement.cases;
3130
			for (int i = 0; i < nextPosition; i++) {
3131
				ReferenceBinding currentType = interfacesToVisit[i];
3132
				computeExpectedTypesForMessageSend(
3133
					currentType,
3134
					selector,
3135
					arguments,
3136
					receiverType,
3137
					scope,
3138
					invocationSite,
3139
					isStatic);
3009
3140
3010
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
3141
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
3011
			int alreadyUsedConstantCount = 0;
3142
					int itsLength = itsInterfaces.length;
3012
			for (int i = 0; i < switchStatement.caseCount; i++) {
3143
					if (nextPosition + itsLength >= interfacesToVisit.length)
3013
				Expression caseExpression = cases[i].constantExpression;
3144
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3014
				if((caseExpression instanceof SingleNameReference)
3145
					nextInterface : for (int a = 0; a < itsLength; a++) {
3015
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
3146
						ReferenceBinding next = itsInterfaces[a];
3016
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
3147
						for (int b = 0; b < nextPosition; b++)
3148
							if (next == interfacesToVisit[b]) continue nextInterface;
3149
						interfacesToVisit[nextPosition++] = next;
3150
					}
3017
				}
3151
				}
3018
			}
3152
			}
3019
3020
			findEnumConstants(
3021
					enumConstantName,
3022
					enumType,
3023
					null /* doesn't need invocation scope */,
3024
					new ObjectVector(),
3025
					alreadyUsedConstants,
3026
					alreadyUsedConstantCount,
3027
					false);
3028
		}
3153
		}
3029
	}
3154
	}
3030
3155
3031
	private void findExceptionFromTryStatement(
3156
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
3032
			char[] typeName,
3157
		this.forbbidenBindingsFilter = NONE;
3033
			ReferenceBinding exceptionType,
3158
		if(scope instanceof ClassScope) {
3034
			ReferenceBinding receiverType,
3159
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
3035
			SourceTypeBinding invocationType,
3160
			if(typeDeclaration.superclass == astNode) {
3036
			BlockScope scope,
3161
				addForbiddenBindings(typeDeclaration.binding);
3037
			ObjectVector typesFound,
3162
				return scope.parent;
3038
			boolean searchSuperClasses) {
3163
			}
3039
3164
			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
3040
		if (searchSuperClasses) {
3165
			int length = superInterfaces == null ? 0 : superInterfaces.length;
3041
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
3166
			for (int i = 0; i < length; i++) {
3042
			if (exceptionType != javaLangThrowable) {
3167
				if(superInterfaces[i] == astNode) {
3043
				ReferenceBinding superClass = exceptionType.superclass();
3168
					addForbiddenBindings(typeDeclaration.binding);
3044
				while(superClass != null && superClass != javaLangThrowable) {
3169
					return scope.parent;
3045
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
3046
					superClass = superClass.superclass();
3047
				}
3170
				}
3048
			}
3171
			}
3049
		}
3172
		} else {
3050
3173
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
3051
		if (typeName.length > exceptionType.sourceName.length)
3174
				boolean isException = false;
3052
			return;
3175
				if (astNode instanceof CompletionOnSingleTypeReference) {
3053
3176
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
3054
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
3177
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
3055
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
3178
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
3056
			return;
3179
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
3057
3180
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
3058
		if (this.options.checkDeprecation &&
3181
				}
3059
				exceptionType.isViewedAsDeprecated() &&
3182
				if (isException) {
3060
				!scope.isDefinedInSameUnit(exceptionType))
3183
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
3061
			return;
3184
					int length = catchArguments == null ? 0 : catchArguments.length;
3062
3185
					for (int i = 0; i < length; i++) {
3063
		if (this.options.checkVisibility) {
3186
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
3064
			if (invocationType != null) {
3187
						if (caughtException != null) {
3065
				if (receiverType != null) {
3188
							addForbiddenBindings(caughtException);
3066
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
3189
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
3067
				} else {
3190
						}
3068
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
3191
					}
3192
					this.forbbidenBindingsFilter = SUBTYPE;
3069
				}
3193
				}
3070
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
3071
				return;
3072
			}
3194
			}
3073
		}
3195
		}
3196
//		else if(scope instanceof MethodScope) {
3197
//			MethodScope methodScope = (MethodScope) scope;
3198
//			if(methodScope.insideTypeAnnotation) {
3199
//				return methodScope.parent.parent;
3200
//			}
3201
//		}
3202
		return scope;
3203
	}
3074
3204
3075
		for (int j = typesFound.size; --j >= 0;) {
3205
	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
3076
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
3077
3078
			if (exceptionType == otherType)
3079
				return;
3080
3081
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
3082
3206
3083
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
3207
		StringBuffer completion = new StringBuffer(10);
3084
					return;
3085
3208
3086
				if (otherType.enclosingType().isInterface())
3209
		if (isStatic) {
3087
					if (exceptionType.enclosingType()
3210
			completion.append(declarationType.sourceName());
3088
						.implementsInterface(otherType.enclosingType(), true))
3089
						return;
3090
3211
3091
				if (exceptionType.enclosingType().isInterface())
3212
		} else if (declarationType == invocationType) {
3092
					if (otherType.enclosingType()
3213
			completion.append(THIS);
3093
						.implementsInterface(exceptionType.enclosingType(), true))
3094
						return;
3095
			}
3096
		}
3097
3214
3098
		typesFound.add(exceptionType);
3215
		} else {
3099
3216
3100
		char[] completionName = exceptionType.sourceName();
3217
			if (!declarationType.isNestedType()) {
3101
3218
3102
		boolean isQualified = false;
3219
				completion.append(declarationType.sourceName());
3220
				completion.append('.');
3221
				completion.append(THIS);
3103
3222
3104
		if(!this.insideQualifiedReference) {
3223
			} else if (!declarationType.isAnonymousType()) {
3105
			isQualified = true;
3106
3224
3107
			char[] memberPackageName = exceptionType.qualifiedPackageName();
3225
				completion.append(declarationType.sourceName());
3108
			char[] memberTypeName = exceptionType.sourceName();
3226
				completion.append('.');
3109
			char[] memberEnclosingTypeNames = null;
3227
				completion.append(THIS);
3110
3228
3111
			ReferenceBinding enclosingType = exceptionType.enclosingType();
3112
			if (enclosingType != null) {
3113
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
3114
			}
3229
			}
3230
		}
3115
3231
3116
			Scope currentScope = scope;
3232
		return completion.toString().toCharArray();
3117
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
3233
	}
3118
3234
3119
				switch (currentScope.kind) {
3235
	private int computeRelevanceForAnnotation(){
3120
3236
		if(this.assistNodeIsAnnotation) {
3121
					case Scope.METHOD_SCOPE :
3237
			return R_ANNOTATION;
3122
					case Scope.BLOCK_SCOPE :
3238
		}
3123
						BlockScope blockScope = (BlockScope) currentScope;
3239
		return 0;
3124
3240
	}
3125
						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
3126
3127
							if (blockScope.subscopes[j] instanceof ClassScope) {
3128
								SourceTypeBinding localType =
3129
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
3130
3131
								if (localType == exceptionType) {
3132
									isQualified = false;
3133
									break done;
3134
								}
3135
							}
3136
						}
3137
						break;
3138
3139
					case Scope.CLASS_SCOPE :
3140
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
3141
						ReferenceBinding[] memberTypes = type.memberTypes();
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
3151
3152
						break;
3153
3241
3154
					case Scope.COMPILATION_UNIT_SCOPE :
3242
	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
3155
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
3243
		if (this.assistNodeIsAnnotation &&
3156
						if (types != null) {
3244
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
3157
							for (int j = 0; j < types.length; j++) {
3245
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
3158
								if (types[j] == exceptionType) {
3246
			if(target == 0 || (target & this.targetedElement) != 0) {
3159
									isQualified = false;
3247
				return R_TARGET;
3160
									break done;
3161
								}
3162
							}
3163
						}
3164
						break done;
3165
				}
3166
				currentScope = currentScope.parent;
3167
			}
3248
			}
3168
3249
		}
3169
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
3250
		return 0;
3170
				if (memberPackageName == null || memberPackageName.length == 0)
3251
	}
3171
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
3252
	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
3172
						return; // ignore types from the default package from outside it
3253
		if (this.options.camelCaseMatch) {
3173
			} else {
3254
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3174
				isQualified = false;
3255
				return R_CASE + R_EXACT_NAME;
3256
			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3257
				return R_CASE;
3258
			} else if (CharOperation.camelCaseMatch(token, proposalName)){
3259
				return R_CAMEL_CASE;
3260
			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3261
				return R_EXACT_NAME;
3175
			}
3262
			}
3176
3263
		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3177
			if (isQualified) {
3264
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3178
				completionName =
3265
				return R_CASE + R_EXACT_NAME;
3179
					CharOperation.concat(
3266
			} else {
3180
							memberPackageName,
3267
				return R_CASE;
3181
							CharOperation.concat(
3182
									memberEnclosingTypeNames,
3183
									memberTypeName,
3184
									'.'),
3185
							'.');
3186
			}
3268
			}
3269
		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3270
			return R_EXACT_NAME;
3187
		}
3271
		}
3272
		return 0;
3273
	}
3188
3274
3189
		int relevance = computeBaseRelevance();
3275
	private int computeRelevanceForClass(){
3190
		relevance += computeRelevanceForResolution();
3276
		if(this.assistNodeIsClass) {
3191
		relevance += computeRelevanceForInterestingProposal();
3277
			return R_CLASS;
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
		}
3278
		}
3198
		relevance += computeRelevanceForClass();
3279
		return 0;
3199
		relevance += computeRelevanceForException();
3280
	}
3200
3281
3201
		this.noProposal = false;
3282
	private int computeRelevanceForEnum(){
3202
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3283
		if(this.assistNodeIsEnum) {
3203
			createTypeProposal(
3284
			return R_ENUM;
3204
					exceptionType,
3205
					exceptionType.qualifiedSourceName(),
3206
					IAccessRule.K_ACCESSIBLE,
3207
					completionName,
3208
					relevance,
3209
					null,
3210
					null,
3211
					null,
3212
					false);
3213
		}
3285
		}
3286
		return 0;
3214
	}
3287
	}
3215
3288
3216
	private void findExceptionFromTryStatement(
3289
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
3217
			char[] typeName,
3290
		if(this.assistNodeIsEnum &&
3218
			ReferenceBinding receiverType,
3291
				proposalType != null &&
3219
			SourceTypeBinding invocationType,
3292
				this.expectedTypes != null) {
3220
			BlockScope scope,
3293
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3221
			ObjectVector typesFound) {
3294
				if (proposalType.isEnum() &&
3295
						proposalType == this.expectedTypes[i]) {
3296
					return R_ENUM + R_ENUM_CONSTANT;
3297
				}
3222
3298
3223
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
3299
			}
3224
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
3300
		}
3301
		return 0;
3302
	}
3225
3303
3226
			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
3304
	private int computeRelevanceForException(){
3305
		if (this.assistNodeIsException) {
3306
			return R_EXCEPTION;
3227
		}
3307
		}
3308
		return 0;
3228
	}
3309
	}
3229
	private void findExplicitConstructors(
3230
		char[] name,
3231
		ReferenceBinding currentType,
3232
		MethodScope scope,
3233
		InvocationSite invocationSite) {
3234
3310
3235
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
3311
	private int computeRelevanceForException(char[] proposalName){
3236
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
3237
3312
3238
		// No visibility checks can be performed without the scope & invocationSite
3313
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
3239
		MethodBinding[] methods = currentType.availableMethods();
3314
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
3240
		if(methods != null) {
3315
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
3241
			next : for (int f = methods.length; --f >= 0;) {
3316
			return R_EXCEPTION;
3242
				MethodBinding constructor = methods[f];
3317
		}
3243
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
3318
		return 0;
3319
	}
3244
3320
3245
					if (constructor.isSynthetic()) continue next;
3321
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
3322
		if(this.expectedTypes != null) {
3323
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3324
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
3325
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
3326
					return R_EXACT_EXPECTED_TYPE;
3327
				}
3328
			}
3329
			if(this.hasJavaLangObjectAsExpectedType) {
3330
				return R_EXPECTED_TYPE;
3331
			}
3332
		}
3333
		return 0;
3334
	}
3246
3335
3247
					if (this.options.checkDeprecation &&
3336
	private int computeRelevanceForExpectingType(TypeBinding proposalType){
3248
							constructor.isViewedAsDeprecated() &&
3337
		if(this.expectedTypes != null && proposalType != null) {
3249
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3338
			int relevance = 0;
3250
						continue next;
3339
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3340
				if((this.expectedTypesFilter & SUBTYPE) != 0
3341
						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
3251
3342
3252
					if (this.options.checkVisibility
3343
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3253
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
3344
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3345
						return R_EXACT_EXPECTED_TYPE;
3346
					}
3254
3347
3255
					TypeBinding[] parameters = constructor.parameters;
3348
					relevance = R_EXPECTED_TYPE;
3256
					int paramLength = parameters.length;
3349
				}
3350
				if((this.expectedTypesFilter & SUPERTYPE) != 0
3351
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
3257
3352
3258
					char[][] parameterPackageNames = new char[paramLength][];
3353
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3259
					char[][] parameterTypeNames = new char[paramLength][];
3354
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3260
					for (int i = 0; i < paramLength; i++) {
3355
						return R_EXACT_EXPECTED_TYPE;
3261
						TypeBinding type = parameters[i];
3262
						parameterPackageNames[i] = type.qualifiedPackageName();
3263
						parameterTypeNames[i] = type.qualifiedSourceName();
3264
					}
3356
					}
3265
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3266
3357
3267
					char[] completion = CharOperation.NO_CHAR;
3358
					relevance = R_EXPECTED_TYPE;
3268
					if (this.source != null
3359
				}
3269
						&& this.source.length > this.endPosition
3360
			}
3270
						&& this.source[this.endPosition] == '(')
3361
			return relevance;
3271
						completion = name;
3362
		}
3272
					else
3363
		return 0;
3273
						completion = CharOperation.concat(name, new char[] { '(', ')' });
3364
	}
3274
3365
3275
					int relevance = computeBaseRelevance();
3366
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
3276
					relevance += computeRelevanceForResolution();
3367
		if (receiverType == declaringClass) return R_NON_INHERITED;
3277
					relevance += computeRelevanceForInterestingProposal();
3368
		return 0;
3278
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
3369
	}
3279
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3280
3370
3281
					this.noProposal = false;
3371
	int computeRelevanceForInterestingProposal(){
3282
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
3372
		return computeRelevanceForInterestingProposal(null);
3283
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3373
	}
3284
						proposal.setDeclarationSignature(getSignature(currentType));
3374
3285
						proposal.setSignature(getSignature(constructor));
3375
	private int computeRelevanceForInterestingProposal(Binding binding){
3286
						MethodBinding original = constructor.original();
3376
		if(this.uninterestingBindings != null) {
3287
						if(original != constructor) {
3377
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
3288
							proposal.setOriginalSignature(getSignature(original));
3378
				if(this.uninterestingBindings[i] == binding) {
3289
						}
3379
					return 0;
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
						}
3308
					}
3309
				}
3380
				}
3310
			}
3381
			}
3311
		}
3382
		}
3383
		return R_INTERESTING;
3312
	}
3384
	}
3313
	private void findConstructors(
3314
		ReferenceBinding currentType,
3315
		TypeBinding[] argTypes,
3316
		Scope scope,
3317
		InvocationSite invocationSite,
3318
		boolean forAnonymousType) {
3319
3385
3320
		// No visibility checks can be performed without the scope & invocationSite
3386
	private int computeRelevanceForInterface(){
3321
		MethodBinding[] methods = currentType.availableMethods();
3387
		if(this.assistNodeIsInterface) {
3322
		if(methods != null) {
3388
			return R_INTERFACE;
3323
			int minArgLength = argTypes == null ? 0 : argTypes.length;
3389
		}
3324
			next : for (int f = methods.length; --f >= 0;) {
3390
		return 0;
3325
				MethodBinding constructor = methods[f];
3391
	}
3326
				if (constructor.isConstructor()) {
3327
3392
3328
					if (constructor.isSynthetic()) continue next;
3393
	private int computeRelevanceForMissingElements(boolean hasProblems) {
3394
		if (!hasProblems) {
3395
			return R_NO_PROBLEMS;
3396
		}
3397
		return 0;
3398
	}
3399
	int computeRelevanceForQualification(boolean prefixRequired) {
3400
		if(!prefixRequired && !this.insideQualifiedReference) {
3401
			return R_UNQUALIFIED;
3402
		}
3329
3403
3330
					if (this.options.checkDeprecation &&
3404
		if(prefixRequired && this.insideQualifiedReference) {
3331
							constructor.isViewedAsDeprecated() &&
3405
			return R_QUALIFIED;
3332
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3406
		}
3333
						continue next;
3407
		return 0;
3408
	}
3334
3409
3335
					if (this.options.checkVisibility
3410
	int computeRelevanceForResolution(){
3336
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
3411
		return computeRelevanceForResolution(true);
3337
						if(!forAnonymousType || !constructor.isProtected())
3412
	}
3338
							continue next;
3339
					}
3340
3413
3341
					TypeBinding[] parameters = constructor.parameters;
3414
	int computeRelevanceForResolution(boolean isResolved){
3342
					int paramLength = parameters.length;
3415
		if (isResolved) {
3343
					if (minArgLength > paramLength)
3416
			return R_RESOLVED;
3344
						continue next;
3417
		}
3345
					for (int a = minArgLength; --a >= 0;)
3418
		return 0;
3346
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
3419
	}
3347
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
3348
								continue next;
3349
						}
3350
3420
3351
					char[][] parameterPackageNames = new char[paramLength][];
3421
	int computeRelevanceForRestrictions(int accessRuleKind) {
3352
					char[][] parameterTypeNames = new char[paramLength][];
3422
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
3353
					for (int i = 0; i < paramLength; i++) {
3423
			return R_NON_RESTRICTED;
3354
						TypeBinding type = parameters[i];
3424
		}
3355
						parameterPackageNames[i] = type.qualifiedPackageName();
3425
		return 0;
3356
						parameterTypeNames[i] = type.qualifiedSourceName();
3426
	}
3357
					}
3358
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3359
3427
3360
					char[] completion = CharOperation.NO_CHAR;
3428
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
3361
					if(forAnonymousType){
3429
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
3362
						int relevance = computeBaseRelevance();
3430
			return R_NON_STATIC;
3363
						relevance += computeRelevanceForResolution();
3431
		}
3364
						relevance += computeRelevanceForInterestingProposal();
3432
		return 0;
3365
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3433
	}
3366
3434
3367
						this.noProposal = false;
3435
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
3368
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
3436
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
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
3437
3401
						// Special case for completion in javadoc
3438
		if (annotatedElement instanceof TypeDeclaration) {
3402
						if (this.assistNodeInJavadoc > 0) {
3439
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
3403
							Expression receiver = null;
3440
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
3404
							char[] selector = null;
3441
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
3405
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
3442
			}
3406
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
3443
			return TagBits.AnnotationForType;
3407
								receiver = alloc.type;
3444
		} else if (annotatedElement instanceof FieldDeclaration) {
3408
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3445
			if (fakeNode.isParameter) {
3409
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3446
				return TagBits.AnnotationForParameter;
3410
								receiver = fieldRef.receiver;
3447
			}
3411
							}
3448
			return TagBits.AnnotationForField;
3412
							if (receiver != null) {
3449
		} else if (annotatedElement instanceof MethodDeclaration) {
3413
								StringBuffer javadocCompletion = new StringBuffer();
3450
			return TagBits.AnnotationForMethod;
3414
								if (receiver.isThis()) {
3451
		} else if (annotatedElement instanceof Argument) {
3415
									selector = (((JavadocImplicitTypeReference)receiver).token);
3452
			return TagBits.AnnotationForParameter;
3416
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3453
		} else if (annotatedElement instanceof ConstructorDeclaration) {
3417
										javadocCompletion.append('#');
3454
			return TagBits.AnnotationForConstructor;
3418
									}
3455
		} else if (annotatedElement instanceof LocalDeclaration) {
3419
								} else if (receiver instanceof JavadocSingleTypeReference) {
3456
			return TagBits.AnnotationForLocalVariable;
3420
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
3457
		} else if (annotatedElement instanceof ImportReference) {
3421
									selector = typeRef.token;
3458
			return TagBits.AnnotationForPackage;
3422
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3459
		}
3423
										javadocCompletion.append(typeRef.token);
3460
		return 0;
3424
										javadocCompletion.append('#');
3461
	}
3425
									}
3462
	private TypeBinding[] computeTypes(Expression[] arguments) {
3426
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
3463
		if (arguments == null) return null;
3427
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
3464
		int argsLength = arguments.length;
3428
									selector = typeRef.tokens[typeRef.tokens.length-1];
3465
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3429
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3466
		for (int a = argsLength; --a >= 0;) {
3430
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
3467
			argTypes[a] = arguments[a].resolvedType;
3431
										javadocCompletion.append('#');
3468
		}
3432
									}
3469
		return argTypes;
3433
								}
3470
	}
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
3471
3454
						// Create standard proposal
3472
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
3455
						this.noProposal = false;
3473
		if (arguments == null) return null;
3456
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3474
		int argsLength = arguments.length;
3457
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3475
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3458
							proposal.setDeclarationSignature(getSignature(currentType));
3476
		for (int a = argsLength; --a >= 0;) {
3459
							proposal.setSignature(getSignature(constructor));
3477
			TypeBinding typeBinding = arguments[a].resolvedType;
3460
							MethodBinding original = constructor.original();
3478
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
3461
							if(original != constructor) {
3479
			argTypes[a] = typeBinding;
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
		}
3480
		}
3481
		return argTypes;
3517
	}
3482
	}
3518
3483
3519
	private char[][] findEnclosingTypeNames(Scope scope){
3484
	private void computeUninterestingBindings(ASTNode parent, Scope scope){
3520
		char[][] excludedNames = new char[10][];
3485
		if(parent instanceof LocalDeclaration) {
3521
		int excludedNameCount = 0;
3486
			addUninterestingBindings(((LocalDeclaration)parent).binding);
3522
3487
		} else if (parent instanceof FieldDeclaration) {
3523
		Scope currentScope = scope;
3488
			addUninterestingBindings(((FieldDeclaration)parent).binding);
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
		}
3489
		}
3490
	}
3566
3491
3567
		if(excludedNameCount == 0) {
3492
	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
3568
			return CharOperation.NO_CHAR_CHAR;
3493
		char[] result = IMPORT;
3494
		if (isStatic) {
3495
			result = CharOperation.concat(result, STATIC, ' ');
3569
		}
3496
		}
3570
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
3497
		result = CharOperation.concat(result, importedElement, ' ');
3571
		return excludedNames;
3498
		if (onDemand) {
3499
			result = CharOperation.concat(result, ON_DEMAND);
3500
		}
3501
		return CharOperation.concat(result, IMPORT_END);
3572
	}
3502
	}
3573
3503
3574
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
3504
	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
3575
	private void findFields(
3505
		//// Modifiers
3576
		char[] fieldName,
3506
		// flush uninteresting modifiers
3577
		FieldBinding[] fields,
3507
		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
3578
		Scope scope,
3508
		if(insertedModifiers != ClassFileConstants.AccDefault){
3579
		ObjectVector fieldsFound,
3509
			ASTNode.printModifiers(insertedModifiers, completion);
3580
		ObjectVector localsFound,
3510
		}
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
3511
3599
		int fieldLength = fieldName.length;
3512
		//// Type parameters
3600
		next : for (int f = fields.length; --f >= 0;) {
3601
			FieldBinding field = fields[f];
3602
3513
3603
			if (field.isSynthetic())	continue next;
3514
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
3515
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
3516
			completion.append('<');
3517
			for (int i = 0; i < typeVariableBindings.length; i++) {
3518
				if(i != 0) {
3519
					completion.append(',');
3520
					completion.append(' ');
3521
				}
3522
				createTypeVariable(typeVariableBindings[i], scope, completion);
3523
			}
3524
			completion.append('>');
3525
			completion.append(' ');
3526
		}
3604
3527
3605
			if (onlyStaticFields && !field.isStatic()) continue next;
3528
		//// Return type
3529
		createType(method.returnType, scope, completion);
3530
		completion.append(' ');
3606
3531
3607
			if (fieldLength > field.name.length) continue next;
3532
		//// Selector
3533
		completion.append(method.selector);
3608
3534
3609
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
3535
		completion.append('(');
3610
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
3611
3536
3612
			if (this.options.checkDeprecation &&
3537
		////Parameters
3613
					field.isViewedAsDeprecated() &&
3538
		TypeBinding[] parameterTypes = method.parameters;
3614
					!scope.isDefinedInSameUnit(field.declaringClass))
3539
		int length = parameterTypes.length;
3615
				continue next;
3540
		for (int i = 0; i < length; i++) {
3541
			if(i != 0) {
3542
				completion.append(',');
3543
				completion.append(' ');
3544
			}
3545
			createType(parameterTypes[i], scope, completion);
3546
			completion.append(' ');
3547
			if(parameterNames != null){
3548
				completion.append(parameterNames[i]);
3549
			} else {
3550
				completion.append('%');
3551
			}
3552
		}
3616
3553
3617
			if (this.options.checkVisibility
3554
		completion.append(')');
3618
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
3619
3555
3620
			boolean prefixRequired = false;
3556
		//// Exceptions
3557
		ReferenceBinding[] exceptions = method.thrownExceptions;
3621
3558
3622
			for (int i = fieldsFound.size; --i >= 0;) {
3559
		if (exceptions != null && exceptions.length > 0){
3623
				Object[] other = (Object[])fieldsFound.elementAt(i);
3560
			completion.append(' ');
3624
				FieldBinding otherField = (FieldBinding) other[0];
3561
			completion.append(THROWS);
3625
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
3562
			completion.append(' ');
3626
				if (field == otherField && receiverType == otherReceiverType)
3563
			for(int i = 0; i < exceptions.length ; i++){
3627
					continue next;
3564
				if(i != 0) {
3628
				if (CharOperation.equals(field.name, otherField.name, true)) {
3565
					completion.append(' ');
3629
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
3566
					completion.append(',');
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
				}
3567
				}
3568
				createType(exceptions[i], scope, completion);
3646
			}
3569
			}
3570
		}
3571
	}
3647
3572
3648
			for (int l = localsFound.size; --l >= 0;) {
3573
	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
3649
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
3574
		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
3650
3575
		proposal.nameLookup = this.nameEnvironment.nameLookup;
3651
				if (CharOperation.equals(field.name, local.name, true)) {
3576
		proposal.completionEngine = this;
3652
					SourceTypeBinding declarationType = scope.enclosingSourceType();
3577
		return proposal;
3653
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
3578
	}
3654
						continue next;
3655
					}
3656
					if(canBePrefixed) {
3657
						prefixRequired = true;
3658
					} else {
3659
						continue next;
3660
					}
3661
					break;
3662
				}
3663
			}
3664
3579
3665
			newFieldsFound.add(new Object[]{field, receiverType});
3580
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
3666
3581
		InternalCompletionProposal proposal = null;
3667
			char[] completion = field.name;
3582
		if (binding instanceof ReferenceBinding) {
3583
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
3668
3584
3669
			if(prefixRequired || this.options.forceImplicitQualification){
3585
			char[] packageName = typeBinding.qualifiedPackageName();
3670
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
3586
			char[] typeName = typeBinding.qualifiedSourceName();
3671
				completion = CharOperation.concat(prefix,completion,'.');
3587
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
3672
			}
3673
3588
3589
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
3590
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3591
			proposal.completionEngine = this;
3592
			proposal.setDeclarationSignature(packageName);
3593
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
3594
			proposal.setPackageName(packageName);
3595
			proposal.setTypeName(typeName);
3596
			proposal.setCompletion(fullyQualifiedName);
3597
			proposal.setFlags(typeBinding.modifiers);
3598
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3599
			proposal.setTokenRange(start - this.offset, end - this.offset);
3600
			proposal.setRelevance(relevance);
3601
		} else if (binding instanceof PackageBinding) {
3602
			PackageBinding packageBinding = (PackageBinding) binding;
3674
3603
3675
			if (castedReceiver != null) {
3604
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
3676
				completion = CharOperation.concat(castedReceiver, completion);
3677
			}
3678
3605
3679
			// Special case for javadoc completion
3606
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
3680
			if (this.assistNodeInJavadoc > 0) {
3607
			proposal.setDeclarationSignature(packageName);
3681
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3608
			proposal.setPackageName(packageName);
3682
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3609
			proposal.setCompletion(packageName);
3683
					if (fieldRef.receiver.isThis()) {
3610
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3684
						if (fieldRef.completeInText()) {
3611
			proposal.setTokenRange(start - this.offset, end - this.offset);
3685
							completion = CharOperation.concat(new char[] { '#' }, field.name);
3612
			proposal.setRelevance(relevance);
3686
						}
3613
		}
3687
					} else if (fieldRef.completeInText()) {
3614
		return proposal;
3688
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
3615
	}
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
3616
3699
			int relevance = computeBaseRelevance();
3617
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
3700
			relevance += computeRelevanceForResolution();
3618
		switch (type.kind()) {
3701
			relevance += computeRelevanceForInterestingProposal(field);
3619
			case Binding.BASE_TYPE :
3702
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3620
				completion.append(type.sourceName());
3703
			relevance += computeRelevanceForExpectingType(field.type);
3621
				break;
3704
			relevance += computeRelevanceForEnumConstant(field.type);
3622
			case Binding.WILDCARD_TYPE :
3705
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
3623
			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
3706
			relevance += computeRelevanceForQualification(prefixRequired);
3624
				WildcardBinding wildcardBinding = (WildcardBinding) type;
3707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3625
				completion.append('?');
3708
			if (onlyStaticFields && this.insideQualifiedReference) {
3626
				switch (wildcardBinding.boundKind) {
3709
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
3627
					case Wildcard.EXTENDS:
3710
			}
3628
						completion.append(' ');
3711
			if (missingElements != null) {
3629
						completion.append(EXTENDS);
3712
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3630
						completion.append(' ');
3713
			}
3631
						createType(wildcardBinding.bound, scope, completion);
3632
						if(wildcardBinding.otherBounds != null) {
3714
3633
3715
			this.noProposal = false;
3634
							int length = wildcardBinding.otherBounds.length;
3716
			if (castedReceiver == null) {
3635
							for (int i = 0; i < length; i++) {
3717
				// Standard proposal
3636
								completion.append(' ');
3718
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3637
								completion.append('&');
3719
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3638
								completion.append(' ');
3720
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3639
								createType(wildcardBinding.otherBounds[i], scope, completion);
3721
					proposal.setSignature(getSignature(field.type));
3640
							}
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
						}
3641
						}
3737
						proposal.setRequiredProposals(subProposals);
3642
						break;
3738
					}
3643
					case Wildcard.SUPER:
3739
					proposal.setCompletion(completion);
3644
						completion.append(' ');
3740
					proposal.setFlags(field.modifiers);
3645
						completion.append(SUPER);
3741
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3646
						completion.append(' ');
3742
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3647
						createType(wildcardBinding.bound, scope, completion);
3743
					proposal.setRelevance(relevance);
3648
						break;
3744
					this.requestor.accept(proposal);
3745
					if(DEBUG) {
3746
						this.printDebug(proposal);
3747
					}
3748
				}
3649
				}
3749
3650
				break;
3750
				// Javadoc completions
3651
			case Binding.ARRAY_TYPE :
3751
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
3652
				createType(type.leafComponentType(), scope, completion);
3752
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3653
				int dim = type.dimensions();
3753
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
3654
				for (int i = 0; i < dim; i++) {
3754
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3655
					completion.append('[');
3755
					proposal.setSignature(getSignature(field.type));
3656
					completion.append(']');
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
				}
3657
				}
3793
			} else {
3658
				break;
3794
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
3659
			case Binding.PARAMETERIZED_TYPE :
3795
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
3660
				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
3796
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3661
				if (type.isMemberType()) {
3797
					proposal.setSignature(getSignature(field.type));
3662
					createType(parameterizedType.enclosingType(), scope, completion);
3798
					proposal.setReceiverSignature(getSignature(receiverType));
3663
					completion.append('.');
3799
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3664
					completion.append(parameterizedType.sourceName);
3800
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3665
				} else {
3801
					proposal.setPackageName(field.type.qualifiedPackageName());
3666
					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
3802
					proposal.setTypeName(field.type.qualifiedSourceName());
3667
				}
3803
					proposal.setName(field.name);
3668
				if (parameterizedType.arguments != null) {
3804
					if (missingElements != null) {
3669
					completion.append('<');
3805
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3670
				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
3806
						for (int i = 0; i < missingElements.length; i++) {
3671
				        if (i != 0) completion.append(',');
3807
							subProposals[i] =
3672
				        createType(parameterizedType.arguments[i], scope, completion);
3808
								createRequiredTypeProposal(
3673
				    }
3809
										missingElements[i],
3674
				    completion.append('>');
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
				}
3675
				}
3676
				break;
3677
			default :
3678
				char[] packageName = type.qualifiedPackageName();
3679
			char[] typeName = type.qualifiedSourceName();
3680
			if(mustQualifyType(
3681
					(ReferenceBinding)type,
3682
					packageName,
3683
					scope)) {
3684
				completion.append(CharOperation.concat(packageName, typeName,'.'));
3685
			} else {
3686
				completion.append(type.sourceName());
3827
			}
3687
			}
3688
			break;
3828
		}
3689
		}
3829
3830
		fieldsFound.addAll(newFieldsFound);
3831
	}
3690
	}
3832
3691
3833
	private void findFields(
3692
	/*
3834
		char[] fieldName,
3693
	 * Create a completion proposal for a member type.
3835
		ReferenceBinding receiverType,
3694
	 */
3836
		Scope scope,
3695
	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
3837
		ObjectVector fieldsFound,
3696
		char[] completionName = typeParameter.name;
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
3697
3856
		ReferenceBinding currentType = receiverType;
3698
		// Create standard type proposal
3857
		ReferenceBinding[] interfacesToVisit = null;
3699
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3858
		int nextPosition = 0;
3700
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3859
		do {
3701
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3860
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
3702
			proposal.completionEngine = this;
3861
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
3703
			proposal.setSignature(getSignature(typeParameter.binding));
3862
				if (interfacesToVisit == null) {
3704
			proposal.setTypeName(completionName);
3863
					interfacesToVisit = itsInterfaces;
3705
			proposal.setCompletion(completionName);
3864
					nextPosition = interfacesToVisit.length;
3706
			proposal.setFlags(typeParameter.modifiers);
3865
				} else {
3707
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3866
					int itsLength = itsInterfaces.length;
3708
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3867
					if (nextPosition + itsLength >= interfacesToVisit.length)
3709
			proposal.setRelevance(relevance);
3868
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3710
			this.requestor.accept(proposal);
3869
					nextInterface : for (int a = 0; a < itsLength; a++) {
3711
			if(DEBUG) {
3870
						ReferenceBinding next = itsInterfaces[a];
3712
				this.printDebug(proposal);
3871
						for (int b = 0; b < nextPosition; b++)
3872
							if (next == interfacesToVisit[b]) continue nextInterface;
3873
						interfacesToVisit[nextPosition++] = next;
3874
					}
3875
				}
3876
			}
3713
			}
3714
		}
3877
3715
3878
			FieldBinding[] fields = currentType.availableFields();
3716
		// Create javadoc text proposal if necessary
3879
			if(fields != null && fields.length > 0) {
3717
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3880
				findFields(
3718
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3881
					fieldName,
3719
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3882
					fields,
3720
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3883
					scope,
3721
			proposal.completionEngine = this;
3884
					fieldsFound,
3722
			proposal.setSignature(getSignature(typeParameter.binding));
3885
					localsFound,
3723
			proposal.setTypeName(javadocCompletion);
3886
					onlyStaticFields,
3724
			proposal.setCompletion(javadocCompletion);
3887
					receiverType,
3725
			proposal.setFlags(typeParameter.modifiers);
3888
					invocationSite,
3726
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3889
					invocationScope,
3727
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3890
					implicitCall,
3728
			proposal.setRelevance(relevance+R_INLINE_TAG);
3891
					canBePrefixed,
3729
			this.requestor.accept(proposal);
3892
					missingElements,
3730
			if(DEBUG) {
3893
					missingElementsStarts,
3731
				this.printDebug(proposal);
3894
					missingElementsEnds,
3895
					missingElementsHaveProblems,
3896
					castedReceiver,
3897
					receiverStart,
3898
					receiverEnd);
3899
			}
3732
			}
3900
			currentType = currentType.superclass();
3733
		}
3901
		} while (notInJavadoc && currentType != null);
3734
	}
3902
3735
3903
		if (notInJavadoc && interfacesToVisit != null) {
3736
	/*
3904
			for (int i = 0; i < nextPosition; i++) {
3737
	 * Create a completion proposal for a type.
3905
				ReferenceBinding anInterface = interfacesToVisit[i];
3738
	 */
3906
				FieldBinding[] fields = anInterface.availableFields();
3739
	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
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
3740
3929
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
3741
		// Create standard type proposal
3930
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3742
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3931
					int itsLength = itsInterfaces.length;
3743
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3932
					if (nextPosition + itsLength >= interfacesToVisit.length)
3744
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3933
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3745
			proposal.completionEngine = this;
3934
					nextInterface : for (int a = 0; a < itsLength; a++) {
3746
			proposal.setDeclarationSignature(packageName);
3935
						ReferenceBinding next = itsInterfaces[a];
3747
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
3936
						for (int b = 0; b < nextPosition; b++)
3748
			proposal.setPackageName(packageName);
3937
							if (next == interfacesToVisit[b]) continue nextInterface;
3749
			proposal.setTypeName(typeName);
3938
						interfacesToVisit[nextPosition++] = next;
3750
			proposal.setCompletion(completionName);
3939
					}
3751
			proposal.setFlags(modifiers);
3940
				}
3752
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3753
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3754
			proposal.setRelevance(relevance);
3755
			proposal.setAccessibility(accessibility);
3756
			this.requestor.accept(proposal);
3757
			if(DEBUG) {
3758
				this.printDebug(proposal);
3759
			}
3760
		}
3761
3762
		// Create javadoc text proposal if necessary
3763
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3764
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3765
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3766
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3767
			proposal.completionEngine = this;
3768
			proposal.setDeclarationSignature(packageName);
3769
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
3770
			proposal.setPackageName(packageName);
3771
			proposal.setTypeName(typeName);
3772
			proposal.setCompletion(javadocCompletion);
3773
			proposal.setFlags(modifiers);
3774
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3775
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3776
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3777
			proposal.setRelevance(relevance+R_INLINE_TAG);
3778
			proposal.setAccessibility(accessibility);
3779
			this.requestor.accept(proposal);
3780
			if(DEBUG) {
3781
				this.printDebug(proposal);
3941
			}
3782
			}
3942
		}
3783
		}
3943
	}
3784
	}
3944
3785
3945
	protected void findFieldsAndMethodsFromAnotherReceiver(
3786
	/*
3946
			char[] token,
3787
	 * Create a completion proposal for a member type.
3947
			TypeReference receiverType,
3788
	 */
3948
			Scope scope,
3789
	private void createTypeProposal(
3949
			ObjectVector fieldsFound,
3790
			ReferenceBinding refBinding,
3950
			ObjectVector methodsFound,
3791
			char[] typeName,
3951
			InvocationSite invocationSite,
3792
			int accessibility,
3952
			Scope invocationScope,
3793
			char[] completionName,
3953
			boolean implicitCall,
3794
			int relevance,
3954
			boolean superCall,
3955
			Binding[] missingElements,
3795
			Binding[] missingElements,
3956
			int[] missingElementsStarts,
3796
			int[] missingElementsStarts,
3957
			int[] missingElementsEnds,
3797
			int[] missingElementsEnds,
3958
			boolean missingElementsHaveProblems,
3798
			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
3799
3972
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
3800
		// Create standard type proposal
3973
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
3801
		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3802
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3803
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3804
			proposal.completionEngine = this;
3805
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
3806
			proposal.setSignature(getCompletedTypeSignature(refBinding));
3807
			proposal.setPackageName(refBinding.qualifiedPackageName());
3808
			proposal.setTypeName(typeName);
3809
			if (missingElements != null) {
3810
				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3811
				for (int i = 0; i < missingElements.length; i++) {
3812
					subProposals[i] =
3813
						createRequiredTypeProposal(
3814
								missingElements[i],
3815
								missingElementsStarts[i],
3816
								missingElementsEnds[i],
3817
								relevance);
3818
				}
3819
				proposal.setRequiredProposals(subProposals);
3820
			}
3821
			proposal.setCompletion(completionName);
3822
			proposal.setFlags(refBinding.modifiers);
3823
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3824
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3825
			proposal.setRelevance(relevance);
3826
			this.requestor.accept(proposal);
3827
			if(DEBUG) {
3828
				this.printDebug(proposal);
3829
			}
3830
		}
3974
3831
3975
			castedReceiver =
3832
		// Create javadoc text proposal if necessary
3976
				CharOperation.concat(
3833
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3977
					CharOperation.concat(
3834
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3978
						'(',
3835
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3979
						CharOperation.concat(
3836
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3980
							CharOperation.concat('(', castedTypeChars, ')'),
3837
			proposal.completionEngine = this;
3981
							receiverChars),
3838
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
3982
						')'),
3839
			proposal.setSignature(getCompletedTypeSignature(refBinding));
3983
					dotChars);
3840
			proposal.setPackageName(refBinding.qualifiedPackageName());
3841
			proposal.setTypeName(typeName);
3842
			proposal.setCompletion(javadocCompletion);
3843
			proposal.setFlags(refBinding.modifiers);
3844
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3845
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3846
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3847
			proposal.setRelevance(relevance+R_INLINE_TAG);
3848
			this.requestor.accept(proposal);
3849
			if(DEBUG) {
3850
				this.printDebug(proposal);
3851
			}
3852
		}
3853
	}
3854
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
3855
		completion.append(typeVariable.sourceName);
3856
3857
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
3858
		    completion.append(' ');
3859
		    completion.append(EXTENDS);
3860
		    completion.append(' ');
3861
		    createType(typeVariable.superclass, scope, completion);
3862
		}
3863
		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
3864
		   if (typeVariable.firstBound != typeVariable.superclass) {
3865
			   completion.append(' ');
3866
			   completion.append(EXTENDS);
3867
			   completion.append(' ');
3868
		   }
3869
		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
3870
			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
3871
				   completion.append(' ');
3872
				   completion.append(EXTENDS);
3873
				   completion.append(' ');
3874
			   }
3875
			   createType(typeVariable.superInterfaces[i], scope, completion);
3876
		   }
3877
		}
3878
	}
3879
	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
3880
		if (type.isArrayType()) {
3881
			createType(type.leafComponentType(), scope, completion);
3882
			int dim = type.dimensions() - 1;
3883
			for (int i = 0; i < dim; i++) {
3884
				completion.append('[');
3885
				completion.append(']');
3886
			}
3887
			completion.append(VARARGS);
3984
		} else {
3888
		} else {
3985
			castedReceiver =
3889
			createType(type, scope, completion);
3986
				CharOperation.concat(
3987
					CharOperation.concat(
3988
						'(',
3989
						CharOperation.concat(
3990
							CharOperation.concat('(', castedTypeChars, ')'),
3991
							CharOperation.concatWith(receiverName, '.')),
3992
						')'),
3993
					DOT);
3994
		}
3890
		}
3891
	}
3892
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
3893
		MethodBinding[] methods = annotation.availableMethods();
3894
		nextAttribute: for (int i = 0; i < methods.length; i++) {
3895
			MethodBinding method = methods[i];
3995
3896
3996
		if (castedReceiver == null) return;
3897
			if(!CharOperation.prefixEquals(token, method.selector, false)
3898
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
3997
3899
3998
		int oldStartPosition = this.startPosition;
3900
			int length = attributesFound == null ? 0 : attributesFound.length;
3999
		this.startPosition = receiverStart;
3901
			for (int j = 0; j < length; j++) {
3902
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
3903
			}
4000
3904
4001
		findFieldsAndMethods(
3905
			int relevance = computeBaseRelevance();
4002
				token,
3906
			relevance += computeRelevanceForResolution();
4003
				receiverTypeBinding,
3907
			relevance += computeRelevanceForInterestingProposal(method);
4004
				scope,
3908
			relevance += computeRelevanceForCaseMatching(token, method.selector);
4005
				fieldsFound,
3909
			relevance += computeRelevanceForQualification(false);
4006
				methodsFound,
3910
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4007
				invocationSite,
4008
				invocationScope,
4009
				implicitCall,
4010
				superCall,
4011
				missingElements,
4012
				missingElementsStarts,
4013
				missingElementsEnds,
4014
				missingElementsHaveProblems,
4015
				castedReceiver,
4016
				receiverStart,
4017
				receiverEnd);
4018
3911
4019
		this.startPosition = oldStartPosition;
3912
			this.noProposal = false;
3913
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
3914
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
3915
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
3916
				proposal.setSignature(getSignature(method.returnType));
3917
				proposal.setName(method.selector);
3918
				proposal.setCompletion(method.selector);
3919
				proposal.setFlags(method.modifiers);
3920
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3921
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3922
				proposal.setRelevance(relevance);
3923
				this.requestor.accept(proposal);
3924
				if(DEBUG) {
3925
					this.printDebug(proposal);
3926
				}
3927
			}
3928
		}
4020
	}
3929
	}
4021
	protected void findFieldsAndMethods(
3930
	private void findAnonymousType(
4022
		char[] token,
3931
		ReferenceBinding currentType,
4023
		TypeBinding receiverType,
3932
		TypeBinding[] argTypes,
4024
		Scope scope,
3933
		Scope scope,
4025
		ObjectVector fieldsFound,
3934
		InvocationSite invocationSite) {
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
3935
4039
		if (token == null)
3936
		if (currentType.isInterface()) {
4040
			return;
3937
			char[] completion = CharOperation.NO_CHAR;
3938
			int relevance = computeBaseRelevance();
3939
			relevance += computeRelevanceForResolution();
3940
			relevance += computeRelevanceForInterestingProposal();
3941
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4041
3942
4042
		if (receiverType.isBaseType())
3943
			this.noProposal = false;
4043
			return; // nothing else is possible with base types
3944
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
3945
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
3946
				proposal.setDeclarationSignature(getSignature(currentType));
3947
				proposal.setDeclarationKey(currentType.computeUniqueKey());
3948
				proposal.setSignature(
3949
						createMethodSignature(
3950
								CharOperation.NO_CHAR_CHAR,
3951
								CharOperation.NO_CHAR_CHAR,
3952
								CharOperation.NO_CHAR,
3953
								CharOperation.NO_CHAR));
3954
				//proposal.setOriginalSignature(null);
3955
				//proposal.setUniqueKey(null);
3956
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3957
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3958
				//proposal.setParameterPackageNames(null);
3959
				//proposal.setParameterTypeNames(null);
3960
				//proposal.setPackageName(null);
3961
				//proposal.setTypeName(null);
3962
				proposal.setCompletion(completion);
3963
				proposal.setFlags(Flags.AccPublic);
3964
				proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
3965
				proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
3966
				proposal.setRelevance(relevance);
3967
				this.requestor.accept(proposal);
3968
				if(DEBUG) {
3969
					this.printDebug(proposal);
3970
				}
3971
			}
3972
		} else {
3973
			findConstructors(
3974
				currentType,
3975
				argTypes,
3976
				scope,
3977
				invocationSite,
3978
				true);
3979
		}
3980
	}
3981
	private void findClassField(
3982
			char[] token,
3983
			TypeBinding receiverType,
3984
			Scope scope,
3985
			Binding[] missingElements,
3986
			int[] missingElementsStarts,
3987
			int[] missingElementsEnds,
3988
			boolean missingElementsHaveProblems) {
4044
3989
4045
		boolean proposeField =
3990
		if (token == null) return;
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
3991
4054
		if (receiverType.isArrayType()) {
3992
		if (token.length <= classField.length
4055
			if (proposeField
3993
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
4056
				&& token.length <= lengthField.length
3994
		)) {
4057
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
3995
			int relevance = computeBaseRelevance();
4058
			)) {
3996
			relevance += computeRelevanceForResolution();
3997
			relevance += computeRelevanceForInterestingProposal();
3998
			relevance += computeRelevanceForCaseMatching(token, classField);
3999
			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
4000
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
4001
			relevance += R_NON_INHERITED;
4059
4002
4060
				int relevance = computeBaseRelevance();
4003
			if (missingElements != null) {
4061
				relevance += computeRelevanceForResolution();
4004
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4062
				relevance += computeRelevanceForInterestingProposal();
4005
			}
4063
				relevance += computeRelevanceForCaseMatching(token,lengthField);
4006
4064
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
4007
			this.noProposal = false;
4065
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
4008
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
4066
				if (missingElements != null) {
4009
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4067
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4010
				//proposal.setDeclarationSignature(null);
4011
				char[] signature =
4012
					createNonGenericTypeSignature(
4013
						CharOperation.concatWith(JAVA_LANG, '.'),
4014
						CLASS);
4015
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
4016
					// add type argument
4017
					char[] typeArgument = getTypeSignature(receiverType);
4018
					int oldLength = signature.length;
4019
					int argumentLength = typeArgument.length;
4020
					int newLength = oldLength + argumentLength + 2;
4021
					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
4022
					signature[oldLength - 1] = '<';
4023
					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
4024
					signature[newLength - 2] = '>';
4025
					signature[newLength - 1] = ';';
4068
				}
4026
				}
4069
				this.noProposal = false;
4027
				proposal.setSignature(signature);
4070
				if (castedReceiver == null) {
4028
				//proposal.setDeclarationPackageName(null);
4071
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
4029
				//proposal.setDeclarationTypeName(null);
4072
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4030
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4073
						proposal.setDeclarationSignature(getSignature(receiverType));
4031
				proposal.setTypeName(CLASS);
4074
						proposal.setSignature(INT_SIGNATURE);
4032
				proposal.setName(classField);
4075
						proposal.setTypeName(INT);
4033
				if (missingElements != null) {
4076
						proposal.setName(lengthField);
4034
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4077
						if (missingElements != null) {
4035
					for (int i = 0; i < missingElements.length; i++) {
4078
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4036
						subProposals[i] =
4079
							for (int i = 0; i < missingElements.length; i++) {
4037
							createRequiredTypeProposal(
4080
								subProposals[i] =
4038
									missingElements[i],
4081
									createRequiredTypeProposal(
4039
									missingElementsStarts[i],
4082
											missingElements[i],
4040
									missingElementsEnds[i],
4083
											missingElementsStarts[i],
4041
									relevance);
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
4102
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
4103
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
4104
						proposal.setDeclarationSignature(getSignature(receiverType));
4105
						proposal.setSignature(INT_SIGNATURE);
4106
						proposal.setReceiverSignature(getSignature(receiverType));
4107
						proposal.setTypeName(INT);
4108
						proposal.setName(lengthField);
4109
						if (missingElements != null) {
4110
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4111
							for (int i = 0; i < missingElements.length; i++) {
4112
								subProposals[i] =
4113
									createRequiredTypeProposal(
4114
											missingElements[i],
4115
											missingElementsStarts[i],
4116
											missingElementsEnds[i],
4117
											relevance);
4118
							}
4119
							proposal.setRequiredProposals(subProposals);
4120
						}
4121
						proposal.setCompletion(completion);
4122
						proposal.setFlags(Flags.AccPublic);
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
					}
4042
					}
4043
					proposal.setRequiredProposals(subProposals);
4044
				}
4045
				proposal.setCompletion(classField);
4046
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
4047
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4048
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4049
				proposal.setRelevance(relevance);
4050
				this.requestor.accept(proposal);
4051
				if(DEBUG) {
4052
					this.printDebug(proposal);
4132
				}
4053
				}
4133
			}
4054
			}
4134
			if (proposeMethod
4055
		}
4135
				&& token.length <= cloneMethod.length
4056
	}
4136
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
4057
	private void findConstructors(
4137
			) {
4058
		ReferenceBinding currentType,
4138
				ReferenceBinding objectRef = scope.getJavaLangObject();
4059
		TypeBinding[] argTypes,
4060
		Scope scope,
4061
		InvocationSite invocationSite,
4062
		boolean forAnonymousType) {
4139
4063
4140
				int relevance = computeBaseRelevance();
4064
		// No visibility checks can be performed without the scope & invocationSite
4141
				relevance += computeRelevanceForResolution();
4065
		MethodBinding[] methods = currentType.availableMethods();
4142
				relevance += computeRelevanceForInterestingProposal();
4066
		if(methods != null) {
4143
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
4067
			int minArgLength = argTypes == null ? 0 : argTypes.length;
4144
				relevance += computeRelevanceForExpectingType(objectRef);
4068
			next : for (int f = methods.length; --f >= 0;) {
4145
				relevance += computeRelevanceForStatic(false, false);
4069
				MethodBinding constructor = methods[f];
4146
				relevance += computeRelevanceForQualification(false);
4070
				if (constructor.isConstructor()) {
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
4071
4160
				if (castedReceiver != null) {
4072
					if (constructor.isSynthetic()) continue next;
4161
					completion = CharOperation.concat(castedReceiver, completion);
4162
				}
4163
4073
4164
				this.noProposal = false;
4074
					if (this.options.checkDeprecation &&
4165
				if (castedReceiver == null) {
4075
							constructor.isViewedAsDeprecated() &&
4166
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
4076
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4167
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4077
						continue next;
4168
						proposal.setDeclarationSignature(getSignature(receiverType));
4078
4169
						proposal.setSignature(
4079
					if (this.options.checkVisibility
4170
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
4080
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
4171
										createMethodSignature(
4081
						if(!forAnonymousType || !constructor.isProtected())
4172
												CharOperation.NO_CHAR_CHAR,
4082
							continue next;
4173
												CharOperation.NO_CHAR_CHAR,
4174
												getSignature(receiverType)) :
4175
										createMethodSignature(
4176
												CharOperation.NO_CHAR_CHAR,
4177
												CharOperation.NO_CHAR_CHAR,
4178
												CharOperation.concatWith(JAVA_LANG, '.'),
4179
												OBJECT));
4180
						//proposal.setOriginalSignature(null);
4181
						//proposal.setDeclarationPackageName(null);
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
					}
4083
					}
4210
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
4084
4211
				} else {
4085
					TypeBinding[] parameters = constructor.parameters;
4212
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
4086
					int paramLength = parameters.length;
4213
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
4087
					if (minArgLength > paramLength)
4214
						proposal.setDeclarationSignature(getSignature(receiverType));
4088
						continue next;
4215
						proposal.setSignature(
4089
					for (int a = minArgLength; --a >= 0;)
4216
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
4090
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
4217
										createMethodSignature(
4091
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
4218
												CharOperation.NO_CHAR_CHAR,
4092
								continue next;
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
						}
4093
						}
4094
4095
					char[][] parameterPackageNames = new char[paramLength][];
4096
					char[][] parameterTypeNames = new char[paramLength][];
4097
					for (int i = 0; i < paramLength; i++) {
4098
						TypeBinding type = parameters[i];
4099
						parameterPackageNames[i] = type.qualifiedPackageName();
4100
						parameterTypeNames[i] = type.qualifiedSourceName();
4252
					}
4101
					}
4253
				}
4102
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4254
			}
4255
4103
4256
			receiverType = scope.getJavaLangObject();
4104
					char[] completion = CharOperation.NO_CHAR;
4257
		}
4105
					if(forAnonymousType){
4106
						int relevance = computeBaseRelevance();
4107
						relevance += computeRelevanceForResolution();
4108
						relevance += computeRelevanceForInterestingProposal();
4109
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4258
4110
4259
		if(proposeField) {
4111
						this.noProposal = false;
4260
			findFields(
4112
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
4261
				token,
4113
							InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
4262
				(ReferenceBinding) receiverType,
4114
							proposal.setDeclarationSignature(getSignature(currentType));
4263
				scope,
4115
							proposal.setDeclarationKey(currentType.computeUniqueKey());
4264
				fieldsFound,
4116
							proposal.setSignature(getSignature(constructor));
4265
				new ObjectVector(),
4117
							MethodBinding original = constructor.original();
4266
				false,
4118
							if(original != constructor) {
4267
				invocationSite,
4119
								proposal.setOriginalSignature(getSignature(original));
4268
				invocationScope,
4120
							}
4269
				implicitCall,
4121
							proposal.setKey(constructor.computeUniqueKey());
4270
				false,
4122
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4271
				missingElements,
4123
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4272
				missingElementsStarts,
4124
							proposal.setParameterPackageNames(parameterPackageNames);
4273
				missingElementsEnds,
4125
							proposal.setParameterTypeNames(parameterTypeNames);
4274
				missingElementsHaveProblems,
4126
							//proposal.setPackageName(null);
4275
				castedReceiver,
4127
							//proposal.setTypeName(null);
4276
				receiverStart,
4128
							proposal.setCompletion(completion);
4277
				receiverEnd);
4129
							proposal.setFlags(constructor.modifiers);
4278
		}
4130
							proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
4131
							proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
4132
							proposal.setRelevance(relevance);
4133
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4134
							this.requestor.accept(proposal);
4135
							if(DEBUG) {
4136
								this.printDebug(proposal);
4137
							}
4138
						}
4139
					} else {
4140
						int relevance = computeBaseRelevance();
4141
						relevance += computeRelevanceForResolution();
4142
						relevance += computeRelevanceForInterestingProposal();
4143
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4279
4144
4280
		if(proposeMethod) {
4145
						// Special case for completion in javadoc
4281
			findMethods(
4146
						if (this.assistNodeInJavadoc > 0) {
4282
				token,
4147
							Expression receiver = null;
4283
				null,
4148
							char[] selector = null;
4284
				null,
4149
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
4285
				(ReferenceBinding) receiverType,
4150
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
4286
				scope,
4151
								receiver = alloc.type;
4287
				methodsFound,
4152
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4288
				false,
4153
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4289
				false,
4154
								receiver = fieldRef.receiver;
4290
				false,
4155
							}
4291
				invocationSite,
4156
							if (receiver != null) {
4292
				invocationScope,
4157
								StringBuffer javadocCompletion = new StringBuffer();
4293
				implicitCall,
4158
								if (receiver.isThis()) {
4294
				superCall,
4159
									selector = (((JavadocImplicitTypeReference)receiver).token);
4295
				false,
4160
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4296
				missingElements,
4161
										javadocCompletion.append('#');
4297
				missingElementsStarts,
4162
									}
4298
				missingElementsEnds,
4163
								} else if (receiver instanceof JavadocSingleTypeReference) {
4299
				missingElementsHaveProblems,
4164
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
4300
				castedReceiver,
4165
									selector = typeRef.token;
4301
				receiverStart,
4166
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4302
				receiverEnd);
4167
										javadocCompletion.append(typeRef.token);
4168
										javadocCompletion.append('#');
4169
									}
4170
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
4171
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
4172
									selector = typeRef.tokens[typeRef.tokens.length-1];
4173
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4174
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
4175
										javadocCompletion.append('#');
4176
									}
4177
								}
4178
								// Append parameters types
4179
								javadocCompletion.append(selector);
4180
								javadocCompletion.append('(');
4181
								if (constructor.parameters != null) {
4182
									boolean isVarargs = constructor.isVarargs();
4183
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
4184
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
4185
										TypeBinding argTypeBinding = constructor.parameters[p];
4186
										if (isVarargs && p == ln - 1)  {
4187
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
4188
										} else {
4189
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
4190
										}
4191
									}
4192
								}
4193
								javadocCompletion.append(')');
4194
								completion = javadocCompletion.toString().toCharArray();
4195
							}
4196
						}
4197
4198
						// Create standard proposal
4199
						this.noProposal = false;
4200
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4201
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4202
							proposal.setDeclarationSignature(getSignature(currentType));
4203
							proposal.setSignature(getSignature(constructor));
4204
							MethodBinding original = constructor.original();
4205
							if(original != constructor) {
4206
								proposal.setOriginalSignature(getSignature(original));
4207
							}
4208
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4209
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4210
							proposal.setParameterPackageNames(parameterPackageNames);
4211
							proposal.setParameterTypeNames(parameterTypeNames);
4212
							//proposal.setPackageName(null);
4213
							//proposal.setTypeName(null);
4214
							proposal.setName(currentType.sourceName());
4215
							proposal.setIsContructor(true);
4216
							proposal.setCompletion(completion);
4217
							proposal.setFlags(constructor.modifiers);
4218
							int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
4219
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4220
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4221
							proposal.setRelevance(relevance);
4222
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4223
							this.requestor.accept(proposal);
4224
							if(DEBUG) {
4225
								this.printDebug(proposal);
4226
							}
4227
						}
4228
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
4229
							char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
4230
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
4231
							proposal.setDeclarationSignature(getSignature(currentType));
4232
							proposal.setSignature(getSignature(constructor));
4233
							MethodBinding original = constructor.original();
4234
							if(original != constructor) {
4235
								proposal.setOriginalSignature(getSignature(original));
4236
							}
4237
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4238
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4239
							proposal.setParameterPackageNames(parameterPackageNames);
4240
							proposal.setParameterTypeNames(parameterTypeNames);
4241
							//proposal.setPackageName(null);
4242
							//proposal.setTypeName(null);
4243
							proposal.setName(currentType.sourceName());
4244
							proposal.setIsContructor(true);
4245
							proposal.setCompletion(javadocCompletion);
4246
							proposal.setFlags(constructor.modifiers);
4247
							int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4248
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4249
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4250
							proposal.setRelevance(relevance+R_INLINE_TAG);
4251
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4252
							this.requestor.accept(proposal);
4253
							if(DEBUG) {
4254
								this.printDebug(proposal);
4255
							}
4256
						}
4257
					}
4258
				}
4259
			}
4303
		}
4260
		}
4304
	}
4261
	}
4262
	private char[][] findEnclosingTypeNames(Scope scope){
4263
		char[][] excludedNames = new char[10][];
4264
		int excludedNameCount = 0;
4305
4265
4306
	private void findFieldsAndMethodsFromFavorites(
4266
		Scope currentScope = scope;
4307
			char[] token,
4267
		while(currentScope != null) {
4308
			Scope scope,
4268
			switch (currentScope.kind) {
4309
			InvocationSite invocationSite,
4269
				case Scope.CLASS_SCOPE :
4270
					ClassScope classScope = (ClassScope) currentScope;
4271
4272
					TypeDeclaration typeDeclaration = classScope.referenceContext;
4273
4274
					if(excludedNameCount == excludedNames.length) {
4275
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4276
					}
4277
					excludedNames[excludedNameCount++] = typeDeclaration.name;
4278
4279
					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
4280
					if(classTypeParameters != null) {
4281
						for (int i = 0; i < classTypeParameters.length; i++) {
4282
							TypeParameter typeParameter = classTypeParameters[i];
4283
							if(excludedNameCount == excludedNames.length) {
4284
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4285
							}
4286
							excludedNames[excludedNameCount++] = typeParameter.name;
4287
						}
4288
					}
4289
					break;
4290
				case Scope.METHOD_SCOPE :
4291
					MethodScope methodScope = (MethodScope) currentScope;
4292
					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
4293
						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
4294
						if(methodTypeParameters != null) {
4295
							for (int i = 0; i < methodTypeParameters.length; i++) {
4296
								TypeParameter typeParameter = methodTypeParameters[i];
4297
								if(excludedNameCount == excludedNames.length) {
4298
									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4299
								}
4300
								excludedNames[excludedNameCount++] = typeParameter.name;
4301
							}
4302
						}
4303
					}
4304
					break;
4305
			}
4306
4307
			currentScope = currentScope.parent;
4308
		}
4309
4310
		if(excludedNameCount == 0) {
4311
			return CharOperation.NO_CHAR_CHAR;
4312
		}
4313
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
4314
		return excludedNames;
4315
	}
4316
	private void findEnumConstants(
4317
			char[] enumConstantName,
4318
			ReferenceBinding enumType,
4310
			Scope invocationScope,
4319
			Scope invocationScope,
4311
			ObjectVector localsFound,
4312
			ObjectVector fieldsFound,
4320
			ObjectVector fieldsFound,
4313
			ObjectVector methodsFound) {
4321
			char[][] alreadyUsedConstants,
4322
			int alreadyUsedConstantCount,
4323
			boolean needQualification) {
4314
4324
4315
		ObjectVector methodsFoundFromFavorites = new ObjectVector();
4325
		FieldBinding[] fields = enumType.fields();
4316
4326
4317
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
4327
		int enumConstantLength = enumConstantName.length;
4328
		next : for (int f = fields.length; --f >= 0;) {
4329
			FieldBinding field = fields[f];
4318
4330
4319
		if (favoriteBindings != null && favoriteBindings.length > 0) {
4331
			if (field.isSynthetic()) continue next;
4320
			for (int i = 0; i < favoriteBindings.length; i++) {
4321
				ImportBinding favoriteBinding = favoriteBindings[i];
4322
				switch (favoriteBinding.resolvedImport.kind()) {
4323
					case Binding.FIELD:
4324
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
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
4332
4369
							findLocalMethodsFromFavorites(
4333
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
4370
									token,
4334
4371
									referenceBinding.availableMethods(),
4335
			if (enumConstantLength > field.name.length) continue next;
4372
									scope,
4336
4373
									methodsFound,
4337
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
4374
									methodsFoundFromFavorites,
4338
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
4375
									referenceBinding,
4339
4376
									invocationSite,
4340
			char[] fieldName = field.name;
4377
									invocationScope);
4341
4378
						}
4342
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
4379
						break;
4343
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
4380
				}
4381
			}
4344
			}
4382
		}
4383
4345
4384
		methodsFound.addAll(methodsFoundFromFavorites);
4346
			int relevance = computeBaseRelevance();
4385
	}
4347
			relevance += computeRelevanceForResolution();
4348
			relevance += computeRelevanceForInterestingProposal(field);
4349
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
4350
			relevance += computeRelevanceForExpectingType(field.type);
4351
			relevance += computeRelevanceForEnumConstant(field.type);
4352
			relevance += computeRelevanceForQualification(needQualification);
4353
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4386
4354
4387
	private boolean findFieldsAndMethodsFromMissingFieldType(
4355
			this.noProposal = false;
4388
		char[] token,
4356
			if (!needQualification) {
4389
		Scope scope,
4357
				char[] completion = fieldName;
4390
		InvocationSite invocationSite,
4391
		boolean insideTypeAnnotation) {
4392
4358
4393
		boolean foundSomeFields = false;
4359
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4360
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4361
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4362
					proposal.setSignature(getSignature(field.type));
4363
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4364
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4365
					proposal.setPackageName(field.type.qualifiedPackageName());
4366
					proposal.setTypeName(field.type.qualifiedSourceName());
4367
					proposal.setName(field.name);
4368
					proposal.setCompletion(completion);
4369
					proposal.setFlags(field.modifiers);
4370
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4371
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4372
					proposal.setRelevance(relevance);
4373
					this.requestor.accept(proposal);
4374
					if(DEBUG) {
4375
						this.printDebug(proposal);
4376
					}
4377
				}
4394
4378
4395
		boolean staticsOnly = false;
4379
			} else {
4396
		Scope currentScope = scope;
4380
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
4381
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
4397
4382
4398
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4383
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
4399
4384
4400
			switch (currentScope.kind) {
4385
				if (!needImport) {
4386
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4387
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4388
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4389
						proposal.setSignature(getSignature(field.type));
4390
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4391
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4392
						proposal.setPackageName(field.type.qualifiedPackageName());
4393
						proposal.setTypeName(field.type.qualifiedSourceName());
4394
						proposal.setName(field.name);
4395
						proposal.setCompletion(completion);
4396
						proposal.setFlags(field.modifiers);
4397
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4398
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4399
						proposal.setRelevance(relevance);
4400
						this.requestor.accept(proposal);
4401
						if(DEBUG) {
4402
							this.printDebug(proposal);
4403
						}
4404
					}
4405
				} else {
4406
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4407
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4408
						int importStart = cu.types[0].declarationSourceStart;
4409
						int importEnd = importStart;
4401
4410
4402
				case Scope.METHOD_SCOPE :
4411
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
4403
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4404
					MethodScope methodScope = (MethodScope) currentScope;
4405
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4406
					break;
4407
				case Scope.CLASS_SCOPE :
4408
					ClassScope classScope = (ClassScope) currentScope;
4409
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4410
					if(!insideTypeAnnotation) {
4411
4412
4412
						FieldDeclaration[] fields = classScope.referenceContext.fields;
4413
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4414
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4415
						proposal.setSignature(getSignature(field.type));
4416
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4417
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4418
						proposal.setPackageName(field.type.qualifiedPackageName());
4419
						proposal.setTypeName(field.type.qualifiedSourceName());
4420
						proposal.setName(field.name);
4421
						proposal.setCompletion(completion);
4422
						proposal.setFlags(field.modifiers);
4423
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4424
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4425
						proposal.setRelevance(relevance);
4413
4426
4414
						int fieldsCount = fields == null ? 0 : fields.length;
4427
						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
4415
						for (int i = 0; i < fieldsCount; i++) {
4428
4416
							FieldDeclaration fieldDeclaration = fields[i];
4429
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4417
							if (CharOperation.equals(fieldDeclaration.name, token)) {
4430
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4418
								FieldBinding fieldBinding = fieldDeclaration.binding;
4431
						typeImportProposal.completionEngine = this;
4419
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
4432
						char[] packageName = fieldType.qualifiedPackageName();
4420
									foundSomeFields = true;
4433
						typeImportProposal.setDeclarationSignature(packageName);
4421
									findFieldsAndMethodsFromMissingType(
4434
						typeImportProposal.setSignature(getSignature(fieldType));
4422
											fieldDeclaration.type,
4435
						typeImportProposal.setPackageName(packageName);
4423
											currentScope,
4436
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
4424
											invocationSite,
4437
						typeImportProposal.setCompletion(typeImportCompletion);
4425
											scope);
4438
						typeImportProposal.setFlags(fieldType.modifiers);
4426
								}
4439
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4427
								break done;
4440
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4428
							}
4441
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4442
						typeImportProposal.setRelevance(relevance);
4443
4444
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4445
4446
						this.requestor.accept(proposal);
4447
						if(DEBUG) {
4448
							this.printDebug(proposal);
4429
						}
4449
						}
4430
					}
4450
					}
4431
					staticsOnly |= enclosingType.isStatic();
4451
				}
4432
					insideTypeAnnotation = false;
4433
					break;
4434
				case Scope.COMPILATION_UNIT_SCOPE :
4435
					break done;
4436
			}
4452
			}
4437
			currentScope = currentScope.parent;
4438
		}
4453
		}
4439
		return foundSomeFields;
4440
	}
4454
	}
4455
	private void findEnumConstantsFromExpectedTypes(
4456
			char[] token,
4457
			Scope invocationScope,
4458
			ObjectVector fieldsFound) {
4459
		int length = this.expectedTypesPtr + 1;
4460
		for (int i = 0; i < length; i++) {
4461
			if (this.expectedTypes[i].isEnum()) {
4462
				findEnumConstants(
4463
						token,
4464
						(ReferenceBinding)this.expectedTypes[i],
4465
						invocationScope,
4466
						fieldsFound,
4467
						CharOperation.NO_CHAR_CHAR,
4468
						0,
4469
						true);
4470
			}
4471
		}
4441
4472
4442
	private void findFieldsAndMethodsFromMissingReturnType(
4473
	}
4443
		char[] token,
4474
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
4444
		TypeBinding[] arguments,
4475
		TypeBinding expressionType = switchStatement.expression.resolvedType;
4445
		Scope scope,
4476
		if(expressionType != null && expressionType.isEnum()) {
4446
		InvocationSite invocationSite,
4477
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
4447
		boolean insideTypeAnnotation) {
4448
4449
		boolean staticsOnly = false;
4450
		Scope currentScope = scope;
4451
4478
4452
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4479
			CaseStatement[] cases = switchStatement.cases;
4453
4480
4454
			switch (currentScope.kind) {
4481
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
4482
			int alreadyUsedConstantCount = 0;
4483
			for (int i = 0; i < switchStatement.caseCount; i++) {
4484
				Expression caseExpression = cases[i].constantExpression;
4485
				if((caseExpression instanceof SingleNameReference)
4486
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
4487
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
4488
				}
4489
			}
4455
4490
4456
				case Scope.METHOD_SCOPE :
4491
			findEnumConstants(
4457
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4492
					enumConstantName,
4458
					MethodScope methodScope = (MethodScope) currentScope;
4493
					enumType,
4459
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4494
					null /* doesn't need invocation scope */,
4460
					break;
4495
					new ObjectVector(),
4461
				case Scope.CLASS_SCOPE :
4496
					alreadyUsedConstants,
4462
					ClassScope classScope = (ClassScope) currentScope;
4497
					alreadyUsedConstantCount,
4463
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4498
					false);
4464
					if(!insideTypeAnnotation) {
4499
		}
4500
	}
4501
	private void findExceptionFromTryStatement(
4502
			char[] typeName,
4503
			ReferenceBinding exceptionType,
4504
			ReferenceBinding receiverType,
4505
			SourceTypeBinding invocationType,
4506
			BlockScope scope,
4507
			ObjectVector typesFound,
4508
			boolean searchSuperClasses) {
4465
4509
4466
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
4510
		if (searchSuperClasses) {
4511
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
4512
			if (exceptionType != javaLangThrowable) {
4513
				ReferenceBinding superClass = exceptionType.superclass();
4514
				while(superClass != null && superClass != javaLangThrowable) {
4515
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
4516
					superClass = superClass.superclass();
4517
				}
4518
			}
4519
		}
4467
4520
4468
						int methodsCount = methods == null ? 0 : methods.length;
4521
		if (typeName.length > exceptionType.sourceName.length)
4469
						for (int i = 0; i < methodsCount; i++) {
4522
			return;
4470
							AbstractMethodDeclaration methodDeclaration = methods[i];
4471
							if (methodDeclaration instanceof MethodDeclaration &&
4472
									CharOperation.equals(methodDeclaration.selector, token)) {
4473
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
4474
								MethodBinding methodBinding = method.binding;
4475
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
4476
									Argument[] parameters = method.arguments;
4477
									int parametersLength = parameters == null ? 0 : parameters.length;
4478
									int argumentsLength = arguments == null ? 0 : arguments.length;
4479
4523
4480
									if (parametersLength == 0) {
4524
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
4481
										if (argumentsLength == 0) {
4525
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
4482
											findFieldsAndMethodsFromMissingType(
4526
			return;
4483
													method.returnType,
4484
													currentScope,
4485
													invocationSite,
4486
													scope);
4487
											break done;
4488
										}
4489
									} else {
4490
										TypeBinding[] parametersBindings;
4491
										if (methodBinding == null) { // since no binding, extra types from type references
4492
											parametersBindings = new TypeBinding[parametersLength];
4493
											for (int j = 0; j < parametersLength; j++) {
4494
												TypeBinding parameterType = parameters[j].type.resolvedType;
4495
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
4496
													parameterType = parameterType.closestMatch();
4497
												}
4498
												parametersBindings[j] = parameterType;
4499
											}
4500
										} else {
4501
											parametersBindings = methodBinding.parameters;
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
										}
4511
									}
4512
								}
4513
4527
4514
							}
4528
		if (this.options.checkDeprecation &&
4515
						}
4529
				exceptionType.isViewedAsDeprecated() &&
4516
					}
4530
				!scope.isDefinedInSameUnit(exceptionType))
4517
					staticsOnly |= enclosingType.isStatic();
4531
			return;
4518
					insideTypeAnnotation = false;
4532
4519
					break;
4533
		if (this.options.checkVisibility) {
4520
				case Scope.COMPILATION_UNIT_SCOPE :
4534
			if (invocationType != null) {
4521
					break done;
4535
				if (receiverType != null) {
4536
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
4537
				} else {
4538
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
4539
				}
4540
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
4541
				return;
4522
			}
4542
			}
4523
			currentScope = currentScope.parent;
4524
		}
4543
		}
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
4544
4559
				}
4545
		for (int j = typesFound.size; --j >= 0;) {
4560
			};
4546
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
4561
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
4562
	}
4563
4547
4564
	private void findFieldsFromFavorites(
4548
			if (exceptionType == otherType)
4565
			char[] fieldName,
4549
				return;
4566
			FieldBinding[] fields,
4567
			Scope scope,
4568
			ObjectVector fieldsFound,
4569
			ObjectVector localsFound,
4570
			ReferenceBinding receiverType,
4571
			InvocationSite invocationSite,
4572
			Scope invocationScope) {
4573
4550
4574
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
4551
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
4575
4552
4576
		int fieldLength = fieldName.length;
4553
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
4577
		next : for (int f = fields.length; --f >= 0;) {
4554
					return;
4578
			FieldBinding field = fields[f];
4579
4555
4580
			if (field.isSynthetic())	continue next;
4556
				if (otherType.enclosingType().isInterface())
4557
					if (exceptionType.enclosingType()
4558
						.implementsInterface(otherType.enclosingType(), true))
4559
						return;
4581
4560
4582
			// only static fields must be proposed
4561
				if (exceptionType.enclosingType().isInterface())
4583
			if (!field.isStatic()) continue next;
4562
					if (otherType.enclosingType()
4563
						.implementsInterface(exceptionType.enclosingType(), true))
4564
						return;
4565
			}
4566
		}
4584
4567
4585
			if (fieldLength > field.name.length) continue next;
4568
		typesFound.add(exceptionType);
4586
4569
4587
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4570
		char[] completionName = exceptionType.sourceName();
4588
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4589
4571
4590
			if (this.options.checkDeprecation &&
4572
		boolean isQualified = false;
4591
					field.isViewedAsDeprecated() &&
4592
					!scope.isDefinedInSameUnit(field.declaringClass))
4593
				continue next;
4594
4573
4595
			if (this.options.checkVisibility
4574
		if(!this.insideQualifiedReference) {
4596
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4575
			isQualified = true;
4597
4576
4598
			for (int i = fieldsFound.size; --i >= 0;) {
4577
			char[] memberPackageName = exceptionType.qualifiedPackageName();
4599
				Object[] other = (Object[])fieldsFound.elementAt(i);
4578
			char[] memberTypeName = exceptionType.sourceName();
4600
				FieldBinding otherField = (FieldBinding) other[0];
4579
			char[] memberEnclosingTypeNames = null;
4601
4580
4602
				if (field == otherField) continue next;
4581
			ReferenceBinding enclosingType = exceptionType.enclosingType();
4582
			if (enclosingType != null) {
4583
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
4603
			}
4584
			}
4604
4585
4605
			fieldsFound.add(new Object[]{field, receiverType});
4586
			Scope currentScope = scope;
4606
4587
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
4607
			int relevance = computeBaseRelevance();
4608
			relevance += computeRelevanceForResolution();
4609
			relevance += computeRelevanceForInterestingProposal(field);
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
4588
4616
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4589
				switch (currentScope.kind) {
4617
			int importStart = cu.types[0].declarationSourceStart;
4618
			int importEnd = importStart;
4619
4590
4620
			this.noProposal = false;
4591
					case Scope.METHOD_SCOPE :
4592
					case Scope.BLOCK_SCOPE :
4593
						BlockScope blockScope = (BlockScope) currentScope;
4621
4594
4622
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
4595
						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
4623
					!this.options.suggestStaticImport) {
4624
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4625
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
4626
4596
4627
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4597
							if (blockScope.subscopes[j] instanceof ClassScope) {
4628
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4598
								SourceTypeBinding localType =
4629
					proposal.setSignature(getSignature(field.type));
4599
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
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
4600
4641
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
4601
								if (localType == exceptionType) {
4602
									isQualified = false;
4603
									break done;
4604
								}
4605
							}
4606
						}
4607
						break;
4642
4608
4643
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4609
					case Scope.CLASS_SCOPE :
4644
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4610
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
4645
					typeImportProposal.completionEngine = this;
4611
						ReferenceBinding[] memberTypes = type.memberTypes();
4646
					char[] packageName = receiverType.qualifiedPackageName();
4612
						if (memberTypes != null) {
4647
					typeImportProposal.setDeclarationSignature(packageName);
4613
							for (int j = 0; j < memberTypes.length; j++) {
4648
					typeImportProposal.setSignature(getSignature(receiverType));
4614
								if (memberTypes[j] == exceptionType) {
4649
					typeImportProposal.setPackageName(packageName);
4615
									isQualified = false;
4650
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
4616
									break done;
4651
					typeImportProposal.setCompletion(typeImportCompletion);
4617
								}
4652
					typeImportProposal.setFlags(receiverType.modifiers);
4618
							}
4653
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4619
						}
4654
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4655
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4656
					typeImportProposal.setRelevance(relevance);
4657
4658
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4659
4660
					this.requestor.accept(proposal);
4661
					if(DEBUG) {
4662
						this.printDebug(proposal);
4663
					}
4664
				}
4665
			} else {
4666
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
4667
					char[] completion = field.name;
4668
4669
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
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
4683
					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
4684
4620
4685
					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
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
4621
4700
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
4622
						break;
4701
4623
4702
					this.requestor.accept(proposal);
4624
					case Scope.COMPILATION_UNIT_SCOPE :
4703
					if(DEBUG) {
4625
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
4704
						this.printDebug(proposal);
4626
						if (types != null) {
4705
					}
4627
							for (int j = 0; j < types.length; j++) {
4628
								if (types[j] == exceptionType) {
4629
									isQualified = false;
4630
									break done;
4631
								}
4632
							}
4633
						}
4634
						break done;
4706
				}
4635
				}
4636
				currentScope = currentScope.parent;
4707
			}
4637
			}
4708
		}
4709
	}
4710
4711
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
4712
		char[][] tokens = importReference.tokens;
4713
4714
		char[] importName = CharOperation.concatWith(tokens, '.');
4715
4638
4716
		if (importName.length == 0)
4639
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
4717
			return;
4640
				if (memberPackageName == null || memberPackageName.length == 0)
4718
4641
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
4719
		char[] lastToken = tokens[tokens.length - 1];
4642
						return; // ignore types from the default package from outside it
4720
		if(lastToken != null && lastToken.length == 0)
4643
			} else {
4721
			importName = CharOperation.concat(importName, new char[]{'.'});
4644
				isQualified = false;
4722
4645
			}
4723
		this.resolvingImports = true;
4724
		this.resolvingStaticImports = importReference.isStatic();
4725
4646
4726
		this.completionToken =  lastToken;
4647
			if (isQualified) {
4727
		this.qualifiedCompletionToken = importName;
4648
				completionName =
4649
					CharOperation.concat(
4650
							memberPackageName,
4651
							CharOperation.concat(
4652
									memberEnclosingTypeNames,
4653
									memberTypeName,
4654
									'.'),
4655
							'.');
4656
			}
4657
		}
4728
4658
4729
		// want to replace the existing .*;
4659
		int relevance = computeBaseRelevance();
4730
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
4660
		relevance += computeRelevanceForResolution();
4731
			int oldStart = this.startPosition;
4661
		relevance += computeRelevanceForInterestingProposal();
4732
			int oldEnd = this.endPosition;
4662
		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
4733
			setSourceRange(
4663
		relevance += computeRelevanceForExpectingType(exceptionType);
4734
				importReference.sourceStart,
4664
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4735
				importReference.declarationSourceEnd);
4665
		if(!this.insideQualifiedReference) {
4736
			this.nameEnvironment.findPackages(importName, this);
4666
			relevance += computeRelevanceForQualification(isQualified);
4737
			setSourceRange(
4738
				oldStart,
4739
				oldEnd - 1,
4740
				false);
4741
		}
4667
		}
4668
		relevance += computeRelevanceForClass();
4669
		relevance += computeRelevanceForException();
4670
4671
		this.noProposal = false;
4742
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4672
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4743
			this.nameEnvironment.findTypes(
4673
			createTypeProposal(
4744
					importName,
4674
					exceptionType,
4745
					findMembers,
4675
					exceptionType.qualifiedSourceName(),
4746
					this.options.camelCaseMatch,
4676
					IAccessRule.K_ACCESSIBLE,
4747
					IJavaSearchConstants.TYPE,
4677
					completionName,
4748
					this);
4678
					relevance,
4749
			acceptTypes(null);
4679
					null,
4680
					null,
4681
					null,
4682
					false);
4750
		}
4683
		}
4751
	}
4684
	}
4685
	private void findExceptionFromTryStatement(
4686
			char[] typeName,
4687
			ReferenceBinding receiverType,
4688
			SourceTypeBinding invocationType,
4689
			BlockScope scope,
4690
			ObjectVector typesFound) {
4752
4691
4753
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
4692
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
4754
		ReferenceBinding[] memberTypes = ref.memberTypes();
4693
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
4755
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
4762
			if (onlyStatic && !memberType.isStatic())
4763
				continue next;
4764
4765
			if (typeLength > memberType.sourceName.length)
4766
				continue next;
4767
4768
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
4769
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
4770
				continue next;
4771
4772
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
4773
4774
			if (this.options.checkVisibility
4775
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
4776
				continue next;
4777
4778
			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
4779
4780
			int relevance = computeBaseRelevance();
4781
			relevance += computeRelevanceForResolution();
4782
			relevance += computeRelevanceForInterestingProposal();
4783
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
4784
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4785
4694
4786
			if (memberType.isClass()) {
4695
			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
		}
4696
		}
4807
	}
4697
	}
4698
	private void findExplicitConstructors(
4699
		char[] name,
4700
		ReferenceBinding currentType,
4701
		MethodScope scope,
4702
		InvocationSite invocationSite) {
4808
4703
4809
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
4704
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
4810
		FieldBinding[] fields = ref.availableFields();
4705
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
4811
4706
4812
		int fieldLength = fieldName.length;
4707
		// No visibility checks can be performed without the scope & invocationSite
4813
		next : for (int m = fields.length; --m >= 0;) {
4708
		MethodBinding[] methods = currentType.availableMethods();
4814
			FieldBinding field = fields[m];
4709
		if(methods != null) {
4710
			next : for (int f = methods.length; --f >= 0;) {
4711
				MethodBinding constructor = methods[f];
4712
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
4815
4713
4816
			if (fieldLength > field.name.length)
4714
					if (constructor.isSynthetic()) continue next;
4817
				continue next;
4818
4715
4819
			if (field.isSynthetic())
4716
					if (this.options.checkDeprecation &&
4820
				continue next;
4717
							constructor.isViewedAsDeprecated() &&
4718
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4719
						continue next;
4821
4720
4822
			if (!field.isStatic())
4721
					if (this.options.checkVisibility
4823
				continue next;
4722
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
4824
4723
4825
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
4724
					TypeBinding[] parameters = constructor.parameters;
4826
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
4725
					int paramLength = parameters.length;
4827
				continue next;
4828
4726
4829
			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
4727
					char[][] parameterPackageNames = new char[paramLength][];
4830
4728
					char[][] parameterTypeNames = new char[paramLength][];
4831
			if (this.options.checkVisibility
4729
					for (int i = 0; i < paramLength; i++) {
4832
				&& !field.canBeSeenBy(this.unitScope.fPackage))
4730
						TypeBinding type = parameters[i];
4833
				continue next;
4731
						parameterPackageNames[i] = type.qualifiedPackageName();
4732
						parameterTypeNames[i] = type.qualifiedSourceName();
4733
					}
4734
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4834
4735
4835
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
4736
					char[] completion = CharOperation.NO_CHAR;
4737
					if (this.source != null
4738
						&& this.source.length > this.endPosition
4739
						&& this.source[this.endPosition] == '(')
4740
						completion = name;
4741
					else
4742
						completion = CharOperation.concat(name, new char[] { '(', ')' });
4836
4743
4837
			int relevance = computeBaseRelevance();
4744
					int relevance = computeBaseRelevance();
4838
			relevance += computeRelevanceForResolution();
4745
					relevance += computeRelevanceForResolution();
4839
			relevance += computeRelevanceForInterestingProposal();
4746
					relevance += computeRelevanceForInterestingProposal();
4840
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4747
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
4841
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4748
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4842
4749
4843
			this.noProposal = false;
4750
					this.noProposal = false;
4844
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4751
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
4845
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4752
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4846
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
4753
						proposal.setDeclarationSignature(getSignature(currentType));
4847
				proposal.setSignature(getSignature(field.type));
4754
						proposal.setSignature(getSignature(constructor));
4848
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4755
						MethodBinding original = constructor.original();
4849
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4756
						if(original != constructor) {
4850
				proposal.setPackageName(field.type.qualifiedPackageName());
4757
							proposal.setOriginalSignature(getSignature(original));
4851
				proposal.setTypeName(field.type.qualifiedSourceName());
4758
						}
4852
				proposal.setName(field.name);
4759
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4853
				proposal.setCompletion(completionName);
4760
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4854
				proposal.setFlags(field.modifiers);
4761
						proposal.setParameterPackageNames(parameterPackageNames);
4855
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4762
						proposal.setParameterTypeNames(parameterTypeNames);
4856
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4763
						//proposal.setPackageName(null);
4857
				proposal.setRelevance(relevance);
4764
						//proposal.setTypeName(null);
4858
				this.requestor.accept(proposal);
4765
						proposal.setName(name);
4859
				if(DEBUG) {
4766
						proposal.setIsContructor(true);
4860
					this.printDebug(proposal);
4767
						proposal.setCompletion(completion);
4768
						proposal.setFlags(constructor.modifiers);
4769
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4770
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4771
						proposal.setRelevance(relevance);
4772
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
4773
						this.requestor.accept(proposal);
4774
						if(DEBUG) {
4775
							this.printDebug(proposal);
4776
						}
4777
					}
4861
				}
4778
				}
4862
			}
4779
			}
4863
		}
4780
		}
4864
	}
4781
	}
4782
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
4783
	private void findFields(
4784
		char[] fieldName,
4785
		FieldBinding[] fields,
4786
		Scope scope,
4787
		ObjectVector fieldsFound,
4788
		ObjectVector localsFound,
4789
		boolean onlyStaticFields,
4790
		ReferenceBinding receiverType,
4791
		InvocationSite invocationSite,
4792
		Scope invocationScope,
4793
		boolean implicitCall,
4794
		boolean canBePrefixed,
4795
		Binding[] missingElements,
4796
		int[] missingElementsStarts,
4797
		int[] missingElementsEnds,
4798
		boolean missingElementsHaveProblems,
4799
		char[] castedReceiver,
4800
		int receiverStart,
4801
		int receiverEnd) {
4865
4802
4866
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
4803
		ObjectVector newFieldsFound = new ObjectVector();
4867
		MethodBinding[] methods = ref.availableMethods();
4804
		// Inherited fields which are hidden by subclasses are filtered out
4805
		// No visibility checks can be performed without the scope & invocationSite
4868
4806
4869
		int methodLength = methodName.length;
4807
		int fieldLength = fieldName.length;
4870
		next : for (int m = methods.length; --m >= 0;) {
4808
		next : for (int f = fields.length; --f >= 0;) {
4871
			MethodBinding method = methods[m];
4809
			FieldBinding field = fields[f];
4872
4810
4873
			if (method.isSynthetic()) continue next;
4811
			if (field.isSynthetic())	continue next;
4874
4812
4875
			if (method.isDefaultAbstract())	continue next;
4813
			if (onlyStaticFields && !field.isStatic()) continue next;
4876
4814
4877
			if (method.isConstructor()) continue next;
4815
			if (fieldLength > field.name.length) continue next;
4878
4816
4879
			if (!method.isStatic()) continue next;
4817
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4818
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4880
4819
4881
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
4820
			if (this.options.checkDeprecation &&
4821
					field.isViewedAsDeprecated() &&
4822
					!scope.isDefinedInSameUnit(field.declaringClass))
4823
				continue next;
4882
4824
4883
			if (this.options.checkVisibility
4825
			if (this.options.checkVisibility
4884
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
4826
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4885
4827
4886
			if (methodLength > method.selector.length)
4828
			boolean prefixRequired = false;
4887
				continue next;
4888
4829
4889
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
4830
			for (int i = fieldsFound.size; --i >= 0;) {
4890
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
4831
				Object[] other = (Object[])fieldsFound.elementAt(i);
4891
				continue next;
4832
				FieldBinding otherField = (FieldBinding) other[0];
4833
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
4834
				if (field == otherField && receiverType == otherReceiverType)
4835
					continue next;
4836
				if (CharOperation.equals(field.name, otherField.name, true)) {
4837
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
4838
						continue next;
4839
					if (otherField.declaringClass.isInterface()) {
4840
						if (field.declaringClass == scope.getJavaLangObject())
4841
							continue next;
4842
						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
4843
							continue next;
4844
					}
4845
					if (field.declaringClass.isInterface())
4846
						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
4847
							continue next;
4848
					if(canBePrefixed) {
4849
						prefixRequired = true;
4850
					} else {
4851
						continue next;
4852
					}
4853
				}
4854
			}
4892
4855
4893
			int length = method.parameters.length;
4856
			for (int l = localsFound.size; --l >= 0;) {
4894
			char[][] parameterPackageNames = new char[length][];
4857
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
4895
			char[][] parameterTypeNames = new char[length][];
4896
4858
4897
			for (int i = 0; i < length; i++) {
4859
				if (CharOperation.equals(field.name, local.name, true)) {
4898
				TypeBinding type = method.original().parameters[i];
4860
					SourceTypeBinding declarationType = scope.enclosingSourceType();
4899
				parameterPackageNames[i] = type.qualifiedPackageName();
4861
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
4900
				parameterTypeNames[i] = type.qualifiedSourceName();
4862
						continue next;
4863
					}
4864
					if(canBePrefixed) {
4865
						prefixRequired = true;
4866
					} else {
4867
						continue next;
4868
					}
4869
					break;
4870
				}
4901
			}
4871
			}
4902
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
4903
4872
4904
			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
4873
			newFieldsFound.add(new Object[]{field, receiverType});
4905
4874
4906
			int relevance = computeBaseRelevance();
4875
			char[] completion = field.name;
4907
			relevance += computeRelevanceForResolution();
4908
			relevance += computeRelevanceForInterestingProposal();
4909
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
4910
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4911
4876
4912
			this.noProposal = false;
4877
			if(prefixRequired || this.options.forceImplicitQualification){
4913
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
4878
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
4914
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
4879
				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
			}
4880
			}
4935
		}
4936
	}
4937
4881
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
4882
4950
			this.noProposal = false;
4883
			if (castedReceiver != null) {
4951
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
4884
				completion = CharOperation.concat(castedReceiver, completion);
4952
				char[] possibleTag = possibleTags[i];
4953
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
4954
				proposal.setName(possibleTag);
4955
				int tagLength = possibleTag.length;
4956
				char[] completion = new char[1+tagLength];
4957
				completion[0] = '@';
4958
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
4959
				proposal.setCompletion(completion);
4960
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4961
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4962
				proposal.setRelevance(relevance);
4963
				this.requestor.accept(proposal);
4964
				if (DEBUG) {
4965
					this.printDebug(proposal);
4966
				}
4967
			}
4885
			}
4968
		}
4969
	}
4970
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();
4980
			relevance += computeRelevanceForInterestingProposal();
4981
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
4982
4886
4983
			this.noProposal = false;
4887
			// Special case for javadoc completion
4984
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
4888
			if (this.assistNodeInJavadoc > 0) {
4985
				char[] possibleTag = possibleTags[i];
4889
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4986
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
4890
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4987
				proposal.setName(possibleTag);
4891
					if (fieldRef.receiver.isThis()) {
4988
				int tagLength = possibleTag.length;
4892
						if (fieldRef.completeInText()) {
4989
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
4893
							completion = CharOperation.concat(new char[] { '#' }, field.name);
4990
				char[] completion = new char[2+tagLength+1];
4894
						}
4991
				completion[0] = '{';
4895
					} else if (fieldRef.completeInText()) {
4992
				completion[1] = '@';
4896
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
4993
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
4897
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
4994
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
4898
							completion = CharOperation.concat(typeRef.token, field.name, '#');
4995
				//completion[tagLength+2] = ' ';
4899
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
4996
				completion[tagLength+2] = '}';
4900
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
4997
				proposal.setCompletion(completion);
4901
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
4998
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4902
						}
4999
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4903
					}
5000
				proposal.setRelevance(relevance);
5001
				this.requestor.accept(proposal);
5002
				if (DEBUG) {
5003
					this.printDebug(proposal);
5004
				}
4904
				}
5005
			}
4905
			}
5006
		}
5007
	}
5008
4906
5009
	// what about onDemand types? Ignore them since it does not happen!
4907
			int relevance = computeBaseRelevance();
5010
	// import p1.p2.A.*;
4908
			relevance += computeRelevanceForResolution();
5011
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
4909
			relevance += computeRelevanceForInterestingProposal(field);
5012
		if(choices == null || choices.length == 0) return;
4910
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4911
			relevance += computeRelevanceForExpectingType(field.type);
4912
			relevance += computeRelevanceForEnumConstant(field.type);
4913
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
4914
			relevance += computeRelevanceForQualification(prefixRequired);
4915
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4916
			if (onlyStaticFields && this.insideQualifiedReference) {
4917
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
4918
			}
4919
			if (missingElements != null) {
4920
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4921
			}
5013
4922
5014
		int length = keyword.length;
4923
			this.noProposal = false;
5015
		if (canCompleteEmptyToken || length > 0)
4924
			if (castedReceiver == null) {
5016
			for (int i = 0; i < choices.length; i++)
4925
				// Standard proposal
5017
				if (length <= choices[i].length
4926
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
5018
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
4927
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
5019
				)){
4928
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
5020
					int relevance = computeBaseRelevance();
4929
					proposal.setSignature(getSignature(field.type));
5021
					relevance += computeRelevanceForResolution();
4930
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5022
					relevance += computeRelevanceForInterestingProposal();
4931
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5023
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
4932
					proposal.setPackageName(field.type.qualifiedPackageName());
5024
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
4933
					proposal.setTypeName(field.type.qualifiedSourceName());
5025
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
4934
					proposal.setName(field.name);
4935
					if (missingElements != null) {
4936
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4937
						for (int i = 0; i < missingElements.length; i++) {
4938
							subProposals[i] =
4939
								createRequiredTypeProposal(
4940
										missingElements[i],
4941
										missingElementsStarts[i],
4942
										missingElementsEnds[i],
4943
										relevance);
4944
						}
4945
						proposal.setRequiredProposals(subProposals);
4946
					}
4947
					proposal.setCompletion(completion);
4948
					proposal.setFlags(field.modifiers);
4949
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4950
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4951
					proposal.setRelevance(relevance);
4952
					this.requestor.accept(proposal);
4953
					if(DEBUG) {
4954
						this.printDebug(proposal);
4955
					}
4956
				}
5026
4957
5027
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
4958
				// Javadoc completions
5028
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
4959
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
5029
						relevance += computeRelevanceForQualification(false);
4960
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
4961
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
4962
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4963
					proposal.setSignature(getSignature(field.type));
4964
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4965
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4966
					proposal.setPackageName(field.type.qualifiedPackageName());
4967
					proposal.setTypeName(field.type.qualifiedSourceName());
4968
					proposal.setName(field.name);
4969
					proposal.setCompletion(javadocCompletion);
4970
					proposal.setFlags(field.modifiers);
4971
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4972
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4973
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4974
					proposal.setRelevance(relevance+R_INLINE_TAG);
4975
					this.requestor.accept(proposal);
4976
					if(DEBUG) {
4977
						this.printDebug(proposal);
5030
					}
4978
					}
5031
					this.noProposal = false;
4979
					// Javadoc value completion for static fields
5032
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
4980
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
5033
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
4981
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
5034
						proposal.setName(choices[i]);
4982
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
5035
						proposal.setCompletion(choices[i]);
4983
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
5036
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4984
						valueProposal.setSignature(getSignature(field.type));
5037
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4985
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5038
						proposal.setRelevance(relevance);
4986
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5039
						this.requestor.accept(proposal);
4987
						valueProposal.setPackageName(field.type.qualifiedPackageName());
4988
						valueProposal.setTypeName(field.type.qualifiedSourceName());
4989
						valueProposal.setName(field.name);
4990
						valueProposal.setCompletion(javadocCompletion);
4991
						valueProposal.setFlags(field.modifiers);
4992
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4993
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4994
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
4995
						this.requestor.accept(valueProposal);
5040
						if(DEBUG) {
4996
						if(DEBUG) {
5041
							this.printDebug(proposal);
4997
							this.printDebug(valueProposal);
5042
						}
4998
						}
5043
					}
4999
					}
5044
				}
5000
				}
5045
	}
5001
			} else {
5046
	private void findTrueOrFalseKeywords(char[][] choices) {
5002
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5047
		if(choices == null || choices.length == 0) return;
5003
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5048
5004
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
5049
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
5005
					proposal.setSignature(getSignature(field.type));
5050
5006
					proposal.setReceiverSignature(getSignature(receiverType));
5051
		for (int i = 0; i < choices.length; i++) {
5007
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5052
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
5008
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5053
					CharOperation.equals(choices[i], Keywords.FALSE)
5009
					proposal.setPackageName(field.type.qualifiedPackageName());
5054
			){
5010
					proposal.setTypeName(field.type.qualifiedSourceName());
5055
				int relevance = computeBaseRelevance();
5011
					proposal.setName(field.name);
5056
				relevance += computeRelevanceForResolution();
5012
					if (missingElements != null) {
5057
				relevance += computeRelevanceForInterestingProposal();
5013
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5058
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
5014
						for (int i = 0; i < missingElements.length; i++) {
5059
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
5015
							subProposals[i] =
5060
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
5016
								createRequiredTypeProposal(
5061
				relevance += computeRelevanceForQualification(false);
5017
										missingElements[i],
5062
				relevance += R_TRUE_OR_FALSE;
5018
										missingElementsStarts[i],
5063
5019
										missingElementsEnds[i],
5064
				this.noProposal = false;
5020
										relevance);
5065
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5021
						}
5066
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5022
						proposal.setRequiredProposals(subProposals);
5067
					proposal.setName(choices[i]);
5023
					}
5068
					proposal.setCompletion(choices[i]);
5024
					proposal.setCompletion(completion);
5025
					proposal.setFlags(field.modifiers);
5069
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5026
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5027
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5070
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5028
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5071
					proposal.setRelevance(relevance);
5029
					proposal.setRelevance(relevance);
5072
					this.requestor.accept(proposal);
5030
					this.requestor.accept(proposal);
Lines 5076-5682 Link Here
5076
				}
5034
				}
5077
			}
5035
			}
5078
		}
5036
		}
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
5037
5096
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
5038
		fieldsFound.addAll(newFieldsFound);
5097
			// abtract
5039
	}
5098
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
5040
	private void findFields(
5099
				keywords[count++] = Keywords.ABSTRACT;
5041
		char[] fieldName,
5100
			}
5042
		ReferenceBinding receiverType,
5043
		Scope scope,
5044
		ObjectVector fieldsFound,
5045
		ObjectVector localsFound,
5046
		boolean onlyStaticFields,
5047
		InvocationSite invocationSite,
5048
		Scope invocationScope,
5049
		boolean implicitCall,
5050
		boolean canBePrefixed,
5051
		Binding[] missingElements,
5052
		int[] missingElementsStarts,
5053
		int[] missingElementsEnds,
5054
		boolean missingElementsHaveProblems,
5055
		char[] castedReceiver,
5056
		int receiverStart,
5057
		int receiverEnd) {
5101
5058
5102
			// final
5059
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
5103
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
5060
		if (fieldName == null && notInJavadoc)
5104
				keywords[count++] = Keywords.FINAL;
5061
			return;
5105
			}
5106
5062
5107
			// static
5063
		ReferenceBinding currentType = receiverType;
5108
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
5064
		ReferenceBinding[] interfacesToVisit = null;
5109
				keywords[count++] = Keywords.STATIC;
5065
		int nextPosition = 0;
5110
			}
5066
		do {
5111
5067
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5112
			boolean canBeField = true;
5068
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5113
			boolean canBeMethod = true;
5069
				if (interfacesToVisit == null) {
5114
			boolean canBeType = true;
5070
					interfacesToVisit = itsInterfaces;
5115
			if((modifiers & ClassFileConstants.AccNative) != 0
5071
					nextPosition = interfacesToVisit.length;
5116
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
5072
				} else {
5117
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
5073
					int itsLength = itsInterfaces.length;
5118
				canBeField = false;
5074
					if (nextPosition + itsLength >= interfacesToVisit.length)
5119
				canBeType = false;
5075
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5120
			}
5076
					nextInterface : for (int a = 0; a < itsLength; a++) {
5121
5077
						ReferenceBinding next = itsInterfaces[a];
5122
			if((modifiers & ClassFileConstants.AccTransient) != 0
5078
						for (int b = 0; b < nextPosition; b++)
5123
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
5079
							if (next == interfacesToVisit[b]) continue nextInterface;
5124
				canBeMethod = false;
5080
						interfacesToVisit[nextPosition++] = next;
5125
				canBeType = false;
5081
					}
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
				}
5082
				}
5138
			}
5083
			}
5139
5084
5140
			if(canBeMethod) {
5085
			FieldBinding[] fields = currentType.availableFields();
5141
				// native
5086
			if(fields != null && fields.length > 0) {
5142
				if((modifiers & ClassFileConstants.AccNative) == 0) {
5087
				findFields(
5143
					keywords[count++] = Keywords.NATIVE;
5088
					fieldName,
5144
				}
5089
					fields,
5090
					scope,
5091
					fieldsFound,
5092
					localsFound,
5093
					onlyStaticFields,
5094
					receiverType,
5095
					invocationSite,
5096
					invocationScope,
5097
					implicitCall,
5098
					canBePrefixed,
5099
					missingElements,
5100
					missingElementsStarts,
5101
					missingElementsEnds,
5102
					missingElementsHaveProblems,
5103
					castedReceiver,
5104
					receiverStart,
5105
					receiverEnd);
5106
			}
5107
			currentType = currentType.superclass();
5108
		} while (notInJavadoc && currentType != null);
5145
5109
5146
				// strictfp
5110
		if (notInJavadoc && interfacesToVisit != null) {
5147
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
5111
			for (int i = 0; i < nextPosition; i++) {
5148
					keywords[count++] = Keywords.STRICTFP;
5112
				ReferenceBinding anInterface = interfacesToVisit[i];
5113
				FieldBinding[] fields = anInterface.availableFields();
5114
				if(fields !=  null) {
5115
					findFields(
5116
						fieldName,
5117
						fields,
5118
						scope,
5119
						fieldsFound,
5120
						localsFound,
5121
						onlyStaticFields,
5122
						receiverType,
5123
						invocationSite,
5124
						invocationScope,
5125
						implicitCall,
5126
						canBePrefixed,
5127
						missingElements,
5128
						missingElementsStarts,
5129
						missingElementsEnds,
5130
						missingElementsHaveProblems,
5131
						castedReceiver,
5132
						receiverStart,
5133
						receiverEnd);
5149
				}
5134
				}
5150
5135
5151
				// synchronized
5136
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5152
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
5137
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
5153
					keywords[count++] = Keywords.SYNCHRONIZED;
5138
					int itsLength = itsInterfaces.length;
5139
					if (nextPosition + itsLength >= interfacesToVisit.length)
5140
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5141
					nextInterface : for (int a = 0; a < itsLength; a++) {
5142
						ReferenceBinding next = itsInterfaces[a];
5143
						for (int b = 0; b < nextPosition; b++)
5144
							if (next == interfacesToVisit[b]) continue nextInterface;
5145
						interfacesToVisit[nextPosition++] = next;
5146
					}
5154
				}
5147
				}
5155
			}
5148
			}
5149
		}
5150
	}
5156
5151
5157
			if(canBeType) {
5152
	protected void findFieldsAndMethods(
5158
				keywords[count++] = Keywords.CLASS;
5153
		char[] token,
5159
				keywords[count++] = Keywords.INTERFACE;
5154
		TypeBinding receiverType,
5155
		Scope scope,
5156
		ObjectVector fieldsFound,
5157
		ObjectVector methodsFound,
5158
		InvocationSite invocationSite,
5159
		Scope invocationScope,
5160
		boolean implicitCall,
5161
		boolean superCall,
5162
		Binding[] missingElements,
5163
		int[] missingElementsStarts,
5164
		int[] missingElementsEnds,
5165
		boolean missingElementsHaveProblems,
5166
		char[] castedReceiver,
5167
		int receiverStart,
5168
		int receiverEnd) {
5160
5169
5161
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
5170
		if (token == null)
5162
					keywords[count++] = Keywords.ENUM;
5171
			return;
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
5172
5172
		findKeywords(token, keywords, false, false);
5173
		if (receiverType.isBaseType())
5173
	}
5174
			return; // nothing else is possible with base types
5174
5175
5175
	protected void findMembers(
5176
		boolean proposeField =
5176
			char[] token,
5177
			castedReceiver == null ?
5177
			ReferenceBinding receiverType,
5178
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
5178
			Scope scope,
5179
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
5179
			InvocationSite invocationSite,
5180
		boolean proposeMethod =
5180
			boolean isInsideAnnotationAttribute,
5181
			castedReceiver == null ?
5181
			Binding[] missingElements,
5182
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
5182
			int[] missingElementsStarts,
5183
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
5183
			int[] missingElementsEnds,
5184
			boolean missingElementsHaveProblems) {
5185
5184
5186
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
5185
		if (receiverType.isArrayType()) {
5187
			findMemberTypes(
5186
			if (proposeField
5188
					token,
5187
				&& token.length <= lengthField.length
5189
					receiverType,
5188
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
5190
					scope,
5189
			)) {
5191
					scope.enclosingSourceType(),
5192
					false,
5193
					true,
5194
					new ObjectVector(),
5195
					missingElements,
5196
					missingElementsStarts,
5197
					missingElementsEnds,
5198
					missingElementsHaveProblems);
5199
		}
5200
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
5201
			findClassField(
5202
					token,
5203
					receiverType,
5204
					scope,
5205
					missingElements,
5206
					missingElementsStarts,
5207
					missingElementsEnds,
5208
					missingElementsHaveProblems);
5209
		}
5210
5190
5211
		MethodScope methodScope = null;
5212
		if (!isInsideAnnotationAttribute &&
5213
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
5214
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
5215
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
5216
			if (token.length > 0) {
5217
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
5218
			} else {
5219
				int relevance = computeBaseRelevance();
5191
				int relevance = computeBaseRelevance();
5220
				relevance += computeRelevanceForResolution();
5192
				relevance += computeRelevanceForResolution();
5221
				relevance += computeRelevanceForInterestingProposal();
5193
				relevance += computeRelevanceForInterestingProposal();
5222
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
5194
				relevance += computeRelevanceForCaseMatching(token,lengthField);
5223
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
5195
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
5224
				relevance += R_NON_INHERITED;
5196
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
5225
5197
				if (missingElements != null) {
5226
				this.noProposal = false;
5198
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5227
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5228
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5229
					proposal.setName(Keywords.THIS);
5230
					proposal.setCompletion(Keywords.THIS);
5231
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5232
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5233
					proposal.setRelevance(relevance);
5234
					this.requestor.accept(proposal);
5235
					if (DEBUG) {
5236
						this.printDebug(proposal);
5237
					}
5238
				}
5199
				}
5239
			}
5200
				this.noProposal = false;
5240
		}
5201
				if (castedReceiver == null) {
5241
5202
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
5242
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
5203
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
5243
			findFields(
5204
						proposal.setDeclarationSignature(getSignature(receiverType));
5244
				token,
5205
						proposal.setSignature(INT_SIGNATURE);
5245
				receiverType,
5206
						proposal.setTypeName(INT);
5246
				scope,
5207
						proposal.setName(lengthField);
5247
				new ObjectVector(),
5208
						if (missingElements != null) {
5248
				new ObjectVector(),
5209
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5249
				true,
5210
							for (int i = 0; i < missingElements.length; i++) {
5250
				invocationSite,
5211
								subProposals[i] =
5251
				scope,
5212
									createRequiredTypeProposal(
5252
				false,
5213
											missingElements[i],
5253
				false,
5214
											missingElementsStarts[i],
5254
				missingElements,
5215
											missingElementsEnds[i],
5255
				missingElementsStarts,
5216
											relevance);
5256
				missingElementsEnds,
5217
							}
5257
				missingElementsHaveProblems,
5218
							proposal.setRequiredProposals(subProposals);
5258
				null,
5219
						}
5259
				-1,
5220
						proposal.setCompletion(lengthField);
5260
				-1);
5221
						proposal.setFlags(Flags.AccPublic);
5261
		}
5222
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5262
5223
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5263
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
5224
						proposal.setRelevance(relevance);
5264
			findMethods(
5225
						this.requestor.accept(proposal);
5226
						if(DEBUG) {
5227
							this.printDebug(proposal);
5228
						}
5229
					}
5230
				} else {
5231
					char[] completion = CharOperation.concat(castedReceiver, lengthField);
5232
5233
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5234
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5235
						proposal.setDeclarationSignature(getSignature(receiverType));
5236
						proposal.setSignature(INT_SIGNATURE);
5237
						proposal.setReceiverSignature(getSignature(receiverType));
5238
						proposal.setTypeName(INT);
5239
						proposal.setName(lengthField);
5240
						if (missingElements != null) {
5241
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5242
							for (int i = 0; i < missingElements.length; i++) {
5243
								subProposals[i] =
5244
									createRequiredTypeProposal(
5245
											missingElements[i],
5246
											missingElementsStarts[i],
5247
											missingElementsEnds[i],
5248
											relevance);
5249
							}
5250
							proposal.setRequiredProposals(subProposals);
5251
						}
5252
						proposal.setCompletion(completion);
5253
						proposal.setFlags(Flags.AccPublic);
5254
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5255
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5256
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5257
						proposal.setRelevance(relevance);
5258
						this.requestor.accept(proposal);
5259
						if(DEBUG) {
5260
							this.printDebug(proposal);
5261
						}
5262
					}
5263
				}
5264
			}
5265
			if (proposeMethod
5266
				&& token.length <= cloneMethod.length
5267
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
5268
			) {
5269
				ReferenceBinding objectRef = scope.getJavaLangObject();
5270
5271
				int relevance = computeBaseRelevance();
5272
				relevance += computeRelevanceForResolution();
5273
				relevance += computeRelevanceForInterestingProposal();
5274
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
5275
				relevance += computeRelevanceForExpectingType(objectRef);
5276
				relevance += computeRelevanceForStatic(false, false);
5277
				relevance += computeRelevanceForQualification(false);
5278
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
5279
				if (missingElements != null) {
5280
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5281
				}
5282
				char[] completion;
5283
				if (this.source != null
5284
					&& this.source.length > this.endPosition
5285
					&& this.source[this.endPosition] == '(') {
5286
					completion = cloneMethod;
5287
					} else {
5288
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
5289
				}
5290
5291
				if (castedReceiver != null) {
5292
					completion = CharOperation.concat(castedReceiver, completion);
5293
				}
5294
5295
				this.noProposal = false;
5296
				if (castedReceiver == null) {
5297
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
5298
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5299
						proposal.setDeclarationSignature(getSignature(receiverType));
5300
						proposal.setSignature(
5301
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5302
										createMethodSignature(
5303
												CharOperation.NO_CHAR_CHAR,
5304
												CharOperation.NO_CHAR_CHAR,
5305
												getSignature(receiverType)) :
5306
										createMethodSignature(
5307
												CharOperation.NO_CHAR_CHAR,
5308
												CharOperation.NO_CHAR_CHAR,
5309
												CharOperation.concatWith(JAVA_LANG, '.'),
5310
												OBJECT));
5311
						//proposal.setOriginalSignature(null);
5312
						//proposal.setDeclarationPackageName(null);
5313
						//proposal.setDeclarationTypeName(null);
5314
						//proposal.setParameterPackageNames(null);
5315
						//proposal.setParameterTypeNames(null);
5316
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5317
						proposal.setTypeName(OBJECT);
5318
						proposal.setName(cloneMethod);
5319
						if (missingElements != null) {
5320
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5321
							for (int i = 0; i < missingElements.length; i++) {
5322
								subProposals[i] =
5323
									createRequiredTypeProposal(
5324
											missingElements[i],
5325
											missingElementsStarts[i],
5326
											missingElementsEnds[i],
5327
											relevance);
5328
							}
5329
							proposal.setRequiredProposals(subProposals);
5330
						}
5331
						proposal.setCompletion(completion);
5332
						proposal.setFlags(Flags.AccPublic);
5333
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5334
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5335
						proposal.setRelevance(relevance);
5336
						this.requestor.accept(proposal);
5337
						if(DEBUG) {
5338
							this.printDebug(proposal);
5339
						}
5340
					}
5341
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
5342
				} else {
5343
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5344
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5345
						proposal.setDeclarationSignature(getSignature(receiverType));
5346
						proposal.setSignature(
5347
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5348
										createMethodSignature(
5349
												CharOperation.NO_CHAR_CHAR,
5350
												CharOperation.NO_CHAR_CHAR,
5351
												getSignature(receiverType)) :
5352
										createMethodSignature(
5353
												CharOperation.NO_CHAR_CHAR,
5354
												CharOperation.NO_CHAR_CHAR,
5355
												CharOperation.concatWith(JAVA_LANG, '.'),
5356
												OBJECT));
5357
						proposal.setReceiverSignature(getSignature(receiverType));
5358
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5359
						proposal.setTypeName(OBJECT);
5360
						proposal.setName(cloneMethod);
5361
						if (missingElements != null) {
5362
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5363
							for (int i = 0; i < missingElements.length; i++) {
5364
								subProposals[i] =
5365
									createRequiredTypeProposal(
5366
											missingElements[i],
5367
											missingElementsStarts[i],
5368
											missingElementsEnds[i],
5369
											relevance);
5370
							}
5371
							proposal.setRequiredProposals(subProposals);
5372
						}
5373
						proposal.setCompletion(completion);
5374
						proposal.setFlags(Flags.AccPublic);
5375
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5376
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5377
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5378
						proposal.setRelevance(relevance);
5379
						this.requestor.accept(proposal);
5380
						if(DEBUG) {
5381
							this.printDebug(proposal);
5382
						}
5383
					}
5384
				}
5385
			}
5386
5387
			receiverType = scope.getJavaLangObject();
5388
		}
5389
		
5390
		checkCancel();
5391
		
5392
		if(proposeField) {
5393
			findFields(
5265
				token,
5394
				token,
5266
				null,
5395
				(ReferenceBinding) receiverType,
5267
				null,
5268
				receiverType,
5269
				scope,
5396
				scope,
5397
				fieldsFound,
5270
				new ObjectVector(),
5398
				new ObjectVector(),
5271
				true,
5272
				false,
5273
				false,
5399
				false,
5274
				invocationSite,
5400
				invocationSite,
5401
				invocationScope,
5402
				implicitCall,
5403
				false,
5404
				missingElements,
5405
				missingElementsStarts,
5406
				missingElementsEnds,
5407
				missingElementsHaveProblems,
5408
				castedReceiver,
5409
				receiverStart,
5410
				receiverEnd);
5411
		}
5412
5413
		if(proposeMethod) {
5414
			findMethods(
5415
				token,
5416
				null,
5417
				null,
5418
				(ReferenceBinding) receiverType,
5275
				scope,
5419
				scope,
5420
				methodsFound,
5276
				false,
5421
				false,
5277
				false,
5422
				false,
5423
				invocationSite,
5424
				invocationScope,
5425
				implicitCall,
5426
				superCall,
5278
				false,
5427
				false,
5279
				missingElements,
5428
				missingElements,
5280
				missingElementsStarts,
5429
				missingElementsStarts,
5281
				missingElementsEnds,
5430
				missingElementsEnds,
5282
				missingElementsHaveProblems,
5431
				missingElementsHaveProblems,
5283
				null,
5432
				castedReceiver,
5284
				-1,
5433
				receiverStart,
5285
				-1);
5434
				receiverEnd);
5286
		}
5435
		}
5287
	}
5436
	}
5288
5437
5289
	private void findMembersFromMissingType(
5438
	protected void findFieldsAndMethodsFromAnotherReceiver(
5290
			final char[] token,
5439
			char[] token,
5291
			final long pos,
5440
			TypeReference receiverType,
5292
			TypeBinding resolveType,
5441
			Scope scope,
5293
			final Scope scope,
5442
			ObjectVector fieldsFound,
5294
			final InvocationSite invocationSite,
5443
			ObjectVector methodsFound,
5295
			final boolean isInsideAnnotationAttribute) {
5444
			InvocationSite invocationSite,
5296
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5445
			Scope invocationScope,
5297
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5446
			boolean implicitCall,
5298
			new MissingTypesGuesser.GuessedTypeRequestor() {
5447
			boolean superCall,
5299
				public void accept(
5448
			Binding[] missingElements,
5300
						TypeBinding guessedType,
5449
			int[] missingElementsStarts,
5301
						Binding[] missingElements,
5450
			int[] missingElementsEnds,
5302
						int[] missingElementsStarts,
5451
			boolean missingElementsHaveProblems,
5303
						int[] missingElementsEnds,
5452
			char[][] receiverName,
5304
						boolean hasProblems) {
5453
			int receiverStart,
5305
					if (guessedType instanceof ReferenceBinding) {
5454
			int receiverEnd) {
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
	}
5323
5455
5324
	// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
5456
		if (receiverType.resolvedType == null) return;
5325
	private void findMemberTypes(
5326
		char[] typeName,
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,
5336
		Binding[] missingElements,
5337
		int[] missingElementsStarts,
5338
		int[] missingElementsEnds,
5339
		boolean missingElementsHaveProblems) {
5340
5457
5341
		// Inherited member types which are hidden by subclasses are filtered out
5458
		TypeBinding receiverTypeBinding = receiverType.resolvedType;
5342
		// No visibility checks can be performed without the scope & invocationSite
5459
		char[] castedReceiver = null;
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
5460
5349
			if (staticOnly && !memberType.isStatic()) continue next;
5461
		char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
5462
		if(this.source != null) {
5463
			int memberRefStart = this.startPosition;
5350
5464
5351
			if (isForbidden(memberType)) continue next;
5465
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5466
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
5352
5467
5353
			if (typeLength > memberType.sourceName.length)
5468
			castedReceiver =
5354
				continue next;
5469
				CharOperation.concat(
5470
					CharOperation.concat(
5471
						'(',
5472
						CharOperation.concat(
5473
							CharOperation.concat('(', castedTypeChars, ')'),
5474
							receiverChars),
5475
						')'),
5476
					dotChars);
5477
		} else {
5478
			castedReceiver =
5479
				CharOperation.concat(
5480
					CharOperation.concat(
5481
						'(',
5482
						CharOperation.concat(
5483
							CharOperation.concat('(', castedTypeChars, ')'),
5484
							CharOperation.concatWith(receiverName, '.')),
5485
						')'),
5486
					DOT);
5487
		}
5355
5488
5356
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
5489
		if (castedReceiver == null) return;
5357
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
5358
				continue next;
5359
5490
5360
			if (this.options.checkDeprecation &&
5491
		int oldStartPosition = this.startPosition;
5361
					memberType.isViewedAsDeprecated() &&
5492
		this.startPosition = receiverStart;
5362
					!scope.isDefinedInSameUnit(memberType))
5363
				continue next;
5364
5493
5365
			if (this.options.checkVisibility) {
5494
		findFieldsAndMethods(
5366
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
5495
				token,
5367
					continue next;
5496
				receiverTypeBinding,
5368
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
5497
				scope,
5369
					continue next;
5498
				fieldsFound,
5370
				}
5499
				methodsFound,
5371
			}
5500
				invocationSite,
5501
				invocationScope,
5502
				implicitCall,
5503
				superCall,
5504
				missingElements,
5505
				missingElementsStarts,
5506
				missingElementsEnds,
5507
				missingElementsHaveProblems,
5508
				castedReceiver,
5509
				receiverStart,
5510
				receiverEnd);
5372
5511
5373
			if (this.insideQualifiedReference &&
5512
		this.startPosition = oldStartPosition;
5374
					receiverType.isParameterizedType() &&
5513
	}
5375
					memberType.isStatic()) {
5514
	private void findFieldsAndMethodsFromCastedReceiver(
5376
				continue next;
5515
			ASTNode enclosingNode,
5377
			}
5516
			Binding qualifiedBinding,
5517
			Scope scope,
5518
			ObjectVector fieldsFound,
5519
			ObjectVector methodsFound,
5520
			InvocationSite invocationSite,
5521
			Scope invocationScope,
5522
			Expression receiver) {
5378
5523
5379
			for (int i = typesFound.size; --i >= 0;) {
5524
		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
5380
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
5381
5525
5382
				if (memberType == otherType)
5526
		IfStatement ifStatement = (IfStatement)enclosingNode;
5383
					continue next;
5384
5527
5385
				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
5528
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
5386
5529
5387
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
5530
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
5388
						continue next;
5389
5531
5390
					if (otherType.enclosingType().isInterface())
5532
		TypeReference instanceOfType = instanceOfExpression.type;
5391
						if (memberType.enclosingType()
5392
							.implementsInterface(otherType.enclosingType(), true))
5393
							continue next;
5394
5533
5395
					if (memberType.enclosingType().isInterface())
5534
		if (instanceOfType.resolvedType == null) return;
5396
						if (otherType.enclosingType()
5535
5397
							.implementsInterface(memberType.enclosingType(), true))
5536
		boolean findFromAnotherReceiver = false;
5398
							continue next;
5537
5399
				}
5538
		char[][] receiverName = null;
5539
		int receiverStart = -1;
5540
		int receiverEnd = -1;
5541
5542
		if (receiver instanceof QualifiedNameReference) {
5543
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
5544
5545
			receiverName = qualifiedNameReference.tokens;
5546
5547
			if (receiverName.length != 1) return;
5548
5549
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
5550
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
5551
5552
			// if (local instanceof X) local.|
5553
			// if (field instanceof X) field.|
5554
			if (instanceOfExpression.expression instanceof SingleNameReference &&
5555
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
5556
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
5557
				findFromAnotherReceiver = true;
5400
			}
5558
			}
5401
5559
5402
			typesFound.add(memberType);
5560
			// if (this.field instanceof X) field.|
5561
			if (instanceOfExpression.expression instanceof FieldReference) {
5562
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
5403
5563
5404
			if(!this.insideQualifiedReference) {
5564
				if (fieldReference.receiver instanceof ThisReference &&
5405
				if(this.assistNodeIsClass) {
5565
						qualifiedBinding instanceof FieldBinding &&
5406
					if(!memberType.isClass()) continue next;
5566
						fieldReference.binding == qualifiedBinding) {
5407
				} else if(this.assistNodeIsInterface) {
5567
							findFromAnotherReceiver = true;
5408
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
5409
				} else if (this.assistNodeIsAnnotation) {
5410
					if(!memberType.isAnnotationType()) continue next;
5411
				}
5568
				}
5412
			}
5569
			}
5570
		} else if (receiver instanceof FieldReference) {
5571
			FieldReference fieldReference1 = (FieldReference) receiver;
5413
5572
5414
			char[] completionName = memberType.sourceName();
5573
			receiverStart = fieldReference1.sourceStart;
5574
			receiverEnd = fieldReference1.sourceEnd + 1;
5415
5575
5416
			boolean isQualified = false;
5576
			if (fieldReference1.receiver instanceof ThisReference) {
5417
			if(checkQualification && !fromStaticImport) {
5577
5418
				char[] memberPackageName = memberType.qualifiedPackageName();
5578
				receiverName = new char[][] {THIS, fieldReference1.token};
5419
				char[] memberTypeName = memberType.sourceName();
5579
5420
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
5580
				// if (field instanceof X) this.field.|
5421
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
5581
				if (instanceOfExpression.expression instanceof SingleNameReference &&
5422
					if (memberPackageName == null || memberPackageName.length == 0)
5582
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
5423
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
5583
					findFromAnotherReceiver = true;
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
				}
5584
				}
5435
			}
5436
5585
5437
			int relevance = computeBaseRelevance();
5586
				// if (this.field instanceof X) this.field.|
5438
			relevance += computeRelevanceForResolution();
5587
				if (instanceOfExpression.expression instanceof FieldReference) {
5439
			relevance += computeRelevanceForInterestingProposal();
5588
					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
5440
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
5441
			relevance += computeRelevanceForExpectingType(memberType);
5442
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
5443
			if(!this.insideQualifiedReference) {
5444
				relevance += computeRelevanceForQualification(isQualified);
5445
			}
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.
5447
5589
5448
			if (memberType.isAnnotationType()) {
5590
					if (fieldReference2.receiver instanceof ThisReference &&
5449
				relevance += computeRelevanceForAnnotation();
5591
							fieldReference2.binding == fieldReference1.binding) {
5450
				relevance += computeRelevanceForAnnotationTarget(memberType);
5592
								findFromAnotherReceiver = true;
5451
			} else if (memberType.isClass()) {
5593
					}
5452
				relevance += computeRelevanceForClass();
5594
				}
5453
				relevance += computeRelevanceForException(memberType.sourceName);
5454
			} else if(memberType.isEnum()) {
5455
				relevance += computeRelevanceForEnum();
5456
			} else if(memberType.isInterface()) {
5457
				relevance += computeRelevanceForInterface();
5458
			}
5595
			}
5596
		}
5459
5597
5460
			if (missingElements != null) {
5598
		if (findFromAnotherReceiver) {
5461
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5599
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
5462
			}
5600
			char[] castedReceiver = null;
5463
5601
5464
			this.noProposal = false;
5602
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
5465
			createTypeProposal(
5603
			if(this.source != null) {
5466
					memberType,
5604
				int memberRefStart = this.startPosition;
5467
					memberType.qualifiedSourceName(),
5468
					IAccessRule.K_ACCESSIBLE,
5469
					completionName,
5470
					relevance,
5471
					missingElements,
5472
					missingElementsStarts,
5473
					missingElementsEnds,
5474
					missingElementsHaveProblems);
5475
		}
5476
	}
5477
5605
5478
	protected void findMemberTypes(
5606
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5479
		char[] typeName,
5607
				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
5480
		ReferenceBinding receiverType,
5481
		Scope scope,
5482
		SourceTypeBinding typeInvocation,
5483
		boolean staticOnly,
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,
5494
				typeInvocation,
5495
				staticOnly,
5496
				staticFieldsAndMethodOnly,
5497
				false,
5498
				false,
5499
				false,
5500
				null,
5501
				typesFound,
5502
				missingElements,
5503
				missingElementsStarts,
5504
				missingElementsEnds,
5505
				missingElementsHaveProblems);
5506
	}
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
5608
5524
		ReferenceBinding currentType = receiverType;
5609
				castedReceiver =
5525
		if (typeName == null)
5610
					CharOperation.concat(
5526
			return;
5611
						CharOperation.concat(
5612
							'(',
5613
							CharOperation.concat(
5614
								CharOperation.concat('(', castedTypeChars, ')'),
5615
								receiverChars),
5616
							')'),
5617
						dotChars);
5618
			} else {
5619
				castedReceiver =
5620
					CharOperation.concat(
5621
						CharOperation.concat(
5622
							'(',
5623
							CharOperation.concat(
5624
								CharOperation.concat('(', castedTypeChars, ')'),
5625
								CharOperation.concatWith(receiverName, '.')),
5626
							')'),
5627
						DOT);
5628
			}
5527
5629
5528
		if (this.insideQualifiedReference
5630
			if (castedReceiver == null) return;
5529
			|| typeName.length == 0) { // do not search up the hierarchy
5530
5631
5531
			findMemberTypes(
5632
			int oldStartPosition = this.startPosition;
5532
				typeName,
5633
			this.startPosition = receiverStart;
5533
				currentType.memberTypes(),
5534
				typesFound,
5535
				receiverType,
5536
				typeInvocation,
5537
				staticOnly,
5538
				staticFieldsAndMethodOnly,
5539
				fromStaticImport,
5540
				checkQualification,
5541
				scope,
5542
				missingElements,
5543
				missingElementsStarts,
5544
				missingElementsEnds,
5545
				missingElementsHaveProblems);
5546
			return;
5547
		}
5548
5634
5549
		ReferenceBinding[] interfacesToVisit = null;
5635
			findFieldsAndMethods(
5550
		int nextPosition = 0;
5636
					this.completionToken,
5637
					receiverTypeBinding,
5638
					scope,
5639
					fieldsFound,
5640
					methodsFound,
5641
					invocationSite,
5642
					invocationScope,
5643
					false,
5644
					false,
5645
					null,
5646
					null,
5647
					null,
5648
					false,
5649
					castedReceiver,
5650
					receiverStart,
5651
					receiverEnd);
5551
5652
5552
		do {
5653
			this.startPosition = oldStartPosition;
5553
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5654
		}
5554
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5655
	}
5555
				if (interfacesToVisit == null) {
5656
	private void findFieldsAndMethodsFromFavorites(
5556
					interfacesToVisit = itsInterfaces;
5657
			char[] token,
5557
					nextPosition = interfacesToVisit.length;
5658
			Scope scope,
5558
				} else {
5659
			InvocationSite invocationSite,
5559
					int itsLength = itsInterfaces.length;
5660
			Scope invocationScope,
5560
					if (nextPosition + itsLength >= interfacesToVisit.length)
5661
			ObjectVector localsFound,
5561
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5662
			ObjectVector fieldsFound,
5562
					nextInterface : for (int a = 0; a < itsLength; a++) {
5663
			ObjectVector methodsFound) {
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
5664
5571
			findMemberTypes(
5665
		ObjectVector methodsFoundFromFavorites = new ObjectVector();
5572
				typeName,
5573
				currentType.memberTypes(),
5574
				typesFound,
5575
				receiverType,
5576
				typeInvocation,
5577
				staticOnly,
5578
				staticFieldsAndMethodOnly,
5579
				fromStaticImport,
5580
				checkQualification,
5581
				scope,
5582
				missingElements,
5583
				missingElementsStarts,
5584
				missingElementsEnds,
5585
				missingElementsHaveProblems);
5586
5666
5587
			currentType = currentType.superclass();
5667
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
5588
		} while (currentType != null);
5589
5668
5590
		if(proposeAllMemberTypes) {
5669
		if (favoriteBindings != null && favoriteBindings.length > 0) {
5591
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
5670
			for (int i = 0; i < favoriteBindings.length; i++) {
5592
			for (int i = 0; i < memberTypes.length; i++) {
5671
				ImportBinding favoriteBinding = favoriteBindings[i];
5593
				if(memberTypes[i] != typeToIgnore) {
5672
				switch (favoriteBinding.resolvedImport.kind()) {
5594
					findSubMemberTypes(
5673
					case Binding.FIELD:
5595
						typeName,
5674
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
5596
						memberTypes[i],
5675
						findFieldsFromFavorites(
5597
						scope,
5676
								token,
5598
						typeInvocation,
5677
								new FieldBinding[]{fieldBinding},
5599
						staticOnly,
5678
								scope,
5600
						staticFieldsAndMethodOnly,
5679
								fieldsFound,
5601
						fromStaticImport,
5680
								localsFound,
5602
						typesFound);
5681
								fieldBinding.declaringClass,
5682
								invocationSite,
5683
								invocationScope);
5684
						break;
5685
					case Binding.METHOD:
5686
						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
5687
						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
5688
						long range;
5689
						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
5690
							int start = (int) range, end = (int) (range >> 32);
5691
							int length = end - start + 1;
5692
							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
5693
						} else {
5694
							methods = Binding.NO_METHODS;
5695
						}
5696
						findLocalMethodsFromFavorites(
5697
								token,
5698
								methods,
5699
								scope,
5700
								methodsFound,
5701
								methodsFoundFromFavorites,
5702
								methodBinding.declaringClass,
5703
								invocationSite,
5704
								invocationScope);
5705
						break;
5706
					case Binding.TYPE:
5707
						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
5708
						if(favoriteBinding.onDemand) {
5709
							findFieldsFromFavorites(
5710
									token,
5711
									referenceBinding.availableFields(),
5712
									scope,
5713
									fieldsFound,
5714
									localsFound,
5715
									referenceBinding,
5716
									invocationSite,
5717
									invocationScope);
5718
5719
							findLocalMethodsFromFavorites(
5720
									token,
5721
									referenceBinding.availableMethods(),
5722
									scope,
5723
									methodsFound,
5724
									methodsFoundFromFavorites,
5725
									referenceBinding,
5726
									invocationSite,
5727
									invocationScope);
5728
						}
5729
						break;
5603
				}
5730
				}
5604
			}
5731
			}
5605
		}
5732
		}
5606
5733
5607
		if (interfacesToVisit != null) {
5734
		methodsFound.addAll(methodsFoundFromFavorites);
5608
			for (int i = 0; i < nextPosition; i++) {
5735
	}
5609
				ReferenceBinding anInterface = interfacesToVisit[i];
5610
				findMemberTypes(
5611
					typeName,
5612
					anInterface.memberTypes(),
5613
					typesFound,
5614
					receiverType,
5615
					typeInvocation,
5616
					staticOnly,
5617
					staticFieldsAndMethodOnly,
5618
					fromStaticImport,
5619
					checkQualification,
5620
					scope,
5621
					missingElements,
5622
					missingElementsStarts,
5623
					missingElementsEnds,
5624
					missingElementsHaveProblems);
5625
5736
5626
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5737
	private boolean findFieldsAndMethodsFromMissingFieldType(
5627
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5738
		char[] token,
5628
					int itsLength = itsInterfaces.length;
5739
		Scope scope,
5629
					if (nextPosition + itsLength >= interfacesToVisit.length)
5740
		InvocationSite invocationSite,
5630
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5741
		boolean insideTypeAnnotation) {
5631
					nextInterface : for (int a = 0; a < itsLength; a++) {
5742
5632
						ReferenceBinding next = itsInterfaces[a];
5743
		boolean foundSomeFields = false;
5633
						for (int b = 0; b < nextPosition; b++)
5744
5634
							if (next == interfacesToVisit[b]) continue nextInterface;
5745
		boolean staticsOnly = false;
5635
						interfacesToVisit[nextPosition++] = next;
5746
		Scope currentScope = scope;
5747
5748
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5749
5750
			switch (currentScope.kind) {
5751
5752
				case Scope.METHOD_SCOPE :
5753
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5754
					MethodScope methodScope = (MethodScope) currentScope;
5755
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5756
					break;
5757
				case Scope.CLASS_SCOPE :
5758
					ClassScope classScope = (ClassScope) currentScope;
5759
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5760
					if(!insideTypeAnnotation) {
5761
5762
						FieldDeclaration[] fields = classScope.referenceContext.fields;
5763
5764
						int fieldsCount = fields == null ? 0 : fields.length;
5765
						for (int i = 0; i < fieldsCount; i++) {
5766
							FieldDeclaration fieldDeclaration = fields[i];
5767
							if (CharOperation.equals(fieldDeclaration.name, token)) {
5768
								FieldBinding fieldBinding = fieldDeclaration.binding;
5769
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
5770
									foundSomeFields = true;
5771
									findFieldsAndMethodsFromMissingType(
5772
											fieldDeclaration.type,
5773
											currentScope,
5774
											invocationSite,
5775
											scope);
5776
								}
5777
								break done;
5778
							}
5779
						}
5636
					}
5780
					}
5637
				}
5781
					staticsOnly |= enclosingType.isStatic();
5782
					insideTypeAnnotation = false;
5783
					break;
5784
				case Scope.COMPILATION_UNIT_SCOPE :
5785
					break done;
5638
			}
5786
			}
5787
			currentScope = currentScope.parent;
5639
		}
5788
		}
5789
		return foundSomeFields;
5640
	}
5790
	}
5641
5791
5642
	private void findMemberTypesFromMissingType(
5792
	private void findFieldsAndMethodsFromMissingReturnType(
5643
			char[] typeName,
5793
		char[] token,
5644
			final long pos,
5794
		TypeBinding[] arguments,
5645
			final Scope scope)  {
5795
		Scope scope,
5646
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5796
		InvocationSite invocationSite,
5647
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5797
		boolean insideTypeAnnotation) {
5648
			new MissingTypesGuesser.GuessedTypeRequestor() {
5798
5649
				public void accept(
5799
		boolean staticsOnly = false;
5650
						TypeBinding guessedType,
5800
		Scope currentScope = scope;
5651
						Binding[] missingElements,
5801
5652
						int[] missingElementsStarts,
5802
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5653
						int[] missingElementsEnds,
5803
5654
						boolean hasProblems) {
5804
			switch (currentScope.kind) {
5655
					if (guessedType instanceof ReferenceBinding) {
5805
5656
						findMemberTypes(
5806
				case Scope.METHOD_SCOPE :
5657
								CompletionEngine.this.completionToken,
5807
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5658
								(ReferenceBinding)guessedType,
5808
					MethodScope methodScope = (MethodScope) currentScope;
5659
								scope,
5809
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5660
								scope.enclosingSourceType(),
5810
					break;
5661
								false,
5811
				case Scope.CLASS_SCOPE :
5662
								false,
5812
					ClassScope classScope = (ClassScope) currentScope;
5663
								new ObjectVector(),
5813
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5664
								missingElements,
5814
					if(!insideTypeAnnotation) {
5665
								missingElementsStarts,
5815
5666
								missingElementsEnds,
5816
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
5667
								hasProblems);
5817
5818
						int methodsCount = methods == null ? 0 : methods.length;
5819
						for (int i = 0; i < methodsCount; i++) {
5820
							AbstractMethodDeclaration methodDeclaration = methods[i];
5821
							if (methodDeclaration instanceof MethodDeclaration &&
5822
									CharOperation.equals(methodDeclaration.selector, token)) {
5823
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
5824
								MethodBinding methodBinding = method.binding;
5825
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
5826
									Argument[] parameters = method.arguments;
5827
									int parametersLength = parameters == null ? 0 : parameters.length;
5828
									int argumentsLength = arguments == null ? 0 : arguments.length;
5829
5830
									if (parametersLength == 0) {
5831
										if (argumentsLength == 0) {
5832
											findFieldsAndMethodsFromMissingType(
5833
													method.returnType,
5834
													currentScope,
5835
													invocationSite,
5836
													scope);
5837
											break done;
5838
										}
5839
									} else {
5840
										TypeBinding[] parametersBindings;
5841
										if (methodBinding == null) { // since no binding, extra types from type references
5842
											parametersBindings = new TypeBinding[parametersLength];
5843
											for (int j = 0; j < parametersLength; j++) {
5844
												TypeBinding parameterType = parameters[j].type.resolvedType;
5845
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
5846
													parameterType = parameterType.closestMatch();
5847
												}
5848
												parametersBindings[j] = parameterType;
5849
											}
5850
										} else {
5851
											parametersBindings = methodBinding.parameters;
5852
										}
5853
										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
5854
											findFieldsAndMethodsFromMissingType(
5855
													method.returnType,
5856
													currentScope,
5857
													invocationSite,
5858
													scope);
5859
											break done;
5860
										}
5861
									}
5862
								}
5863
5864
							}
5865
						}
5668
					}
5866
					}
5669
				}
5867
					staticsOnly |= enclosingType.isStatic();
5670
			};
5868
					insideTypeAnnotation = false;
5671
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
5869
					break;
5672
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
5870
				case Scope.COMPILATION_UNIT_SCOPE :
5673
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5871
					break done;
5872
			}
5873
			currentScope = currentScope.parent;
5874
		}
5674
	}
5875
	}
5675
5876
5676
	private void findMemberTypesFromMissingType(
5877
	private void findFieldsAndMethodsFromMissingType(
5677
			TypeReference typeRef,
5878
			TypeReference typeRef,
5678
			final long pos,
5879
			final Scope scope,
5679
			final Scope scope)  {
5880
			final InvocationSite invocationSite,
5881
			final Scope invocationScope) {
5680
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5882
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5681
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5883
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5682
			new MissingTypesGuesser.GuessedTypeRequestor() {
5884
			new MissingTypesGuesser.GuessedTypeRequestor() {
Lines 5686-5896 Link Here
5686
						int[] missingElementsStarts,
5888
						int[] missingElementsStarts,
5687
						int[] missingElementsEnds,
5889
						int[] missingElementsEnds,
5688
						boolean hasProblems) {
5890
						boolean hasProblems) {
5689
					if (guessedType instanceof ReferenceBinding) {
5891
					findFieldsAndMethods(
5690
						findMemberTypes(
5892
						CompletionEngine.this.completionToken,
5691
								CompletionEngine.this.completionToken,
5893
						guessedType,
5692
								(ReferenceBinding)guessedType,
5894
						scope,
5693
								scope,
5895
						new ObjectVector(),
5694
								scope.enclosingSourceType(),
5896
						new ObjectVector(),
5695
								false,
5897
						invocationSite,
5696
								false,
5898
						invocationScope,
5697
								new ObjectVector(),
5899
						false,
5698
								missingElements,
5900
						false,
5699
								missingElementsStarts,
5901
						missingElements,
5700
								missingElementsEnds,
5902
						missingElementsStarts,
5701
								hasProblems);
5903
						missingElementsEnds,
5702
					}
5904
						hasProblems,
5905
						null,
5906
						-1,
5907
						-1);
5908
5703
				}
5909
				}
5704
			};
5910
			};
5705
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5911
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5706
	}
5912
	}
5707
5913
5708
	/*
5914
	private void findFieldsAndMethodsFromStaticImports(
5709
	 * Find javadoc parameter names.
5915
			char[] token,
5710
	 */
5916
			Scope scope,
5711
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
5917
			InvocationSite invocationSite,
5712
5918
			Scope invocationScope,
5713
		if (missingParams == null) return;
5919
			boolean exactMatch,
5714
5920
			boolean insideAnnotationAttribute,
5715
		// Get relevance
5921
			ObjectVector localsFound,
5716
		int relevance = computeBaseRelevance();
5922
			ObjectVector fieldsFound,
5717
		relevance += computeRelevanceForInterestingProposal();
5923
			ObjectVector methodsFound,
5718
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
5924
			boolean proposeField,
5719
		if (!isTypeParam) relevance += R_INTERESTING;
5925
			boolean proposeMethod) {
5720
5926
		// search in static import
5721
		// Propose missing param
5927
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
5722
		int length = missingParams.length;
5928
		for (int i = 0; i < importBindings.length; i++) {
5723
		relevance += length;
5929
			ImportBinding importBinding = importBindings[i];
5724
		for (int i=0; i<length; i++) {
5930
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
5725
			char[] argName = missingParams[i];
5931
				Binding binding = importBinding.resolvedImport;
5726
			if (token == null || CharOperation.prefixEquals(token, argName)) {
5932
				if(binding != null && binding.isValidBinding()) {
5727
5933
					if(importBinding.onDemand) {
5728
				this.noProposal = false;
5934
						if((binding.kind() & Binding.TYPE) != 0) {
5729
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
5935
							if(proposeField) {
5730
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
5936
								findFields(
5731
					proposal.setName(argName);
5937
									token,
5732
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
5938
									(ReferenceBinding)binding,
5733
					proposal.setCompletion(completion);
5939
									scope,
5734
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5940
									fieldsFound,
5735
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5941
									localsFound,
5736
					proposal.setRelevance(--relevance);
5942
									true,
5737
					this.requestor.accept(proposal);
5943
									invocationSite,
5738
					if (DEBUG) {
5944
									invocationScope,
5739
						this.printDebug(proposal);
5945
									true,
5740
					}
5946
									false,
5947
									null,
5948
									null,
5949
									null,
5950
									false,
5951
									null,
5952
									-1,
5953
									-1);
5954
							}
5955
							if(proposeMethod && !insideAnnotationAttribute) {
5956
								findMethods(
5957
									token,
5958
									null,
5959
									null,
5960
									(ReferenceBinding)binding,
5961
									scope,
5962
									methodsFound,
5963
									true,
5964
									exactMatch,
5965
									invocationSite,
5966
									invocationScope,
5967
									true,
5968
									false,
5969
									false,
5970
									null,
5971
									null,
5972
									null,
5973
									false,
5974
									null,
5975
									-1,
5976
									-1);
5977
							}
5978
						}
5979
					} else {
5980
						if ((binding.kind() & Binding.FIELD) != 0) {
5981
							if(proposeField) {
5982
									findFields(
5983
											token,
5984
											new FieldBinding[]{(FieldBinding)binding},
5985
											scope,
5986
											fieldsFound,
5987
											localsFound,
5988
											true,
5989
											((FieldBinding)binding).declaringClass,
5990
											invocationSite,
5991
											invocationScope,
5992
											true,
5993
											false,
5994
											null,
5995
											null,
5996
											null,
5997
											false,
5998
											null,
5999
											-1,
6000
											-1);
6001
							}
6002
						} else if ((binding.kind() & Binding.METHOD) != 0) {
6003
							if(proposeMethod && !insideAnnotationAttribute) {
6004
								MethodBinding methodBinding = (MethodBinding)binding;
6005
								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
6006
										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
6007
6008
									findLocalMethodsFromStaticImports(
6009
											methodBinding.selector,
6010
											methodBinding.declaringClass.methods(),
6011
											scope,
6012
											exactMatch,
6013
											methodsFound,
6014
											methodBinding.declaringClass,
6015
											invocationSite);
6016
								}
6017
							}
6018
						}
6019
					}
5741
				}
6020
				}
5742
			}
6021
			}
5743
		}
6022
		}
5744
	}
6023
	}
5745
6024
5746
	private void findSubMemberTypes(
6025
	private void findFieldsFromFavorites(
5747
		char[] typeName,
6026
			char[] fieldName,
5748
		ReferenceBinding receiverType,
6027
			FieldBinding[] fields,
5749
		Scope scope,
6028
			Scope scope,
5750
		SourceTypeBinding typeInvocation,
6029
			ObjectVector fieldsFound,
5751
		boolean staticOnly,
6030
			ObjectVector localsFound,
5752
		boolean staticFieldsAndMethodOnly,
6031
			ReferenceBinding receiverType,
5753
		boolean fromStaticImport,
6032
			InvocationSite invocationSite,
5754
		ObjectVector typesFound) {
6033
			Scope invocationScope) {
5755
6034
5756
		ReferenceBinding currentType = receiverType;
6035
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
5757
		if (typeName == null || typeName.length == 0)
5758
			return;
5759
6036
5760
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
6037
		int fieldLength = fieldName.length;
6038
		next : for (int f = fields.length; --f >= 0;) {
6039
			FieldBinding field = fields[f];
5761
6040
5762
		findMemberTypes(
6041
			if (field.isSynthetic())	continue next;
5763
				typeName,
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
6042
5778
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
6043
			// only static fields must be proposed
5779
		next : for (int i = 0; i < memberTypes.length; i++) {
6044
			if (!field.isStatic()) continue next;
5780
			if (this.options.checkVisibility) {
5781
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
5782
					continue next;
5783
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
5784
					continue next;
5785
				}
5786
			}
5787
			findSubMemberTypes(
5788
				typeName,
5789
				memberTypes[i],
5790
				scope,
5791
				typeInvocation,
5792
				staticOnly,
5793
				staticFieldsAndMethodOnly,
5794
				fromStaticImport,
5795
				typesFound);
5796
		}
5797
	}
5798
6045
5799
	private void findInterfacesMethods(
6046
			if (fieldLength > field.name.length) continue next;
5800
		char[] selector,
5801
		TypeBinding[] typeArgTypes,
5802
		TypeBinding[] argTypes,
5803
		ReferenceBinding receiverType,
5804
		ReferenceBinding[] itsInterfaces,
5805
		Scope scope,
5806
		ObjectVector methodsFound,
5807
		boolean onlyStaticMethods,
5808
		boolean exactMatch,
5809
		boolean isCompletingDeclaration,
5810
		InvocationSite invocationSite,
5811
		Scope invocationScope,
5812
		boolean implicitCall,
5813
		boolean superCall,
5814
		boolean canBePrefixed,
5815
		Binding[] missingElements,
5816
		int[] missingElementssStarts,
5817
		int[] missingElementsEnds,
5818
		boolean missingElementsHaveProblems,
5819
		char[] castedReceiver,
5820
		int receiverStart,
5821
		int receiverEnd) {
5822
6047
5823
		if (selector == null)
6048
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
5824
			return;
6049
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
5825
6050
5826
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6051
			if (this.options.checkDeprecation &&
5827
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6052
					field.isViewedAsDeprecated() &&
5828
			int nextPosition = interfacesToVisit.length;
6053
					!scope.isDefinedInSameUnit(field.declaringClass))
6054
				continue next;
5829
6055
5830
			for (int i = 0; i < nextPosition; i++) {
6056
			if (this.options.checkVisibility
5831
				ReferenceBinding currentType = interfacesToVisit[i];
6057
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
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
6058
5868
				itsInterfaces = currentType.superInterfaces();
6059
			for (int i = fieldsFound.size; --i >= 0;) {
5869
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6060
				Object[] other = (Object[])fieldsFound.elementAt(i);
5870
					int itsLength = itsInterfaces.length;
6061
				FieldBinding otherField = (FieldBinding) other[0];
5871
					if (nextPosition + itsLength >= interfacesToVisit.length)
6062
5872
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6063
				if (field == otherField) continue next;
5873
					nextInterface : for (int a = 0; a < itsLength; a++) {
5874
						ReferenceBinding next = itsInterfaces[a];
5875
						for (int b = 0; b < nextPosition; b++)
5876
							if (next == interfacesToVisit[b]) continue nextInterface;
5877
						interfacesToVisit[nextPosition++] = next;
5878
					}
5879
				}
5880
			}
6064
			}
5881
		}
5882
	}
5883
6065
5884
	private void findImplicitMessageSends(
6066
			fieldsFound.add(new Object[]{field, receiverType});
5885
		char[] token,
5886
		TypeBinding[] argTypes,
5887
		Scope scope,
5888
		InvocationSite invocationSite,
5889
		Scope invocationScope,
5890
		ObjectVector methodsFound) {
5891
6067
5892
		if (token == null)
6068
			int relevance = computeBaseRelevance();
5893
			return;
6069
			relevance += computeRelevanceForResolution();
6070
			relevance += computeRelevanceForInterestingProposal(field);
6071
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6072
			relevance += computeRelevanceForExpectingType(field.type);
6073
			relevance += computeRelevanceForEnumConstant(field.type);
6074
			relevance += computeRelevanceForStatic(true, true);
6075
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6076
6077
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6078
			int importStart = cu.types[0].declarationSourceStart;
6079
			int importEnd = importStart;
6080
6081
			this.noProposal = false;
6082
6083
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
6084
					!this.options.suggestStaticImport) {
6085
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
6086
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
6087
6088
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6089
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6090
					proposal.setSignature(getSignature(field.type));
6091
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6092
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6093
					proposal.setPackageName(field.type.qualifiedPackageName());
6094
					proposal.setTypeName(field.type.qualifiedSourceName());
6095
					proposal.setName(field.name);
6096
					proposal.setCompletion(completion);
6097
					proposal.setFlags(field.modifiers);
6098
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6099
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6100
					proposal.setRelevance(relevance);
6101
6102
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
6103
6104
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
6105
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
6106
					typeImportProposal.completionEngine = this;
6107
					char[] packageName = receiverType.qualifiedPackageName();
6108
					typeImportProposal.setDeclarationSignature(packageName);
6109
					typeImportProposal.setSignature(getSignature(receiverType));
6110
					typeImportProposal.setPackageName(packageName);
6111
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
6112
					typeImportProposal.setCompletion(typeImportCompletion);
6113
					typeImportProposal.setFlags(receiverType.modifiers);
6114
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
6115
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6116
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6117
					typeImportProposal.setRelevance(relevance);
6118
6119
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
6120
6121
					this.requestor.accept(proposal);
6122
					if(DEBUG) {
6123
						this.printDebug(proposal);
6124
					}
6125
				}
6126
			} else {
6127
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
6128
					char[] completion = field.name;
6129
6130
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6131
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6132
					proposal.setSignature(getSignature(field.type));
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);
6143
6144
					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
6145
6146
					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
6147
					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
6148
					fieldImportProposal.setSignature(getSignature(field.type));
6149
					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6150
					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6151
					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
6152
					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
6153
					fieldImportProposal.setName(field.name);
6154
					fieldImportProposal.setCompletion(fieldImportCompletion);
6155
					fieldImportProposal.setFlags(field.modifiers);
6156
					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
6157
					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6158
					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6159
					fieldImportProposal.setRelevance(relevance);
6160
6161
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
6162
6163
					this.requestor.accept(proposal);
6164
					if(DEBUG) {
6165
						this.printDebug(proposal);
6166
					}
6167
				}
6168
			}
6169
		}
6170
	}
6171
	private void findImplicitMessageSends(
6172
		char[] token,
6173
		TypeBinding[] argTypes,
6174
		Scope scope,
6175
		InvocationSite invocationSite,
6176
		Scope invocationScope,
6177
		ObjectVector methodsFound) {
6178
6179
		if (token == null)
6180
			return;
5894
6181
5895
		boolean staticsOnly = false;
6182
		boolean staticsOnly = false;
5896
		// need to know if we're in a static context (or inside a constructor)
6183
		// need to know if we're in a static context (or inside a constructor)
Lines 5917-5923 Link Here
5917
						methodsFound,
6204
						methodsFound,
5918
						staticsOnly,
6205
						staticsOnly,
5919
						true,
6206
						true,
5920
						false,
5921
						invocationSite,
6207
						invocationSite,
5922
						invocationScope,
6208
						invocationScope,
5923
						true,
6209
						true,
Lines 5939-6075 Link Here
5939
			scope = scope.parent;
6225
			scope = scope.parent;
5940
		}
6226
		}
5941
	}
6227
	}
6228
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
6229
		char[][] tokens = importReference.tokens;
5942
6230
5943
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6231
		char[] importName = CharOperation.concatWith(tokens, '.');
5944
	private void findLocalMethods(
5945
		char[] methodName,
5946
		TypeBinding[] typeArgTypes,
5947
		TypeBinding[] argTypes,
5948
		MethodBinding[] methods,
5949
		Scope scope,
5950
		ObjectVector methodsFound,
5951
		boolean onlyStaticMethods,
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
6232
5967
		ObjectVector newMethodsFound =  new ObjectVector();
6233
		if (importName.length == 0)
5968
		// Inherited methods which are hidden by subclasses are filtered out
6234
			return;
5969
		// No visibility checks can be performed without the scope & invocationSite
5970
6235
5971
		int methodLength = methodName.length;
6236
		char[] lastToken = tokens[tokens.length - 1];
5972
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
6237
		if(lastToken != null && lastToken.length == 0)
5973
		int minArgLength = argTypes == null ? 0 : argTypes.length;
6238
			importName = CharOperation.concat(importName, new char[]{'.'});
5974
6239
5975
		next : for (int f = methods.length; --f >= 0;) {
6240
		this.resolvingImports = true;
5976
			MethodBinding method = methods[f];
6241
		this.resolvingStaticImports = importReference.isStatic();
5977
6242
5978
			if (method.isSynthetic()) continue next;
6243
		this.completionToken =  lastToken;
6244
		this.qualifiedCompletionToken = importName;
5979
6245
5980
			if (method.isDefaultAbstract())	continue next;
6246
		// want to replace the existing .*;
6247
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
6248
			int oldStart = this.startPosition;
6249
			int oldEnd = this.endPosition;
6250
			setSourceRange(
6251
				importReference.sourceStart,
6252
				importReference.declarationSourceEnd);
6253
			this.nameEnvironment.findPackages(importName, this);
6254
			setSourceRange(
6255
				oldStart,
6256
				oldEnd - 1,
6257
				false);
6258
		}
6259
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6260
			this.foundTypesCount = 0;
6261
			this.nameEnvironment.findTypes(
6262
					importName,
6263
					findMembers,
6264
					this.options.camelCaseMatch,
6265
					IJavaSearchConstants.TYPE,
6266
					this);
6267
			acceptTypes(null);
6268
		}
6269
	}
5981
6270
5982
			if (method.isConstructor()) continue next;
6271
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
6272
		ReferenceBinding[] memberTypes = ref.memberTypes();
5983
6273
5984
			if (this.options.checkDeprecation &&
6274
		int typeLength = typeName.length;
5985
					method.isViewedAsDeprecated() &&
6275
		next : for (int m = memberTypes.length; --m >= 0;) {
5986
					!scope.isDefinedInSameUnit(method.declaringClass))
6276
			ReferenceBinding memberType = memberTypes[m];
6277
			//		if (!wantClasses && memberType.isClass()) continue next;
6278
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
6279
6280
			if (onlyStatic && !memberType.isStatic())
5987
				continue next;
6281
				continue next;
5988
6282
5989
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
6283
			if (typeLength > memberType.sourceName.length)
5990
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
6284
				continue next;
5991
6285
5992
			if (onlyStaticMethods && !method.isStatic()) continue next;
6286
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
6287
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
6288
				continue next;
5993
6289
5994
			if (this.options.checkVisibility
6290
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
5995
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
5996
6291
5997
			if(superCall && method.isAbstract()) {
6292
			if (this.options.checkVisibility
5998
				methodsFound.add(new Object[]{method, receiverType});
6293
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
5999
				continue next;
6294
				continue next;
6000
			}
6001
6295
6002
			if (exactMatch) {
6296
			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
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
6297
6014
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
6298
			int relevance = computeBaseRelevance();
6015
				continue next;
6299
			relevance += computeRelevanceForResolution();
6300
			relevance += computeRelevanceForInterestingProposal();
6301
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
6302
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6016
6303
6017
			if (minTypeArgLength != 0) {
6304
			if (memberType.isClass()) {
6018
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
6305
				relevance += computeRelevanceForClass();
6306
			} else if(memberType.isEnum()) {
6307
				relevance += computeRelevanceForEnum();
6308
			} else if (memberType.isInterface()) {
6309
				relevance += computeRelevanceForInterface();
6310
			}
6311
			this.noProposal = false;
6312
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6313
				createTypeProposal(
6314
						memberType,
6315
						memberType.qualifiedSourceName(),
6316
						IAccessRule.K_ACCESSIBLE,
6317
						completionName,
6318
						relevance,
6319
						null,
6320
						null,
6321
						null,
6322
						false);
6019
			}
6323
			}
6324
		}
6325
	}
6020
6326
6021
			if (minArgLength > method.parameters.length)
6327
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
6328
		FieldBinding[] fields = ref.availableFields();
6329
6330
		int fieldLength = fieldName.length;
6331
		next : for (int m = fields.length; --m >= 0;) {
6332
			FieldBinding field = fields[m];
6333
6334
			if (fieldLength > field.name.length)
6022
				continue next;
6335
				continue next;
6023
6336
6024
			for (int a = minArgLength; --a >= 0;){
6337
			if (field.isSynthetic())
6025
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
6338
				continue next;
6026
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
6027
						continue next;
6028
					}
6029
				}
6030
			}
6031
6339
6032
			boolean prefixRequired = false;
6340
			if (!field.isStatic())
6341
				continue next;
6033
6342
6034
			for (int i = methodsFound.size; --i >= 0;) {
6343
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
6035
				Object[] other = (Object[]) methodsFound.elementAt(i);
6344
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
6036
				MethodBinding otherMethod = (MethodBinding) other[0];
6345
				continue next;
6037
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6038
				if (method == otherMethod && receiverType == otherReceiverType)
6039
					continue next;
6040
6346
6041
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6347
			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
6042
					if (receiverType == otherReceiverType) {
6043
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6044
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
6045
								continue next;
6046
							}
6047
						}
6048
					} else {
6049
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6050
							if(receiverType.isAnonymousType()) continue next;
6051
6348
6052
							if(!superCall) {
6349
			if (this.options.checkVisibility
6053
								if(!canBePrefixed) continue next;
6350
				&& !field.canBeSeenBy(this.unitScope.fPackage))
6351
				continue next;
6054
6352
6055
								prefixRequired = true;
6353
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
6056
							}
6057
						}
6058
					}
6059
				}
6060
			}
6061
6354
6062
			newMethodsFound.add(new Object[]{method, receiverType});
6355
			int relevance = computeBaseRelevance();
6356
			relevance += computeRelevanceForResolution();
6357
			relevance += computeRelevanceForInterestingProposal();
6358
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6359
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6063
6360
6064
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6361
			this.noProposal = false;
6065
			if (method.declaringClass != superTypeWithSameErasure) {
6362
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
6066
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6363
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6067
				for (int i = 0; i < otherMethods.length; i++) {
6364
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
6068
					if(otherMethods[i].original() == method.original()) {
6365
				proposal.setSignature(getSignature(field.type));
6069
						method = otherMethods[i];
6366
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6070
					}
6367
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6368
				proposal.setPackageName(field.type.qualifiedPackageName());
6369
				proposal.setTypeName(field.type.qualifiedSourceName());
6370
				proposal.setName(field.name);
6371
				proposal.setCompletion(completionName);
6372
				proposal.setFlags(field.modifiers);
6373
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6374
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6375
				proposal.setRelevance(relevance);
6376
				this.requestor.accept(proposal);
6377
				if(DEBUG) {
6378
					this.printDebug(proposal);
6071
				}
6379
				}
6072
			}
6380
			}
6381
		}
6382
	}
6383
6384
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
6385
		MethodBinding[] methods = ref.availableMethods();
6386
6387
		int methodLength = methodName.length;
6388
		next : for (int m = methods.length; --m >= 0;) {
6389
			MethodBinding method = methods[m];
6390
6391
			if (method.isSynthetic()) continue next;
6392
6393
			if (method.isDefaultAbstract())	continue next;
6394
6395
			if (method.isConstructor()) continue next;
6396
6397
			if (!method.isStatic()) continue next;
6398
6399
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
6400
6401
			if (this.options.checkVisibility
6402
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
6403
6404
			if (methodLength > method.selector.length)
6405
				continue next;
6406
6407
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
6408
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6409
				continue next;
6073
6410
6074
			int length = method.parameters.length;
6411
			int length = method.parameters.length;
6075
			char[][] parameterPackageNames = new char[length][];
6412
			char[][] parameterPackageNames = new char[length][];
Lines 6082-6728 Link Here
6082
			}
6419
			}
6083
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6420
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6084
6421
6085
			char[] completion = CharOperation.NO_CHAR;
6422
			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
6086
6087
			int previousStartPosition = this.startPosition;
6088
			int previousTokenStart = this.tokenStart;
6089
6090
			// Special case for completion in javadoc
6091
			if (this.assistNodeInJavadoc > 0) {
6092
				Expression receiver = null;
6093
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
6094
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
6095
					receiver = msg.receiver;
6096
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
6097
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
6098
					receiver = fieldRef.receiver;
6099
				}
6100
				if (receiver != null) {
6101
					StringBuffer javadocCompletion = new StringBuffer();
6102
					if (receiver.isThis()) {
6103
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
6104
							javadocCompletion.append('#');
6105
						}
6106
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
6107
						if (receiver instanceof JavadocSingleTypeReference) {
6108
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
6109
							javadocCompletion.append(typeRef.token);
6110
							javadocCompletion.append('#');
6111
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
6112
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
6113
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
6114
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
6115
								if (t>0) javadocCompletion.append('.');
6116
								javadocCompletion.append(typeRef.tokens[t]);
6117
							}
6118
							javadocCompletion.append('#');
6119
						}
6120
					}
6121
					javadocCompletion.append(method.selector);
6122
					// Append parameters types
6123
					javadocCompletion.append('(');
6124
					if (method.parameters != null) {
6125
						boolean isVarargs = method.isVarargs();
6126
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
6127
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
6128
							TypeBinding argTypeBinding = method.parameters[p];
6129
							if (isVarargs && p == ln - 1)  {
6130
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
6131
							} else {
6132
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
6133
							}
6134
						}
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 {
6156
						this.startPosition = this.endPosition;
6157
					}
6158
					this.tokenStart = this.tokenEnd;
6159
				}
6160
6161
				if(prefixRequired || this.options.forceImplicitQualification){
6162
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
6163
					completion = CharOperation.concat(prefix,completion,'.');
6164
				}
6165
			}
6166
6423
6167
			int relevance = computeBaseRelevance();
6424
			int relevance = computeBaseRelevance();
6168
			relevance += computeRelevanceForResolution();
6425
			relevance += computeRelevanceForResolution();
6169
			relevance += computeRelevanceForInterestingProposal();
6426
			relevance += computeRelevanceForInterestingProposal();
6170
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6427
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6171
			relevance += computeRelevanceForExpectingType(method.returnType);
6172
			relevance += computeRelevanceForEnumConstant(method.returnType);
6173
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
6174
			relevance += computeRelevanceForQualification(prefixRequired);
6175
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6428
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6176
			if (onlyStaticMethods && this.insideQualifiedReference) {
6177
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
6178
			}
6179
			if (missingElements != null) {
6180
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
6181
			}
6182
6429
6183
			this.noProposal = false;
6430
			this.noProposal = false;
6184
6431
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
6185
			if (castedReceiver == null) {
6432
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
6186
				// Standard proposal
6433
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6187
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
6434
				proposal.setSignature(getSignature(method));
6188
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6435
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6189
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6436
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6190
					proposal.setSignature(getSignature(method));
6437
				proposal.setParameterPackageNames(parameterPackageNames);
6191
					MethodBinding original = method.original();
6438
				proposal.setParameterTypeNames(parameterTypeNames);
6192
					if(original != method) {
6439
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6193
						proposal.setOriginalSignature(getSignature(original));
6440
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6194
					}
6441
				proposal.setName(method.selector);
6195
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6442
				proposal.setCompletion(completionName);
6196
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6443
				proposal.setFlags(method.modifiers);
6197
					proposal.setParameterPackageNames(parameterPackageNames);
6444
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6198
					proposal.setParameterTypeNames(parameterTypeNames);
6445
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6199
					proposal.setPackageName(method.returnType.qualifiedPackageName());
6446
				proposal.setRelevance(relevance);
6200
					proposal.setTypeName(method.returnType.qualifiedSourceName());
6447
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
6201
					proposal.setName(method.selector);
6448
				this.requestor.accept(proposal);
6202
					if (missingElements != null) {
6449
				if(DEBUG) {
6203
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
6450
					this.printDebug(proposal);
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
6226
				// Javadoc proposal
6227
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
6228
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
6229
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
6230
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6231
					proposal.setSignature(getSignature(method));
6232
					MethodBinding original = method.original();
6233
					if(original != method) {
6234
						proposal.setOriginalSignature(getSignature(original));
6235
					}
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
						}
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
					}
6295
				}
6451
				}
6296
			}
6452
			}
6297
			this.startPosition = previousStartPosition;
6298
			this.tokenStart = previousTokenStart;
6299
		}
6453
		}
6300
6301
		methodsFound.addAll(newMethodsFound);
6302
	}
6454
	}
6455
	
6456
	private void findInterfacesMethodDeclarations(
6457
		char[] selector,
6458
		ReferenceBinding receiverType,
6459
		ReferenceBinding[] itsInterfaces,
6460
		Scope scope,
6461
		ObjectVector methodsFound,
6462
		Binding[] missingElements,
6463
		int[] missingElementssStarts,
6464
		int[] missingElementsEnds,
6465
		boolean missingElementsHaveProblems) {
6303
6466
6304
	private void findLocalMethodsFromFavorites(
6467
		if (selector == null)
6305
			char[] methodName,
6468
			return;
6306
			MethodBinding[] methods,
6307
			Scope scope,
6308
			ObjectVector methodsFound,
6309
			ObjectVector methodsFoundFromFavorites,
6310
			ReferenceBinding receiverType,
6311
			InvocationSite invocationSite,
6312
			Scope invocationScope) {
6313
6314
			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
6315
6316
			int methodLength = methodName.length;
6317
6318
			next : for (int f = methods.length; --f >= 0;) {
6319
				MethodBinding method = methods[f];
6320
6321
				if (method.isSynthetic()) continue next;
6322
6323
				if (method.isDefaultAbstract())	continue next;
6324
6325
				if (method.isConstructor()) continue next;
6326
6327
				if (this.options.checkDeprecation &&
6328
						method.isViewedAsDeprecated() &&
6329
						!scope.isDefinedInSameUnit(method.declaringClass))
6330
					continue next;
6331
6332
				if (!method.isStatic()) continue next;
6333
6334
				if (this.options.checkVisibility
6335
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
6336
6469
6337
				if (methodLength > method.selector.length) continue next;
6470
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6471
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6472
			int nextPosition = interfacesToVisit.length;
6338
6473
6339
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6474
			for (int i = 0; i < nextPosition; i++) {
6340
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6475
				ReferenceBinding currentType = interfacesToVisit[i];
6341
					continue next;
6476
				MethodBinding[] methods = currentType.availableMethods();
6477
				if(methods != null) {
6478
					findLocalMethodDeclarations(
6479
						selector,
6480
						methods,
6481
						scope,
6482
						methodsFound,
6483
						false,
6484
						receiverType);
6342
				}
6485
				}
6343
6486
6344
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
6487
				itsInterfaces = currentType.superInterfaces();
6345
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
6488
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6346
					MethodBinding otherMethod = (MethodBinding) other[0];
6489
					int itsLength = itsInterfaces.length;
6347
6490
					if (nextPosition + itsLength >= interfacesToVisit.length)
6348
					if (method == otherMethod) continue next;
6491
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6349
6492
					nextInterface : for (int a = 0; a < itsLength; a++) {
6350
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6493
						ReferenceBinding next = itsInterfaces[a];
6351
						if (otherMethod.declaringClass == method.declaringClass &&
6494
						for (int b = 0; b < nextPosition; b++)
6352
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6495
							if (next == interfacesToVisit[b]) continue nextInterface;
6353
							continue next;
6496
						interfacesToVisit[nextPosition++] = next;
6354
						}
6355
					}
6497
					}
6356
				}
6498
				}
6499
			}
6500
		}
6501
	}
6502
	
6503
	private void findInterfacesMethods(
6504
		char[] selector,
6505
		TypeBinding[] typeArgTypes,
6506
		TypeBinding[] argTypes,
6507
		ReferenceBinding receiverType,
6508
		ReferenceBinding[] itsInterfaces,
6509
		Scope scope,
6510
		ObjectVector methodsFound,
6511
		boolean onlyStaticMethods,
6512
		boolean exactMatch,
6513
		InvocationSite invocationSite,
6514
		Scope invocationScope,
6515
		boolean implicitCall,
6516
		boolean superCall,
6517
		boolean canBePrefixed,
6518
		Binding[] missingElements,
6519
		int[] missingElementssStarts,
6520
		int[] missingElementsEnds,
6521
		boolean missingElementsHaveProblems,
6522
		char[] castedReceiver,
6523
		int receiverStart,
6524
		int receiverEnd) {
6357
6525
6358
				for (int i = methodsFound.size; --i >= 0;) {
6526
		if (selector == null)
6359
					Object[] other = (Object[]) methodsFound.elementAt(i);
6527
			return;
6360
					MethodBinding otherMethod = (MethodBinding) other[0];
6361
6528
6362
					if (method == otherMethod) continue next;
6529
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6530
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6531
			int nextPosition = interfacesToVisit.length;
6363
6532
6364
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6533
			for (int i = 0; i < nextPosition; i++) {
6365
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6534
				ReferenceBinding currentType = interfacesToVisit[i];
6366
							continue next;
6535
				MethodBinding[] methods = currentType.availableMethods();
6367
						}
6536
				if(methods != null) {
6368
					}
6537
					findLocalMethods(
6538
						selector,
6539
						typeArgTypes,
6540
						argTypes,
6541
						methods,
6542
						scope,
6543
						methodsFound,
6544
						onlyStaticMethods,
6545
						exactMatch,
6546
						receiverType,
6547
						invocationSite,
6548
						invocationScope,
6549
						implicitCall,
6550
						superCall,
6551
						canBePrefixed,
6552
						missingElements,
6553
						missingElementssStarts,
6554
						missingElementsEnds,
6555
						missingElementsHaveProblems,
6556
						castedReceiver,
6557
						receiverStart,
6558
						receiverEnd);
6369
				}
6559
				}
6370
6560
6371
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
6561
				itsInterfaces = currentType.superInterfaces();
6372
					this.options.suggestStaticImport;
6562
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6373
6563
					int itsLength = itsInterfaces.length;
6374
				boolean isAlreadyImported = false;
6564
					if (nextPosition + itsLength >= interfacesToVisit.length)
6375
				if (!proposeStaticImport) {
6565
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6376
					if(!this.importCachesInitialized) {
6566
					nextInterface : for (int a = 0; a < itsLength; a++) {
6377
						initializeImportCaches();
6567
						ReferenceBinding next = itsInterfaces[a];
6378
					}
6568
						for (int b = 0; b < nextPosition; b++)
6379
					for (int j = 0; j < this.importCacheCount; j++) {
6569
							if (next == interfacesToVisit[b]) continue nextInterface;
6380
						char[][] importName = this.importsCache[j];
6570
						interfacesToVisit[nextPosition++] = next;
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
					}
6571
					}
6389
				}
6572
				}
6390
6573
			}
6391
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
6574
		}
6392
6575
	}
6393
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6576
	/*
6394
				if (method.declaringClass != superTypeWithSameErasure) {
6577
	 * Find javadoc block tags for a given completion javadoc tag node
6395
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6578
	 */
6396
					for (int i = 0; i < otherMethods.length; i++) {
6579
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
6397
						if(otherMethods[i].original() == method.original()) {
6580
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
6398
							method = otherMethods[i];
6581
		if (possibleTags == null) return;
6399
						}
6582
		int length = possibleTags.length;
6400
					}
6583
		for (int i=0; i<length; i++) {
6584
			int relevance = computeBaseRelevance();
6585
			relevance += computeRelevanceForInterestingProposal();
6586
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6587
6588
			this.noProposal = false;
6589
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
6590
				char[] possibleTag = possibleTags[i];
6591
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
6592
				proposal.setName(possibleTag);
6593
				int tagLength = possibleTag.length;
6594
				char[] completion = new char[1+tagLength];
6595
				completion[0] = '@';
6596
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
6597
				proposal.setCompletion(completion);
6598
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6599
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6600
				proposal.setRelevance(relevance);
6601
				this.requestor.accept(proposal);
6602
				if (DEBUG) {
6603
					this.printDebug(proposal);
6401
				}
6604
				}
6605
			}
6606
		}
6607
	}
6402
6608
6403
				int length = method.parameters.length;
6609
	/*
6404
				char[][] parameterPackageNames = new char[length][];
6610
	 * Find javadoc inline tags for a given completion javadoc tag node
6405
				char[][] parameterTypeNames = new char[length][];
6611
	 */
6612
	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
6613
		char[][] possibleTags = javadocTag.getPossibleInlineTags();
6614
		if (possibleTags == null) return;
6615
		int length = possibleTags.length;
6616
		for (int i=0; i<length; i++) {
6617
			int relevance = computeBaseRelevance();
6618
			relevance += computeRelevanceForInterestingProposal();
6619
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6406
6620
6407
				for (int i = 0; i < length; i++) {
6621
			this.noProposal = false;
6408
					TypeBinding type = method.original().parameters[i];
6622
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
6409
					parameterPackageNames[i] = type.qualifiedPackageName();
6623
				char[] possibleTag = possibleTags[i];
6410
					parameterTypeNames[i] = type.qualifiedSourceName();
6624
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
6625
				proposal.setName(possibleTag);
6626
				int tagLength = possibleTag.length;
6627
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
6628
				char[] completion = new char[2+tagLength+1];
6629
				completion[0] = '{';
6630
				completion[1] = '@';
6631
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
6632
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
6633
				//completion[tagLength+2] = ' ';
6634
				completion[tagLength+2] = '}';
6635
				proposal.setCompletion(completion);
6636
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6637
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6638
				proposal.setRelevance(relevance);
6639
				this.requestor.accept(proposal);
6640
				if (DEBUG) {
6641
					this.printDebug(proposal);
6411
				}
6642
				}
6412
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6643
			}
6413
6644
		}
6414
				char[] completion = CharOperation.NO_CHAR;
6645
	}
6415
6646
6416
				int previousStartPosition = this.startPosition;
6647
	/*
6417
				int previousTokenStart = this.tokenStart;
6648
	 * Find javadoc parameter names.
6649
	 */
6650
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
6418
6651
6419
				if (this.source != null
6652
		if (missingParams == null) return;
6420
					&& this.source.length > this.endPosition
6421
					&& this.source[this.endPosition] == '(') {
6422
					completion = method.selector;
6423
				} else {
6424
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6425
				}
6426
6653
6427
				int relevance = computeBaseRelevance();
6654
		// Get relevance
6428
				relevance += computeRelevanceForResolution();
6655
		int relevance = computeBaseRelevance();
6429
				relevance += computeRelevanceForInterestingProposal();
6656
		relevance += computeRelevanceForInterestingProposal();
6430
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6657
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
6431
				relevance += computeRelevanceForExpectingType(method.returnType);
6658
		if (!isTypeParam) relevance += R_INTERESTING;
6432
				relevance += computeRelevanceForEnumConstant(method.returnType);
6433
				relevance += computeRelevanceForStatic(true, method.isStatic());
6434
				relevance += computeRelevanceForQualification(true);
6435
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6436
6659
6437
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6660
		// Propose missing param
6438
				int importStart = cu.types[0].declarationSourceStart;
6661
		int length = missingParams.length;
6439
				int importEnd = importStart;
6662
		relevance += length;
6663
		for (int i=0; i<length; i++) {
6664
			char[] argName = missingParams[i];
6665
			if (token == null || CharOperation.prefixEquals(token, argName)) {
6440
6666
6441
				this.noProposal = false;
6667
				this.noProposal = false;
6668
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
6669
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
6670
					proposal.setName(argName);
6671
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
6672
					proposal.setCompletion(completion);
6673
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6674
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6675
					proposal.setRelevance(--relevance);
6676
					this.requestor.accept(proposal);
6677
					if (DEBUG) {
6678
						this.printDebug(proposal);
6679
					}
6680
				}
6681
			}
6682
		}
6683
	}
6442
6684
6443
				if (!proposeStaticImport) {
6685
	// what about onDemand types? Ignore them since it does not happen!
6444
					if (isAlreadyImported) {
6686
	// import p1.p2.A.*;
6445
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
6687
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
6446
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6688
		if(choices == null || choices.length == 0) return;
6447
6448
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6449
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
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
6689
6469
							this.requestor.accept(proposal);
6690
		int length = keyword.length;
6470
							if(DEBUG) {
6691
		if (canCompleteEmptyToken || length > 0)
6471
								this.printDebug(proposal);
6692
			for (int i = 0; i < choices.length; i++)
6472
							}
6693
				if (length <= choices[i].length
6473
						}
6694
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
6474
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
6695
				)){
6475
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6696
					int relevance = computeBaseRelevance();
6697
					relevance += computeRelevanceForResolution();
6698
					relevance += computeRelevanceForInterestingProposal();
6699
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
6700
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
6701
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
6476
6702
6477
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6703
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
6478
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6704
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
6479
						proposal.setSignature(getSignature(method));
6705
						relevance += computeRelevanceForQualification(false);
6480
						MethodBinding original = method.original();
6706
					}
6481
						if(original != method) {
6707
					this.noProposal = false;
6482
							proposal.setOriginalSignature(getSignature(original));
6708
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
6483
						}
6709
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
6484
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6710
						proposal.setName(choices[i]);
6485
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6711
						proposal.setCompletion(choices[i]);
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);
6712
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6494
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6713
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6495
						proposal.setRelevance(relevance);
6714
						proposal.setRelevance(relevance);
6496
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
6497
6498
						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
6499
6500
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
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
6515
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
6516
6517
						this.requestor.accept(proposal);
6715
						this.requestor.accept(proposal);
6518
						if(DEBUG) {
6716
						if(DEBUG) {
6519
							this.printDebug(proposal);
6717
							this.printDebug(proposal);
6520
						}
6718
						}
6521
					}
6719
					}
6522
				} else {
6720
				}
6523
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
6721
	}
6524
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6722
	private void findKeywordsForMember(char[] token, int modifiers) {
6525
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6723
		char[][] keywords = new char[Keywords.COUNT][];
6526
						proposal.setSignature(getSignature(method));
6724
		int count = 0;
6527
						MethodBinding original = method.original();
6528
						if(original != method) {
6529
							proposal.setOriginalSignature(getSignature(original));
6530
						}
6531
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6532
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6533
						proposal.setParameterPackageNames(parameterPackageNames);
6534
						proposal.setParameterTypeNames(parameterTypeNames);
6535
						proposal.setPackageName(method.returnType.qualifiedPackageName());
6536
						proposal.setTypeName(method.returnType.qualifiedSourceName());
6537
						proposal.setName(method.selector);
6538
						proposal.setCompletion(completion);
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
6545
						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
6546
6547
						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
6548
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
6549
						methodImportProposal.setSignature(getSignature(method));
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
6725
6568
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
6726
		// visibility
6727
		if((modifiers & ClassFileConstants.AccPrivate) == 0
6728
			&& (modifiers & ClassFileConstants.AccProtected) == 0
6729
			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
6730
			keywords[count++] = Keywords.PROTECTED;
6731
			keywords[count++] = Keywords.PUBLIC;
6732
			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6733
				keywords[count++] = Keywords.PRIVATE;
6734
			}
6735
		}
6569
6736
6570
						this.requestor.accept(proposal);
6737
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6571
						if(DEBUG) {
6738
			// abtract
6572
							this.printDebug(proposal);
6739
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
6573
						}
6740
				keywords[count++] = Keywords.ABSTRACT;
6574
					}
6741
			}
6742
6743
			// final
6744
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
6745
				keywords[count++] = Keywords.FINAL;
6746
			}
6747
6748
			// static
6749
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
6750
				keywords[count++] = Keywords.STATIC;
6751
			}
6752
6753
			boolean canBeField = true;
6754
			boolean canBeMethod = true;
6755
			boolean canBeType = true;
6756
			if((modifiers & ClassFileConstants.AccNative) != 0
6757
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
6758
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
6759
				canBeField = false;
6760
				canBeType = false;
6761
			}
6762
6763
			if((modifiers & ClassFileConstants.AccTransient) != 0
6764
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
6765
				canBeMethod = false;
6766
				canBeType = false;
6767
			}
6768
6769
			if(canBeField) {
6770
				// transient
6771
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
6772
					keywords[count++] = Keywords.TRANSIENT;
6575
				}
6773
				}
6576
6774
6577
				this.startPosition = previousStartPosition;
6775
				// volatile
6578
				this.tokenStart = previousTokenStart;
6776
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
6777
					keywords[count++] = Keywords.VOLATILE;
6778
				}
6579
			}
6779
			}
6580
		}
6581
6780
6582
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
6781
			if(canBeMethod) {
6583
		InternalCompletionProposal proposal = null;
6782
				// native
6584
		if (binding instanceof ReferenceBinding) {
6783
				if((modifiers & ClassFileConstants.AccNative) == 0) {
6585
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
6784
					keywords[count++] = Keywords.NATIVE;
6785
				}
6586
6786
6587
			char[] packageName = typeBinding.qualifiedPackageName();
6787
				// strictfp
6588
			char[] typeName = typeBinding.qualifiedSourceName();
6788
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
6589
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
6789
					keywords[count++] = Keywords.STRICTFP;
6790
				}
6590
6791
6591
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
6792
				// synchronized
6592
			proposal.nameLookup = this.nameEnvironment.nameLookup;
6793
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
6593
			proposal.completionEngine = this;
6794
					keywords[count++] = Keywords.SYNCHRONIZED;
6594
			proposal.setDeclarationSignature(packageName);
6795
				}
6595
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
6796
			}
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
6797
6606
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
6798
			if(canBeType) {
6799
				keywords[count++] = Keywords.CLASS;
6800
				keywords[count++] = Keywords.INTERFACE;
6607
6801
6608
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
6802
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
6609
			proposal.setDeclarationSignature(packageName);
6803
					keywords[count++] = Keywords.ENUM;
6610
			proposal.setPackageName(packageName);
6804
				}
6611
			proposal.setCompletion(packageName);
6805
			}
6612
			proposal.setReplaceRange(start - this.offset, end - this.offset);
6806
		} else {
6613
			proposal.setTokenRange(start - this.offset, end - this.offset);
6807
			// class
6614
			proposal.setRelevance(relevance);
6808
			keywords[count++] = Keywords.CLASS;
6809
			keywords[count++] = Keywords.INTERFACE;
6615
		}
6810
		}
6616
		return proposal;
6811
		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
6812
6813
		findKeywords(token, keywords, false, false);
6617
	}
6814
	}
6815
	private void findLabels(char[] label, char[][] choices) {
6816
		if(choices == null || choices.length == 0) return;
6618
6817
6619
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6818
		int length = label.length;
6620
	private void findLocalMethodsFromStaticImports(
6819
		for (int i = 0; i < choices.length; i++) {
6820
			if (length <= choices[i].length
6821
				&& CharOperation.prefixEquals(label, choices[i], false /* ignore case */
6822
			)){
6823
				int relevance = computeBaseRelevance();
6824
				relevance += computeRelevanceForResolution();
6825
				relevance += computeRelevanceForInterestingProposal();
6826
				relevance += computeRelevanceForCaseMatching(label, choices[i]);
6827
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6828
6829
				this.noProposal = false;
6830
				if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
6831
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
6832
					proposal.setName(choices[i]);
6833
					proposal.setCompletion(choices[i]);
6834
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6835
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6836
					proposal.setRelevance(relevance);
6837
					this.requestor.accept(proposal);
6838
					if(DEBUG) {
6839
						this.printDebug(proposal);
6840
					}
6841
				}
6842
			}
6843
		}
6844
	}
6845
6846
	// Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
6847
	private void findLocalMethodDeclarations(
6621
		char[] methodName,
6848
		char[] methodName,
6622
		MethodBinding[] methods,
6849
		MethodBinding[] methods,
6623
		Scope scope,
6850
		Scope scope,
6624
		boolean exactMatch,
6625
		ObjectVector methodsFound,
6851
		ObjectVector methodsFound,
6626
		ReferenceBinding receiverType,
6852
		//	boolean noVoidReturnType, how do you know?
6627
		InvocationSite invocationSite) {
6853
		boolean exactMatch,
6854
		ReferenceBinding receiverType) {
6628
6855
6629
		ObjectVector newMethodsFound =  new ObjectVector();
6856
		ObjectVector newMethodsFound =  new ObjectVector();
6630
6857
		// Inherited methods which are hidden by subclasses are filtered out
6858
		// No visibility checks can be performed without the scope & invocationSite
6859
		int methodLength = methodName.length;
6631
		next : for (int f = methods.length; --f >= 0;) {
6860
		next : for (int f = methods.length; --f >= 0;) {
6632
			MethodBinding method = methods[f];
6633
6861
6634
			if (method.isSynthetic()) continue next;
6862
			MethodBinding method = methods[f];
6863
			if (method.isSynthetic())	continue next;
6635
6864
6636
			if (method.isDefaultAbstract())	continue next;
6865
			if (method.isDefaultAbstract()) continue next;
6637
6866
6638
			if (method.isConstructor()) continue next;
6867
			if (method.isConstructor()) continue next;
6639
6868
6640
			if (!method.isStatic()) continue next;
6869
			if (method.isFinal()) {
6870
                newMethodsFound.add(method);
6871
                continue next;
6872
            }
6641
6873
6642
			if (this.options.checkDeprecation &&
6874
			if (this.options.checkDeprecation &&
6643
					method.isViewedAsDeprecated() &&
6875
					method.isViewedAsDeprecated() &&
6644
					!scope.isDefinedInSameUnit(method.declaringClass))
6876
					!scope.isDefinedInSameUnit(method.declaringClass))
6645
				continue next;
6877
				continue next;
6646
6878
6647
			if (this.options.checkVisibility
6879
			//		if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
6648
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
6880
			if(method.isStatic()) continue next;
6649
6881
6650
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
6882
			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
6651
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6883
6652
				continue next;
6884
			if (exactMatch) {
6885
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
6886
					))
6887
					continue next;
6888
6889
			} else {
6890
6891
				if (methodLength > method.selector.length)
6892
					continue next;
6893
6894
				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
6895
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6896
					continue next;
6897
			}
6653
6898
6654
			for (int i = methodsFound.size; --i >= 0;) {
6899
			for (int i = methodsFound.size; --i >= 0;) {
6655
				Object[] other = (Object[]) methodsFound.elementAt(i);
6900
				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
6656
				MethodBinding otherMethod = (MethodBinding) other[0];
6901
				if (method == otherMethod)
6657
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6658
				if (method == otherMethod && receiverType == otherReceiverType)
6659
					continue next;
6902
					continue next;
6660
6903
6661
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6904
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
6662
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6905
						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6663
						continue next;
6906
					continue next;
6664
					}
6665
				}
6907
				}
6666
			}
6908
			}
6667
6909
6668
			newMethodsFound.add(new Object[]{method, receiverType});
6910
			newMethodsFound.add(method);
6669
6911
6670
			int length = method.parameters.length;
6912
			int length = method.parameters.length;
6671
			char[][] parameterPackageNames = new char[length][];
6913
			char[][] parameterPackageNames = new char[length][];
6672
			char[][] parameterTypeNames = new char[length][];
6914
			char[][] parameterFullTypeNames = new char[length][];
6673
6915
6674
			for (int i = 0; i < length; i++) {
6916
			for (int i = 0; i < length; i++) {
6675
				TypeBinding type = method.original().parameters[i];
6917
				TypeBinding type = method.parameters[i];
6676
				parameterPackageNames[i] = type.qualifiedPackageName();
6918
				parameterPackageNames[i] = type.qualifiedPackageName();
6677
				parameterTypeNames[i] = type.qualifiedSourceName();
6919
				parameterFullTypeNames[i] = type.qualifiedSourceName();
6678
			}
6920
			}
6679
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6680
6681
			char[] completion = CharOperation.NO_CHAR;
6682
6921
6683
			int previousStartPosition = this.startPosition;
6922
			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
6684
			int previousTokenStart = this.tokenStart;
6685
6923
6686
			if (!exactMatch) {
6924
			if(method.typeVariables != null && method.typeVariables.length > 0) {
6687
				if (this.source != null
6925
				char[][] excludedNames = findEnclosingTypeNames(scope);
6688
					&& this.source.length > this.endPosition
6926
				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
6689
					&& this.source[this.endPosition] == '(') {
6927
				if(substituedParameterNames != null) {
6690
					completion = method.selector;
6928
					method = new ParameterizedMethodBinding(
6691
				} else {
6929
								method.declaringClass,
6692
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6930
								method,
6693
				}
6931
								substituedParameterNames,
6694
			} else {
6932
								scope.environment());
6695
				this.startPosition = this.endPosition;
6933
				}
6696
				this.tokenStart = this.tokenEnd;
6934
			}
6935
6936
			StringBuffer completion = new StringBuffer(10);
6937
			if (!exactMatch) {
6938
				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
6697
			}
6939
			}
6698
6940
6699
			int relevance = computeBaseRelevance();
6941
			int relevance = computeBaseRelevance();
6700
			relevance += computeRelevanceForResolution();
6942
			relevance += computeRelevanceForResolution();
6701
			relevance += computeRelevanceForInterestingProposal();
6943
			relevance += computeRelevanceForInterestingProposal();
6702
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6944
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6703
			relevance += computeRelevanceForExpectingType(method.returnType);
6945
			relevance += R_METHOD_OVERIDE;
6704
			relevance += computeRelevanceForEnumConstant(method.returnType);
6946
			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
6705
			relevance += computeRelevanceForStatic(true, method.isStatic());
6706
			relevance += computeRelevanceForQualification(false);
6707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6947
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6708
6948
6709
			this.noProposal = false;
6949
			this.noProposal = false;
6710
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
6950
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
6711
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6951
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
6712
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6952
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6953
				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
6713
				proposal.setSignature(getSignature(method));
6954
				proposal.setSignature(getSignature(method));
6714
				MethodBinding original = method.original();
6955
				MethodBinding original = method.original();
6715
				if(original != method) {
6956
				if(original != method) {
6716
					proposal.setOriginalSignature(getSignature(original));
6957
					proposal.setOriginalSignature(getSignature(original));
6717
				}
6958
				}
6959
				proposal.setKey(method.computeUniqueKey());
6718
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6960
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6719
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6961
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6720
				proposal.setParameterPackageNames(parameterPackageNames);
6962
				proposal.setParameterPackageNames(parameterPackageNames);
6721
				proposal.setParameterTypeNames(parameterTypeNames);
6963
				proposal.setParameterTypeNames(parameterFullTypeNames);
6722
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6964
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6723
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6965
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6966
				proposal.setCompletion(completion.toString().toCharArray());
6724
				proposal.setName(method.selector);
6967
				proposal.setName(method.selector);
6725
				proposal.setCompletion(completion);
6726
				proposal.setFlags(method.modifiers);
6968
				proposal.setFlags(method.modifiers);
6727
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6969
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6728
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6970
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
Lines 6733-10022 Link Here
6733
					this.printDebug(proposal);
6975
					this.printDebug(proposal);
6734
				}
6976
				}
6735
			}
6977
			}
6736
			this.startPosition = previousStartPosition;
6737
			this.tokenStart = previousTokenStart;
6738
		}
6978
		}
6739
6740
		methodsFound.addAll(newMethodsFound);
6979
		methodsFound.addAll(newMethodsFound);
6741
	}
6980
	}
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
		}
6768
		return 0;
6769
	}
6770
	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
6771
		if (this.assistNodeIsAnnotation &&
6772
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
6773
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
6774
			if(target == 0 || (target & this.targetedElement) != 0) {
6775
				return R_TARGET;
6776
			}
6777
		}
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
	}
6804
	int computeRelevanceForQualification(boolean prefixRequired) {
6805
		if(!prefixRequired && !this.insideQualifiedReference) {
6806
			return R_UNQUALIFIED;
6807
		}
6808
6981
6809
		if(prefixRequired && this.insideQualifiedReference) {
6982
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6810
			return R_QUALIFIED;
6983
	private void findLocalMethods(
6811
		}
6984
		char[] methodName,
6812
		return 0;
6985
		TypeBinding[] typeArgTypes,
6813
	}
6986
		TypeBinding[] argTypes,
6814
	int computeRelevanceForRestrictions(int accessRuleKind) {
6987
		MethodBinding[] methods,
6815
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
6988
		Scope scope,
6816
			return R_NON_RESTRICTED;
6989
		ObjectVector methodsFound,
6817
		}
6990
		boolean onlyStaticMethods,
6818
		return 0;
6991
		boolean exactMatch,
6819
	}
6992
		ReferenceBinding receiverType,
6820
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
6993
		InvocationSite invocationSite,
6821
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
6994
		Scope invocationScope,
6822
			return R_NON_STATIC;
6995
		boolean implicitCall,
6823
		}
6996
		boolean superCall,
6824
		return 0;
6997
		boolean canBePrefixed,
6825
	}
6998
		Binding[] missingElements,
6826
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
6999
		int[] missingElementsStarts,
6827
		if(this.assistNodeIsEnum &&
7000
		int[] missingElementsEnds,
6828
				proposalType != null &&
7001
		boolean missingElementsHaveProblems,
6829
				this.expectedTypes != null) {
7002
		char[] castedReceiver,
6830
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
7003
		int receiverStart,
6831
				if (proposalType.isEnum() &&
7004
		int receiverEnd) {
6832
						proposalType == this.expectedTypes[i]) {
6833
					return R_ENUM + R_ENUM_CONSTANT;
6834
				}
6835
7005
6836
			}
7006
		ObjectVector newMethodsFound =  new ObjectVector();
6837
		}
7007
		// Inherited methods which are hidden by subclasses are filtered out
6838
		return 0;
7008
		// No visibility checks can be performed without the scope & invocationSite
6839
	}
6840
	private int computeRelevanceForException(){
6841
		if (this.assistNodeIsException) {
6842
			return R_EXCEPTION;
6843
		}
6844
		return 0;
6845
	}
6846
	private int computeRelevanceForException(char[] proposalName){
6847
7009
6848
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
7010
		int methodLength = methodName.length;
6849
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
7011
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
6850
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
7012
		int minArgLength = argTypes == null ? 0 : argTypes.length;
6851
			return R_EXCEPTION;
6852
		}
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
7013
6862
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
7014
		next : for (int f = methods.length; --f >= 0;) {
6863
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
7015
			MethodBinding method = methods[f];
6864
						return R_EXACT_EXPECTED_TYPE;
6865
					}
6866
7016
6867
					relevance = R_EXPECTED_TYPE;
7017
			if (method.isSynthetic()) continue next;
6868
				}
6869
				if((this.expectedTypesFilter & SUPERTYPE) != 0
6870
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
6871
7018
6872
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
7019
			if (method.isDefaultAbstract())	continue next;
6873
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
6874
						return R_EXACT_EXPECTED_TYPE;
6875
					}
6876
7020
6877
					relevance = R_EXPECTED_TYPE;
7021
			if (method.isConstructor()) continue next;
6878
				}
7022
7023
			if (this.options.checkDeprecation &&
7024
					method.isViewedAsDeprecated() &&
7025
					!scope.isDefinedInSameUnit(method.declaringClass))
7026
				continue next;
7027
7028
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
7029
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
7030
7031
			if (onlyStaticMethods && !method.isStatic()) continue next;
7032
7033
			if (this.options.checkVisibility
7034
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7035
7036
			if(superCall && method.isAbstract()) {
7037
				methodsFound.add(new Object[]{method, receiverType});
7038
				continue next;
6879
			}
7039
			}
6880
			return relevance;
7040
6881
		}
7041
			if (exactMatch) {
6882
		return 0;
7042
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
6883
	}
7043
					continue next;
6884
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
7044
				}
6885
		if(this.expectedTypes != null) {
7045
			} else {
6886
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
7046
				if (methodLength > method.selector.length) continue next;
6887
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
7047
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6888
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
7048
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6889
					return R_EXACT_EXPECTED_TYPE;
7049
					continue next;
6890
				}
7050
				}
6891
			}
7051
			}
6892
			if(this.hasJavaLangObjectAsExpectedType) {
7052
6893
				return R_EXPECTED_TYPE;
7053
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
7054
				continue next;
7055
7056
			if (minTypeArgLength != 0) {
7057
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
6894
			}
7058
			}
6895
		}
6896
		return 0;
6897
	}
6898
7059
6899
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
7060
			if (minArgLength > method.parameters.length)
6900
		if (receiverType == declaringClass) return R_NON_INHERITED;
7061
				continue next;
6901
		return 0;
6902
	}
6903
7062
6904
	int computeRelevanceForInterestingProposal(){
7063
			for (int a = minArgLength; --a >= 0;){
6905
		return computeRelevanceForInterestingProposal(null);
7064
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
6906
	}
7065
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
6907
	private int computeRelevanceForInterestingProposal(Binding binding){
7066
						continue next;
6908
		if(this.uninterestingBindings != null) {
6909
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
6910
				if(this.uninterestingBindings[i] == binding) {
6911
					return 0;
6912
				}
6913
			}
6914
		}
6915
		return R_INTERESTING;
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
6925
	private void findLabels(char[] label, char[][] choices) {
6926
		if(choices == null || choices.length == 0) return;
6927
6928
		int length = label.length;
6929
		for (int i = 0; i < choices.length; i++) {
6930
			if (length <= choices[i].length
6931
				&& CharOperation.prefixEquals(label, choices[i], false /* ignore case */
6932
			)){
6933
				int relevance = computeBaseRelevance();
6934
				relevance += computeRelevanceForResolution();
6935
				relevance += computeRelevanceForInterestingProposal();
6936
				relevance += computeRelevanceForCaseMatching(label, choices[i]);
6937
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6938
6939
				this.noProposal = false;
6940
				if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
6941
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
6942
					proposal.setName(choices[i]);
6943
					proposal.setCompletion(choices[i]);
6944
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6945
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6946
					proposal.setRelevance(relevance);
6947
					this.requestor.accept(proposal);
6948
					if(DEBUG) {
6949
						this.printDebug(proposal);
6950
					}
7067
					}
6951
				}
7068
				}
6952
			}
7069
			}
6953
		}
6954
	}
6955
6956
	// Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
6957
	private void findLocalMethodDeclarations(
6958
		char[] methodName,
6959
		MethodBinding[] methods,
6960
		Scope scope,
6961
		ObjectVector methodsFound,
6962
		//	boolean noVoidReturnType, how do you know?
6963
		boolean exactMatch,
6964
		ReferenceBinding receiverType) {
6965
6966
		ObjectVector newMethodsFound =  new ObjectVector();
6967
		// Inherited methods which are hidden by subclasses are filtered out
6968
		// No visibility checks can be performed without the scope & invocationSite
6969
		int methodLength = methodName.length;
6970
		next : for (int f = methods.length; --f >= 0;) {
6971
6972
			MethodBinding method = methods[f];
6973
			if (method.isSynthetic())	continue next;
6974
6975
			if (method.isDefaultAbstract()) continue next;
6976
6977
			if (method.isConstructor()) continue next;
6978
6979
			if (method.isFinal()) {
6980
                newMethodsFound.add(method);
6981
                continue next;
6982
            }
6983
6984
			if (this.options.checkDeprecation &&
6985
					method.isViewedAsDeprecated() &&
6986
					!scope.isDefinedInSameUnit(method.declaringClass))
6987
				continue next;
6988
6989
			//		if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
6990
			if(method.isStatic()) continue next;
6991
7070
6992
			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
7071
			boolean prefixRequired = false;
6993
7072
6994
			if (exactMatch) {
7073
			for (int i = methodsFound.size; --i >= 0;) {
6995
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
7074
				Object[] other = (Object[]) methodsFound.elementAt(i);
6996
					))
7075
				MethodBinding otherMethod = (MethodBinding) other[0];
7076
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
7077
				if (method == otherMethod && receiverType == otherReceiverType)
6997
					continue next;
7078
					continue next;
6998
7079
6999
			} else {
7080
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7081
					if (receiverType == otherReceiverType) {
7082
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7083
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
7084
								continue next;
7085
							}
7086
						}
7087
					} else {
7088
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7089
							if(receiverType.isAnonymousType()) continue next;
7000
7090
7001
				if (methodLength > method.selector.length)
7091
							if(!superCall) {
7002
					continue next;
7092
								if(!canBePrefixed) continue next;
7003
7093
7004
				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
7094
								prefixRequired = true;
7005
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
7095
							}
7006
					continue next;
7096
						}
7097
					}
7098
				}
7007
			}
7099
			}
7008
7100
7009
			for (int i = methodsFound.size; --i >= 0;) {
7101
			newMethodsFound.add(new Object[]{method, receiverType});
7010
				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
7011
				if (method == otherMethod)
7012
					continue next;
7013
7102
7014
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
7103
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7015
						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7104
			if (method.declaringClass != superTypeWithSameErasure) {
7016
					continue next;
7105
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7106
				for (int i = 0; i < otherMethods.length; i++) {
7107
					if(otherMethods[i].original() == method.original()) {
7108
						method = otherMethods[i];
7109
					}
7017
				}
7110
				}
7018
			}
7111
			}
7019
7112
7020
			newMethodsFound.add(method);
7021
7022
			int length = method.parameters.length;
7113
			int length = method.parameters.length;
7023
			char[][] parameterPackageNames = new char[length][];
7114
			char[][] parameterPackageNames = new char[length][];
7024
			char[][] parameterFullTypeNames = new char[length][];
7115
			char[][] parameterTypeNames = new char[length][];
7025
7116
7026
			for (int i = 0; i < length; i++) {
7117
			for (int i = 0; i < length; i++) {
7027
				TypeBinding type = method.parameters[i];
7118
				TypeBinding type = method.original().parameters[i];
7028
				parameterPackageNames[i] = type.qualifiedPackageName();
7119
				parameterPackageNames[i] = type.qualifiedPackageName();
7029
				parameterFullTypeNames[i] = type.qualifiedSourceName();
7120
				parameterTypeNames[i] = type.qualifiedSourceName();
7030
			}
7121
			}
7122
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7031
7123
7032
			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
7124
			char[] completion = CharOperation.NO_CHAR;
7033
7125
7034
			if(method.typeVariables != null && method.typeVariables.length > 0) {
7126
			int previousStartPosition = this.startPosition;
7035
				char[][] excludedNames = findEnclosingTypeNames(scope);
7127
			int previousTokenStart = this.tokenStart;
7036
				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
7128
7037
				if(substituedParameterNames != null) {
7129
			// Special case for completion in javadoc
7038
					method = new ParameterizedMethodBinding(
7130
			if (this.assistNodeInJavadoc > 0) {
7039
								method.declaringClass,
7131
				Expression receiver = null;
7040
								method,
7132
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
7041
								substituedParameterNames,
7133
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
7042
								scope.environment());
7134
					receiver = msg.receiver;
7135
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
7136
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
7137
					receiver = fieldRef.receiver;
7043
				}
7138
				}
7044
			}
7139
				if (receiver != null) {
7140
					StringBuffer javadocCompletion = new StringBuffer();
7141
					if (receiver.isThis()) {
7142
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7143
							javadocCompletion.append('#');
7144
						}
7145
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7146
						if (receiver instanceof JavadocSingleTypeReference) {
7147
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
7148
							javadocCompletion.append(typeRef.token);
7149
							javadocCompletion.append('#');
7150
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
7151
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
7152
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
7153
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
7154
								if (t>0) javadocCompletion.append('.');
7155
								javadocCompletion.append(typeRef.tokens[t]);
7156
							}
7157
							javadocCompletion.append('#');
7158
						}
7159
					}
7160
					javadocCompletion.append(method.selector);
7161
					// Append parameters types
7162
					javadocCompletion.append('(');
7163
					if (method.parameters != null) {
7164
						boolean isVarargs = method.isVarargs();
7165
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
7166
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
7167
							TypeBinding argTypeBinding = method.parameters[p];
7168
							if (isVarargs && p == ln - 1)  {
7169
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
7170
							} else {
7171
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
7172
							}
7173
						}
7174
					}
7175
					javadocCompletion.append(')');
7176
					completion = javadocCompletion.toString().toCharArray();
7177
				}
7178
			} else {
7179
				// nothing to insert - do not want to replace the existing selector & arguments
7180
				if (!exactMatch) {
7181
					if (this.source != null
7182
						&& this.source.length > this.endPosition
7183
						&& this.source[this.endPosition] == '(')
7184
						completion = method.selector;
7185
					else
7186
						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7045
7187
7046
			StringBuffer completion = new StringBuffer(10);
7188
					if (castedReceiver != null) {
7047
			if (!exactMatch) {
7189
						completion = CharOperation.concat(castedReceiver, completion);
7048
				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
7190
					}
7191
				} else {
7192
					if(prefixRequired && (this.source != null)) {
7193
						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
7194
					} else {
7195
						this.startPosition = this.endPosition;
7196
					}
7197
					this.tokenStart = this.tokenEnd;
7198
				}
7199
7200
				if(prefixRequired || this.options.forceImplicitQualification){
7201
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
7202
					completion = CharOperation.concat(prefix,completion,'.');
7203
				}
7049
			}
7204
			}
7050
7205
7051
			int relevance = computeBaseRelevance();
7206
			int relevance = computeBaseRelevance();
7052
			relevance += computeRelevanceForResolution();
7207
			relevance += computeRelevanceForResolution();
7053
			relevance += computeRelevanceForInterestingProposal();
7208
			relevance += computeRelevanceForInterestingProposal();
7054
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7209
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7055
			relevance += R_METHOD_OVERIDE;
7210
			relevance += computeRelevanceForExpectingType(method.returnType);
7056
			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
7211
			relevance += computeRelevanceForEnumConstant(method.returnType);
7212
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
7213
			relevance += computeRelevanceForQualification(prefixRequired);
7057
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7214
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7215
			if (onlyStaticMethods && this.insideQualifiedReference) {
7216
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
7217
			}
7218
			if (missingElements != null) {
7219
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
7220
			}
7058
7221
7059
			this.noProposal = false;
7222
			this.noProposal = false;
7060
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
7223
7061
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
7224
			if (castedReceiver == null) {
7062
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
7225
				// Standard proposal
7063
				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
7226
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
7064
				proposal.setSignature(getSignature(method));
7227
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7065
				MethodBinding original = method.original();
7228
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7066
				if(original != method) {
7229
					proposal.setSignature(getSignature(method));
7067
					proposal.setOriginalSignature(getSignature(original));
7230
					MethodBinding original = method.original();
7231
					if(original != method) {
7232
						proposal.setOriginalSignature(getSignature(original));
7233
					}
7234
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7235
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7236
					proposal.setParameterPackageNames(parameterPackageNames);
7237
					proposal.setParameterTypeNames(parameterTypeNames);
7238
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7239
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7240
					proposal.setName(method.selector);
7241
					if (missingElements != null) {
7242
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7243
						for (int i = 0; i < missingElements.length; i++) {
7244
							subProposals[i] =
7245
								createRequiredTypeProposal(
7246
										missingElements[i],
7247
										missingElementsStarts[i],
7248
										missingElementsEnds[i],
7249
										relevance);
7250
						}
7251
						proposal.setRequiredProposals(subProposals);
7252
					}
7253
					proposal.setCompletion(completion);
7254
					proposal.setFlags(method.modifiers);
7255
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7256
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7257
					proposal.setRelevance(relevance);
7258
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7259
					this.requestor.accept(proposal);
7260
					if(DEBUG) {
7261
						this.printDebug(proposal);
7262
					}
7068
				}
7263
				}
7069
				proposal.setKey(method.computeUniqueKey());
7264
7070
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7265
				// Javadoc proposal
7071
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7266
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
7072
				proposal.setParameterPackageNames(parameterPackageNames);
7267
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
7073
				proposal.setParameterTypeNames(parameterFullTypeNames);
7268
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
7074
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7269
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7075
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7270
					proposal.setSignature(getSignature(method));
7076
				proposal.setCompletion(completion.toString().toCharArray());
7271
					MethodBinding original = method.original();
7077
				proposal.setName(method.selector);
7272
					if(original != method) {
7078
				proposal.setFlags(method.modifiers);
7273
						proposal.setOriginalSignature(getSignature(original));
7079
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7274
					}
7080
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7275
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7081
				proposal.setRelevance(relevance);
7276
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7082
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7277
					proposal.setParameterPackageNames(parameterPackageNames);
7083
				this.requestor.accept(proposal);
7278
					proposal.setParameterTypeNames(parameterTypeNames);
7084
				if(DEBUG) {
7279
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7085
					this.printDebug(proposal);
7280
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7281
					proposal.setName(method.selector);
7282
					proposal.setCompletion(javadocCompletion);
7283
					proposal.setFlags(method.modifiers);
7284
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
7285
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
7286
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7287
					proposal.setRelevance(relevance+R_INLINE_TAG);
7288
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7289
					this.requestor.accept(proposal);
7290
					if(DEBUG) {
7291
						this.printDebug(proposal);
7292
					}
7293
				}
7294
			} else {
7295
				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
7296
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
7297
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7298
					proposal.setSignature(getSignature(method));
7299
					MethodBinding original = method.original();
7300
					if(original != method) {
7301
						proposal.setOriginalSignature(getSignature(original));
7302
					}
7303
					proposal.setReceiverSignature(getSignature(receiverType));
7304
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7305
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7306
					proposal.setParameterPackageNames(parameterPackageNames);
7307
					proposal.setParameterTypeNames(parameterTypeNames);
7308
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7309
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7310
					proposal.setName(method.selector);
7311
					if (missingElements != null) {
7312
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7313
						for (int i = 0; i < missingElements.length; i++) {
7314
							subProposals[i] =
7315
								createRequiredTypeProposal(
7316
										missingElements[i],
7317
										missingElementsStarts[i],
7318
										missingElementsEnds[i],
7319
										relevance);
7320
						}
7321
						proposal.setRequiredProposals(subProposals);
7322
					}
7323
					proposal.setCompletion(completion);
7324
					proposal.setFlags(method.modifiers);
7325
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7326
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
7327
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7328
					proposal.setRelevance(relevance);
7329
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7330
					this.requestor.accept(proposal);
7331
					if(DEBUG) {
7332
						this.printDebug(proposal);
7333
					}
7086
				}
7334
				}
7087
			}
7335
			}
7336
			this.startPosition = previousStartPosition;
7337
			this.tokenStart = previousTokenStart;
7088
		}
7338
		}
7339
7089
		methodsFound.addAll(newMethodsFound);
7340
		methodsFound.addAll(newMethodsFound);
7090
	}
7341
	}
7342
	private void findLocalMethodsFromFavorites(
7343
			char[] methodName,
7344
			MethodBinding[] methods,
7345
			Scope scope,
7346
			ObjectVector methodsFound,
7347
			ObjectVector methodsFoundFromFavorites,
7348
			ReferenceBinding receiverType,
7349
			InvocationSite invocationSite,
7350
			Scope invocationScope) {
7091
7351
7092
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
7352
			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
7093
		completion.append(typeVariable.sourceName);
7094
7353
7095
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
7354
			int methodLength = methodName.length;
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
7355
7118
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
7356
			next : for (int f = methods.length; --f >= 0;) {
7119
		switch (type.kind()) {
7357
				MethodBinding method = methods[f];
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
7358
7135
							int length = wildcardBinding.otherBounds.length;
7359
				if (method.isSynthetic()) continue next;
7136
							for (int i = 0; i < length; i++) {
7360
7137
								completion.append(' ');
7361
				if (method.isDefaultAbstract())	continue next;
7138
								completion.append('&');
7362
7139
								completion.append(' ');
7363
				if (method.isConstructor()) continue next;
7140
								createType(wildcardBinding.otherBounds[i], scope, completion);
7364
7141
							}
7365
				if (this.options.checkDeprecation &&
7366
						method.isViewedAsDeprecated() &&
7367
						!scope.isDefinedInSameUnit(method.declaringClass))
7368
					continue next;
7369
7370
				if (!method.isStatic()) continue next;
7371
7372
				if (this.options.checkVisibility
7373
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7374
7375
				if (methodLength > method.selector.length) continue next;
7376
7377
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
7378
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
7379
					continue next;
7380
				}
7381
7382
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
7383
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
7384
					MethodBinding otherMethod = (MethodBinding) other[0];
7385
7386
					if (method == otherMethod) continue next;
7387
7388
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7389
						if (otherMethod.declaringClass == method.declaringClass &&
7390
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7391
							continue next;
7142
						}
7392
						}
7143
						break;
7393
					}
7144
					case Wildcard.SUPER:
7145
						completion.append(' ');
7146
						completion.append(SUPER);
7147
						completion.append(' ');
7148
						createType(wildcardBinding.bound, scope, completion);
7149
						break;
7150
				}
7394
				}
7151
				break;
7395
7152
			case Binding.ARRAY_TYPE :
7396
				for (int i = methodsFound.size; --i >= 0;) {
7153
				createType(type.leafComponentType(), scope, completion);
7397
					Object[] other = (Object[]) methodsFound.elementAt(i);
7154
				int dim = type.dimensions();
7398
					MethodBinding otherMethod = (MethodBinding) other[0];
7155
				for (int i = 0; i < dim; i++) {
7399
7156
					completion.append('[');
7400
					if (method == otherMethod) continue next;
7157
					completion.append(']');
7401
7402
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7403
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7404
							continue next;
7405
						}
7406
					}
7158
				}
7407
				}
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
7408
7225
		//// Type parameters
7409
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
7410
					this.options.suggestStaticImport;
7226
7411
7227
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
7412
				boolean isAlreadyImported = false;
7228
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
7413
				if (!proposeStaticImport) {
7229
			completion.append('<');
7414
					if(!this.importCachesInitialized) {
7230
			for (int i = 0; i < typeVariableBindings.length; i++) {
7415
						initializeImportCaches();
7231
				if(i != 0) {
7416
					}
7232
					completion.append(',');
7417
					for (int j = 0; j < this.importCacheCount; j++) {
7233
					completion.append(' ');
7418
						char[][] importName = this.importsCache[j];
7419
						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
7420
							if (!CharOperation.equals(typeName, importName[1])) {
7421
								continue next;
7422
							} else {
7423
								isAlreadyImported = true;
7424
							}
7425
						}
7426
					}
7234
				}
7427
				}
7235
				createTypeVariable(typeVariableBindings[i], scope, completion);
7236
			}
7237
			completion.append('>');
7238
			completion.append(' ');
7239
		}
7240
7428
7241
		//// Return type
7429
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
7242
		createType(method.returnType, scope, completion);
7243
		completion.append(' ');
7244
7430
7245
		//// Selector
7431
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7246
		completion.append(method.selector);
7432
				if (method.declaringClass != superTypeWithSameErasure) {
7433
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7434
					for (int i = 0; i < otherMethods.length; i++) {
7435
						if(otherMethods[i].original() == method.original()) {
7436
							method = otherMethods[i];
7437
						}
7438
					}
7439
				}
7247
7440
7248
		completion.append('(');
7441
				int length = method.parameters.length;
7442
				char[][] parameterPackageNames = new char[length][];
7443
				char[][] parameterTypeNames = new char[length][];
7249
7444
7250
		////Parameters
7445
				for (int i = 0; i < length; i++) {
7251
		TypeBinding[] parameterTypes = method.parameters;
7446
					TypeBinding type = method.original().parameters[i];
7252
		int length = parameterTypes.length;
7447
					parameterPackageNames[i] = type.qualifiedPackageName();
7253
		for (int i = 0; i < length; i++) {
7448
					parameterTypeNames[i] = type.qualifiedSourceName();
7254
			if(i != 0) {
7449
				}
7255
				completion.append(',');
7450
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
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
7451
7267
		completion.append(')');
7452
				char[] completion = CharOperation.NO_CHAR;
7268
7453
7269
		//// Exceptions
7454
				int previousStartPosition = this.startPosition;
7270
		ReferenceBinding[] exceptions = method.thrownExceptions;
7455
				int previousTokenStart = this.tokenStart;
7271
7456
7272
		if (exceptions != null && exceptions.length > 0){
7457
				if (this.source != null
7273
			completion.append(' ');
7458
					&& this.source.length > this.endPosition
7274
			completion.append(THROWS);
7459
					&& this.source[this.endPosition] == '(') {
7275
			completion.append(' ');
7460
					completion = method.selector;
7276
			for(int i = 0; i < exceptions.length ; i++){
7461
				} else {
7277
				if(i != 0) {
7462
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7278
					completion.append(' ');
7279
					completion.append(',');
7280
				}
7463
				}
7281
				createType(exceptions[i], scope, completion);
7282
			}
7283
		}
7284
	}
7285
7464
7286
	private boolean isIgnored(int kind, boolean missingTypes) {
7465
				int relevance = computeBaseRelevance();
7287
		return this.requestor.isIgnored(kind) ||
7466
				relevance += computeRelevanceForResolution();
7288
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
7467
				relevance += computeRelevanceForInterestingProposal();
7289
	}
7468
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7469
				relevance += computeRelevanceForExpectingType(method.returnType);
7470
				relevance += computeRelevanceForEnumConstant(method.returnType);
7471
				relevance += computeRelevanceForStatic(true, method.isStatic());
7472
				relevance += computeRelevanceForQualification(true);
7473
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7290
7474
7291
	private boolean isIgnored(int kind) {
7475
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
7292
		return this.requestor.isIgnored(kind);
7476
				int importStart = cu.types[0].declarationSourceStart;
7293
	}
7477
				int importEnd = importStart;
7294
7478
7295
	private boolean isIgnored(int kind, int requiredProposalKind) {
7479
				this.noProposal = false;
7296
		return this.requestor.isIgnored(kind) ||
7297
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
7298
	}
7299
7480
7300
	private void findMethods(
7481
				if (!proposeStaticImport) {
7301
		char[] selector,
7482
					if (isAlreadyImported) {
7302
		TypeBinding[] typeArgTypes,
7483
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
7303
		TypeBinding[] argTypes,
7484
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
7304
		ReferenceBinding receiverType,
7305
		Scope scope,
7306
		ObjectVector methodsFound,
7307
		boolean onlyStaticMethods,
7308
		boolean exactMatch,
7309
		boolean isCompletingDeclaration,
7310
		InvocationSite invocationSite,
7311
		Scope invocationScope,
7312
		boolean implicitCall,
7313
		boolean superCall,
7314
		boolean canBePrefixed,
7315
		Binding[] missingElements,
7316
		int[] missingElementsStarts,
7317
		int[] missingElementsEnds,
7318
		boolean missingElementsHaveProblems,
7319
		char[] castedReceiver,
7320
		int receiverStart,
7321
		int receiverEnd) {
7322
7485
7323
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
7486
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7324
		if (selector == null && notInJavadoc) {
7487
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
7325
			return;
7488
							proposal.setSignature(getSignature(method));
7326
		}
7489
							MethodBinding original = method.original();
7490
							if(original != method) {
7491
								proposal.setOriginalSignature(getSignature(original));
7492
							}
7493
							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7494
							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7495
							proposal.setParameterPackageNames(parameterPackageNames);
7496
							proposal.setParameterTypeNames(parameterTypeNames);
7497
							proposal.setPackageName(method.returnType.qualifiedPackageName());
7498
							proposal.setTypeName(method.returnType.qualifiedSourceName());
7499
							proposal.setName(method.selector);
7500
							proposal.setCompletion(completion);
7501
							proposal.setFlags(method.modifiers);
7502
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7503
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7504
							proposal.setRelevance(relevance);
7505
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
7327
7506
7328
		if(isCompletingDeclaration) {
7507
							this.requestor.accept(proposal);
7329
			MethodBinding[] methods = receiverType.availableMethods();
7508
							if(DEBUG) {
7330
			if (methods != null){
7509
								this.printDebug(proposal);
7331
				for (int i = 0; i < methods.length; i++) {
7510
							}
7332
					if(!methods[i].isDefaultAbstract()) {
7511
						}
7333
						methodsFound.add(methods[i]);
7512
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
7334
					}
7513
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
7335
				}
7336
			}
7337
		}
7338
7514
7339
		ReferenceBinding currentType = receiverType;
7515
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7340
		if (notInJavadoc) {
7516
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7341
			if (receiverType.isInterface()) {
7517
						proposal.setSignature(getSignature(method));
7342
				if (isCompletingDeclaration) {
7518
						MethodBinding original = method.original();
7343
					findInterfacesMethods(
7519
						if(original != method) {
7344
						selector,
7520
							proposal.setOriginalSignature(getSignature(original));
7345
						typeArgTypes,
7521
						}
7346
						argTypes,
7522
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7347
						receiverType,
7523
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7348
						currentType.superInterfaces(),
7524
						proposal.setParameterPackageNames(parameterPackageNames);
7349
						scope,
7525
						proposal.setParameterTypeNames(parameterTypeNames);
7350
						methodsFound,
7526
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7351
						onlyStaticMethods,
7527
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7352
						exactMatch,
7528
						proposal.setName(method.selector);
7353
						isCompletingDeclaration,
7529
						proposal.setCompletion(completion);
7354
						invocationSite,
7530
						proposal.setFlags(method.modifiers);
7355
						invocationScope,
7531
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7356
						implicitCall,
7532
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7357
						superCall,
7533
						proposal.setRelevance(relevance);
7358
						canBePrefixed,
7534
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
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
				}
7391
7392
				currentType = scope.getJavaLangObject();
7393
			} else {
7394
				if (isCompletingDeclaration){
7395
					findInterfacesMethods(
7396
						selector,
7397
						typeArgTypes,
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
7535
7419
					currentType = receiverType.superclass();
7536
						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
7420
				}
7421
			}
7422
		}
7423
		boolean hasPotentialDefaultAbstractMethods = true;
7424
		while (currentType != null) {
7425
7537
7426
			MethodBinding[] methods = currentType.availableMethods();
7538
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
7427
			if (methods != null) {
7539
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
7428
				if (isCompletingDeclaration){
7540
						typeImportProposal.completionEngine = this;
7429
					findLocalMethodDeclarations(
7541
						char[] packageName = receiverType.qualifiedPackageName();
7430
						selector,
7542
						typeImportProposal.setDeclarationSignature(packageName);
7431
						methods,
7543
						typeImportProposal.setSignature(getSignature(receiverType));
7432
						scope,
7544
						typeImportProposal.setPackageName(packageName);
7433
						methodsFound,
7545
						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
7434
						exactMatch,
7546
						typeImportProposal.setCompletion(typeImportCompletion);
7435
						receiverType);
7547
						typeImportProposal.setFlags(receiverType.modifiers);
7436
				} else{
7548
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
7437
					findLocalMethods(
7549
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7438
						selector,
7550
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7439
						typeArgTypes,
7551
						typeImportProposal.setRelevance(relevance);
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
			}
7461
7552
7462
			if (hasPotentialDefaultAbstractMethods &&
7553
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
7463
					(currentType.isAbstract() ||
7464
							currentType.isTypeVariable() ||
7465
							currentType.isIntersectionType() ||
7466
							currentType.isEnum())){
7467
7554
7468
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
7555
						this.requestor.accept(proposal);
7469
				if (superInterfaces != null && currentType.isIntersectionType()) {
7556
						if(DEBUG) {
7470
					for (int i = 0; i < superInterfaces.length; i++) {
7557
							this.printDebug(proposal);
7471
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
7558
						}
7472
					}
7559
					}
7473
				}
7560
				} else {
7474
7561
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
7475
				findInterfacesMethods(
7562
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7476
					selector,
7563
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7477
					typeArgTypes,
7564
						proposal.setSignature(getSignature(method));
7478
					argTypes,
7565
						MethodBinding original = method.original();
7479
					receiverType,
7566
						if(original != method) {
7480
					superInterfaces,
7567
							proposal.setOriginalSignature(getSignature(original));
7481
					scope,
7568
						}
7482
					methodsFound,
7569
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7483
					onlyStaticMethods,
7570
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7484
					exactMatch,
7571
						proposal.setParameterPackageNames(parameterPackageNames);
7485
					isCompletingDeclaration,
7572
						proposal.setParameterTypeNames(parameterTypeNames);
7486
					invocationSite,
7573
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7487
					invocationScope,
7574
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7488
					implicitCall,
7575
						proposal.setName(method.selector);
7489
					superCall,
7576
						proposal.setCompletion(completion);
7490
					canBePrefixed,
7577
						proposal.setFlags(method.modifiers);
7491
					missingElements,
7578
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7492
					missingElementsStarts,
7579
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7493
					missingElementsEnds,
7580
						proposal.setRelevance(relevance);
7494
					missingElementsHaveProblems,
7581
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
7495
					castedReceiver,
7496
					receiverStart,
7497
					receiverEnd);
7498
			} else {
7499
				hasPotentialDefaultAbstractMethods = false;
7500
			}
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
7508
		char[][] parameterNames = null;
7509
7510
		int length = parameterTypeNames.length;
7511
7512
		if (length == 0){
7513
			return CharOperation.NO_CHAR_CHAR;
7514
		}
7515
		// look into the corresponding unit if it is available
7516
		if (erasure instanceof SourceTypeBinding){
7517
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
7518
7582
7519
			if (sourceType.scope != null){
7583
						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
7520
				TypeDeclaration parsedType;
7521
7584
7522
				if ((parsedType = sourceType.scope.referenceContext) != null){
7585
						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
7523
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
7586
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
7587
						methodImportProposal.setSignature(getSignature(method));
7588
						if(original != method) {
7589
							proposal.setOriginalSignature(getSignature(original));
7590
						}
7591
						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7592
						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7593
						methodImportProposal.setParameterPackageNames(parameterPackageNames);
7594
						methodImportProposal.setParameterTypeNames(parameterTypeNames);
7595
						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
7596
						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
7597
						methodImportProposal.setName(method.selector);
7598
						methodImportProposal.setCompletion(methodImportCompletion);
7599
						methodImportProposal.setFlags(method.modifiers);
7600
						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
7601
						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7602
						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7603
						methodImportProposal.setRelevance(relevance);
7604
						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
7524
7605
7525
					if (methodDecl != null){
7606
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
7526
						Argument[] arguments = methodDecl.arguments;
7527
						parameterNames = new char[length][];
7528
7607
7529
						for(int i = 0 ; i < length ; i++){
7608
						this.requestor.accept(proposal);
7530
							parameterNames[i] = arguments[i].name;
7609
						if(DEBUG) {
7610
							this.printDebug(proposal);
7531
						}
7611
						}
7532
					}
7612
					}
7533
				}
7613
				}
7614
7615
				this.startPosition = previousStartPosition;
7616
				this.tokenStart = previousTokenStart;
7534
			}
7617
			}
7535
		}
7618
		}
7536
		// look into the model
7537
		if(parameterNames == null){
7538
7619
7539
			ReferenceBinding bindingType = (ReferenceBinding)erasure;
7620
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
7621
	private void findLocalMethodsFromStaticImports(
7622
		char[] methodName,
7623
		MethodBinding[] methods,
7624
		Scope scope,
7625
		boolean exactMatch,
7626
		ObjectVector methodsFound,
7627
		ReferenceBinding receiverType,
7628
		InvocationSite invocationSite) {
7540
7629
7541
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
7630
		ObjectVector newMethodsFound =  new ObjectVector();
7542
			Object type = this.typeCache.get(compoundName);
7543
7631
7544
			ISourceType sourceType = null;
7632
		next : for (int f = methods.length; --f >= 0;) {
7545
			if(type != null) {
7633
			MethodBinding method = methods[f];
7546
				if(type instanceof ISourceType) {
7547
					sourceType = (ISourceType) type;
7548
				}
7549
			} else {
7550
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
7551
				if(answer != null && answer.isSourceType()) {
7552
					sourceType = answer.getSourceTypes()[0];
7553
					this.typeCache.put(compoundName, sourceType);
7554
				}
7555
			}
7556
7557
			if(sourceType != null) {
7558
				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
7559
7560
				String[] parameterTypeSignatures = new String[length];
7561
				for (int i = 0; i < length; i++) {
7562
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
7563
				}
7564
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
7565
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
7566
7567
				if(foundMethods != null) {
7568
					int len = foundMethods.length;
7569
					if(len == 1) {
7570
						try {
7571
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
7572
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
7573
						} catch (JavaModelException e) {
7574
							// method doesn't exist: ignore
7575
						}
7576
					}
7577
				}
7578
			}
7579
		}
7580
		return parameterNames;
7581
	}
7582
7583
	private void findNestedTypes(
7584
		char[] typeName,
7585
		SourceTypeBinding currentType,
7586
		Scope scope,
7587
		boolean proposeAllMemberTypes,
7588
		ObjectVector typesFound) {
7589
		if (typeName == null)
7590
			return;
7591
7592
		int typeLength = typeName.length;
7593
7594
		SourceTypeBinding nextTypeToIgnore = null;
7595
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
7596
7597
			switch (scope.kind) {
7598
7599
				case Scope.METHOD_SCOPE :
7600
				case Scope.BLOCK_SCOPE :
7601
					BlockScope blockScope = (BlockScope) scope;
7602
7634
7603
					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
7635
			if (method.isSynthetic()) continue next;
7604
7636
7605
						if (blockScope.subscopes[i] instanceof ClassScope) {
7637
			if (method.isDefaultAbstract())	continue next;
7606
							SourceTypeBinding localType =
7607
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
7608
7638
7609
							if (!localType.isAnonymousType()) {
7639
			if (method.isConstructor()) continue next;
7610
								if (isForbidden(localType))
7611
									continue next;
7612
7640
7613
								if (typeLength > localType.sourceName.length)
7641
			if (!method.isStatic()) continue next;
7614
									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
7642
7619
								for (int j = typesFound.size; --j >= 0;) {
7643
			if (this.options.checkDeprecation &&
7620
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
7644
					method.isViewedAsDeprecated() &&
7645
					!scope.isDefinedInSameUnit(method.declaringClass))
7646
				continue next;
7621
7647
7622
									if (localType == otherType)
7648
			if (this.options.checkVisibility
7623
										continue next;
7649
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7624
								}
7625
7650
7626
								if(this.assistNodeIsClass) {
7651
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
7627
									if(!localType.isClass()) continue next;
7652
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
7628
								} else if(this.assistNodeIsInterface) {
7653
				continue next;
7629
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
7630
								} else if (this.assistNodeIsAnnotation) {
7631
									if(!localType.isAnnotationType()) continue next;
7632
								}
7633
7654
7634
								int relevance = computeBaseRelevance();
7655
			for (int i = methodsFound.size; --i >= 0;) {
7635
								relevance += computeRelevanceForResolution();
7656
				Object[] other = (Object[]) methodsFound.elementAt(i);
7636
								relevance += computeRelevanceForInterestingProposal();
7657
				MethodBinding otherMethod = (MethodBinding) other[0];
7637
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
7658
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
7638
								relevance += computeRelevanceForExpectingType(localType);
7659
				if (method == otherMethod && receiverType == otherReceiverType)
7639
								relevance += computeRelevanceForException(localType.sourceName);
7660
					continue next;
7640
								relevance += computeRelevanceForClass();
7641
								relevance += computeRelevanceForQualification(false);
7642
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
7643
								relevance += computeRelevanceForAnnotationTarget(localType);
7644
7661
7645
								this.noProposal = false;
7662
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7646
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7663
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7647
									createTypeProposal(
7664
						continue next;
7648
											localType,
7649
											localType.sourceName,
7650
											IAccessRule.K_ACCESSIBLE,
7651
											localType.sourceName,
7652
											relevance,
7653
											null,
7654
											null,
7655
											null,
7656
											false);
7657
								}
7658
							}
7659
						}
7660
					}
7665
					}
7661
					break;
7666
				}
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
			}
7667
			}
7689
			scope = scope.parent;
7690
		}
7691
	}
7692
7668
7693
	private void findPackages(CompletionOnPackageReference packageStatement) {
7669
			newMethodsFound.add(new Object[]{method, receiverType});
7694
7670
7695
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
7671
			int length = method.parameters.length;
7696
		if (this.completionToken.length == 0)
7672
			char[][] parameterPackageNames = new char[length][];
7697
			return;
7673
			char[][] parameterTypeNames = new char[length][];
7698
7674
7699
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
7675
			for (int i = 0; i < length; i++) {
7700
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
7676
				TypeBinding type = method.original().parameters[i];
7701
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
7677
				parameterPackageNames[i] = type.qualifiedPackageName();
7702
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
7678
				parameterTypeNames[i] = type.qualifiedSourceName();
7703
	}
7679
			}
7680
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7704
7681
7705
	private void findParameterizedType(TypeReference ref, Scope scope) {
7682
			char[] completion = CharOperation.NO_CHAR;
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
7683
7713
			int accessibility = IAccessRule.K_ACCESSIBLE;
7684
			int previousStartPosition = this.startPosition;
7714
			if(refBinding.hasRestrictedAccess()) {
7685
			int previousTokenStart = this.tokenStart;
7715
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7686
7716
				if(accessRestriction != null) {
7687
			if (!exactMatch) {
7717
					switch (accessRestriction.getProblemId()) {
7688
				if (this.source != null
7718
						case IProblem.ForbiddenReference:
7689
					&& this.source.length > this.endPosition
7719
							if (this.options.checkForbiddenReference) {
7690
					&& this.source[this.endPosition] == '(') {
7720
								return;
7691
					completion = method.selector;
7721
							}
7692
				} else {
7722
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
7693
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7723
							break;
7724
						case IProblem.DiscouragedReference:
7725
							if (this.options.checkDiscouragedReference) {
7726
								return;
7727
							}
7728
							accessibility = IAccessRule.K_DISCOURAGED;
7729
							break;
7730
					}
7731
				}
7694
				}
7695
			} else {
7696
				this.startPosition = this.endPosition;
7697
				this.tokenStart = this.tokenEnd;
7732
			}
7698
			}
7733
7699
7734
			int relevance = computeBaseRelevance();
7700
			int relevance = computeBaseRelevance();
7735
			relevance += computeRelevanceForResolution();
7701
			relevance += computeRelevanceForResolution();
7736
			relevance += computeRelevanceForInterestingProposal();
7702
			relevance += computeRelevanceForInterestingProposal();
7737
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
7703
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7738
			relevance += computeRelevanceForExpectingType(refBinding);
7704
			relevance += computeRelevanceForExpectingType(method.returnType);
7705
			relevance += computeRelevanceForEnumConstant(method.returnType);
7706
			relevance += computeRelevanceForStatic(true, method.isStatic());
7739
			relevance += computeRelevanceForQualification(false);
7707
			relevance += computeRelevanceForQualification(false);
7740
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
7708
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
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
7709
7759
		TypeParameter[] typeParameters = null;
7710
			this.noProposal = false;
7760
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
7711
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7761
			typeParameters = null;
7712
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7762
			switch (scope.kind) {
7713
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
7763
				case Scope.METHOD_SCOPE :
7714
				proposal.setSignature(getSignature(method));
7764
					MethodScope methodScope = (MethodScope) scope;
7715
				MethodBinding original = method.original();
7765
					if(methodScope.referenceContext instanceof MethodDeclaration) {
7716
				if(original != method) {
7766
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
7717
					proposal.setOriginalSignature(getSignature(original));
7767
						typeParameters = methodDeclaration.typeParameters;
7718
				}
7768
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
7719
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7769
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
7720
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7770
						typeParameters = methodDeclaration.typeParameters;
7721
				proposal.setParameterPackageNames(parameterPackageNames);
7771
					}
7722
				proposal.setParameterTypeNames(parameterTypeNames);
7772
					break;
7723
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7773
				case Scope.CLASS_SCOPE :
7724
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7774
					ClassScope classScope = (ClassScope) scope;
7725
				proposal.setName(method.selector);
7775
					typeParameters = classScope.referenceContext.typeParameters;
7726
				proposal.setCompletion(completion);
7776
					break;
7727
				proposal.setFlags(method.modifiers);
7777
				case Scope.COMPILATION_UNIT_SCOPE :
7728
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7778
					return;
7729
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7779
			}
7730
				proposal.setRelevance(relevance);
7780
			if(typeParameters != null) {
7731
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7781
				for (int i = 0; i < typeParameters.length; i++) {
7732
				this.requestor.accept(proposal);
7782
					int typeLength = token.length;
7733
				if(DEBUG) {
7783
					TypeParameter typeParameter = typeParameters[i];
7734
					this.printDebug(proposal);
7784
7785
					if(typeParameter.binding == null) continue;
7786
7787
					if (typeLength > typeParameter.name.length) continue;
7788
7789
					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
7790
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
7791
7792
					int relevance = computeBaseRelevance();
7793
					relevance += computeRelevanceForResolution();
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
7801
					this.noProposal = false;
7802
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7803
						createTypeParameterProposal(typeParameter, relevance);
7804
					}
7805
				}
7735
				}
7806
			}
7736
			}
7807
			scope = scope.parent;
7737
			this.startPosition = previousStartPosition;
7738
			this.tokenStart = previousTokenStart;
7808
		}
7739
		}
7740
7741
		methodsFound.addAll(newMethodsFound);
7809
	}
7742
	}
7810
	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
7811
7743
7812
		if (token == null)
7744
	private void findLocalMethodsFromStaticImports(
7813
			return;
7745
			char[] token,
7746
			Scope scope,
7747
			InvocationSite invocationSite,
7748
			Scope invocationScope,
7749
			boolean exactMatch,
7750
			ObjectVector methodsFound,
7751
			boolean proposeMethod) {
7752
		findFieldsAndMethodsFromStaticImports(
7753
				token,
7754
				scope,
7755
				invocationSite,
7756
				invocationScope,
7757
				exactMatch,
7758
				false,
7759
				new ObjectVector(),
7760
				new ObjectVector(),
7761
				methodsFound,
7762
				false,
7763
				proposeMethod);
7764
	}
7765
	protected void findMembers(
7766
			char[] token,
7767
			ReferenceBinding receiverType,
7768
			Scope scope,
7769
			InvocationSite invocationSite,
7770
			boolean isInsideAnnotationAttribute,
7771
			Binding[] missingElements,
7772
			int[] missingElementsStarts,
7773
			int[] missingElementsEnds,
7774
			boolean missingElementsHaveProblems) {
7814
7775
7815
		// do not propose type if completion token is empty
7776
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7816
		boolean skip = false;
7777
			findMemberTypes(
7817
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
7778
					token,
7818
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
7779
					receiverType,
7819
				return;
7780
					scope,
7820
			}
7781
					scope.enclosingSourceType(),
7821
			skip = true;
7782
					false,
7783
					true,
7784
					new ObjectVector(),
7785
					missingElements,
7786
					missingElementsStarts,
7787
					missingElementsEnds,
7788
					missingElementsHaveProblems);
7822
		}
7789
		}
7823
7790
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
7824
		boolean proposeType =
7791
			findClassField(
7825
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
7792
					token,
7826
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
7793
					receiverType,
7827
7794
					scope,
7828
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
7795
					missingElements,
7829
7796
					missingElementsStarts,
7830
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
7797
					missingElementsEnds,
7831
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
7798
					missingElementsHaveProblems);
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
		}
7799
		}
7840
7800
7841
		boolean isEmptyPrefix = token.length == 0;
7801
		MethodScope methodScope = null;
7842
7802
		if (!isInsideAnnotationAttribute &&
7843
		if (!skip && proposeType && this.unitScope != null) {
7803
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
7844
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
7804
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
7845
			if(outerInvocationType != null) {
7805
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
7846
				ReferenceBinding temp = outerInvocationType.enclosingType();
7806
			if (token.length > 0) {
7847
				while(temp != null) {
7807
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
7848
					outerInvocationType = temp;
7808
			} else {
7849
					temp = temp.enclosingType();
7850
				}
7851
			}
7852
7853
			int typeLength = token.length;
7854
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
7855
7856
			next : for (int i = 0, length = types.length; i < length; i++) {
7857
				SourceTypeBinding sourceType = types[i];
7858
7859
				if(isForbidden(sourceType)) continue next;
7860
7861
				if(proposeAllMemberTypes &&
7862
					sourceType != outerInvocationType) {
7863
					findSubMemberTypes(
7864
							token,
7865
							sourceType,
7866
							scope,
7867
							scope.enclosingSourceType(),
7868
							false,
7869
							false,
7870
							false,
7871
							typesFound);
7872
				}
7873
7874
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
7875
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
7876
7877
				if (typeLength > sourceType.sourceName.length) continue next;
7878
7879
				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
7880
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
7881
7882
				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
7883
					continue next;
7884
				}
7885
7886
				for (int j = typesFound.size; --j >= 0;) {
7887
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
7888
7889
					if (sourceType == otherType) continue next;
7890
				}
7891
7892
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
7893
7894
				if(this.assistNodeIsClass) {
7895
					if(!sourceType.isClass()) continue next;
7896
				} else if(this.assistNodeIsInterface) {
7897
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
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
					}
7904
				}
7905
7906
				int relevance = computeBaseRelevance();
7809
				int relevance = computeBaseRelevance();
7907
				relevance += computeRelevanceForResolution();
7810
				relevance += computeRelevanceForResolution();
7908
				relevance += computeRelevanceForInterestingProposal();
7811
				relevance += computeRelevanceForInterestingProposal();
7909
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
7812
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
7910
				relevance += computeRelevanceForExpectingType(sourceType);
7813
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
7911
				relevance += computeRelevanceForQualification(false);
7814
				relevance += R_NON_INHERITED;
7912
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
7913
7815
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;
7816
				this.noProposal = false;
7924
				if(proposeType) {
7817
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
7925
					char[] typeName = sourceType.sourceName();
7818
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
7926
					createTypeProposal(
7819
					proposal.setName(Keywords.THIS);
7927
							sourceType,
7820
					proposal.setCompletion(Keywords.THIS);
7928
							typeName,
7821
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7929
							IAccessRule.K_ACCESSIBLE,
7822
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7930
							typeName,
7823
					proposal.setRelevance(relevance);
7931
							relevance,
7824
					this.requestor.accept(proposal);
7932
							null,
7825
					if (DEBUG) {
7933
							null,
7826
						this.printDebug(proposal);
7934
							null,
7827
					}
7935
							false);
7936
				}
7828
				}
7937
			}
7829
			}
7938
		}
7830
		}
7939
7831
7940
		if(!skip && proposeType) {
7832
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
7941
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
7833
			findFields(
7834
				token,
7835
				receiverType,
7836
				scope,
7837
				new ObjectVector(),
7838
				new ObjectVector(),
7839
				true,
7840
				invocationSite,
7841
				scope,
7842
				false,
7843
				false,
7844
				missingElements,
7845
				missingElementsStarts,
7846
				missingElementsEnds,
7847
				missingElementsHaveProblems,
7848
				null,
7849
				-1,
7850
				-1);
7942
		}
7851
		}
7943
7852
7944
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
7853
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7945
			if(proposeType && this.expectedTypesPtr > -1) {
7854
			findMethods(
7946
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
7855
				token,
7947
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
7856
				null,
7948
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
7857
				null,
7949
7858
				receiverType,
7950
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
7859
				scope,
7951
							// don't propose type variable if the completion is a constructor ('new |')
7860
				new ObjectVector(),
7952
							continue next;
7861
				true,
7953
						}
7862
				false,
7954
						if (this.options.checkDeprecation &&
7863
				invocationSite,
7955
								refBinding.isViewedAsDeprecated() &&
7864
				scope,
7956
								!scope.isDefinedInSameUnit(refBinding))
7865
				false,
7957
							continue next;
7866
				false,
7958
7867
				false,
7959
						int accessibility = IAccessRule.K_ACCESSIBLE;
7868
				missingElements,
7960
						if(refBinding.hasRestrictedAccess()) {
7869
				missingElementsStarts,
7961
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7870
				missingElementsEnds,
7962
							if(accessRestriction != null) {
7871
				missingElementsHaveProblems,
7963
								switch (accessRestriction.getProblemId()) {
7872
				null,
7964
									case IProblem.ForbiddenReference:
7873
				-1,
7965
										if (this.options.checkForbiddenReference) {
7874
				-1);
7966
											continue next;
7875
		}
7967
										}
7876
	}
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
7980
						for (int j = 0; j < typesFound.size(); j++) {
7981
							ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
7982
							if (typeFound == refBinding) {
7983
								continue next;
7984
							}
7985
						}
7986
7877
7987
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
7878
	private void findMembersFromMissingType(
7879
			final char[] token,
7880
			final long pos,
7881
			TypeBinding resolveType,
7882
			final Scope scope,
7883
			final InvocationSite invocationSite,
7884
			final boolean isInsideAnnotationAttribute) {
7885
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
7886
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
7887
			new MissingTypesGuesser.GuessedTypeRequestor() {
7888
				public void accept(
7889
						TypeBinding guessedType,
7890
						Binding[] missingElements,
7891
						int[] missingElementsStarts,
7892
						int[] missingElementsEnds,
7893
						boolean hasProblems) {
7894
					if (guessedType instanceof ReferenceBinding) {
7895
						findMembers(
7896
								CompletionEngine.this.completionToken,
7897
								(ReferenceBinding)guessedType,
7898
								scope,
7899
								invocationSite,
7900
								isInsideAnnotationAttribute,
7901
								missingElements,
7902
								missingElementsStarts,
7903
								missingElementsEnds,
7904
								hasProblems);
7905
					}
7906
				}
7907
			};
7908
		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
7909
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
7910
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
7911
	}
7988
7912
7989
						// top level types of the current unit are already proposed.
7913
	private void findMemberTypes(
7990
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
7914
		char[] typeName,
7991
							char[] packageName = refBinding.qualifiedPackageName();
7915
		ReferenceBinding receiverType,
7992
							char[] typeName = refBinding.sourceName();
7916
		Scope scope,
7993
							char[] completionName = typeName;
7917
		SourceTypeBinding typeInvocation,
7918
		boolean staticOnly,
7919
		boolean staticFieldsAndMethodOnly,
7920
		boolean fromStaticImport,
7921
		boolean checkQualification,
7922
		boolean proposeAllMemberTypes,
7923
		SourceTypeBinding typeToIgnore,
7924
		ObjectVector typesFound,
7925
		Binding[] missingElements,
7926
		int[] missingElementsStarts,
7927
		int[] missingElementsEnds,
7928
		boolean missingElementsHaveProblems) {
7994
7929
7995
							boolean isQualified = false;
7930
		ReferenceBinding currentType = receiverType;
7996
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
7931
		if (typeName == null)
7997
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
7932
			return;
7998
									if (packageName == null || packageName.length == 0)
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
7933
8006
							if(this.assistNodeIsClass) {
7934
		if (this.insideQualifiedReference
8007
								if(!refBinding.isClass()) continue next;
7935
			|| typeName.length == 0) { // do not search up the hierarchy
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
7936
8014
							int relevance = computeBaseRelevance();
7937
			findMemberTypes(
8015
							relevance += computeRelevanceForResolution();
7938
				typeName,
8016
							relevance += computeRelevanceForInterestingProposal();
7939
				currentType.memberTypes(),
8017
							relevance += computeRelevanceForCaseMatching(token, typeName);
7940
				typesFound,
8018
							relevance += computeRelevanceForExpectingType(refBinding);
7941
				receiverType,
8019
							relevance += computeRelevanceForQualification(isQualified);
7942
				typeInvocation,
8020
							relevance += computeRelevanceForRestrictions(accessibility);
7943
				staticOnly,
7944
				staticFieldsAndMethodOnly,
7945
				fromStaticImport,
7946
				checkQualification,
7947
				scope,
7948
				missingElements,
7949
				missingElementsStarts,
7950
				missingElementsEnds,
7951
				missingElementsHaveProblems);
7952
			return;
7953
		}
8021
7954
8022
							if(refBinding.isClass()) {
7955
		ReferenceBinding[] interfacesToVisit = null;
8023
								relevance += computeRelevanceForClass();
7956
		int nextPosition = 0;
8024
								relevance += computeRelevanceForException(typeName);
8025
							} else if(refBinding.isEnum()) {
8026
								relevance += computeRelevanceForEnum();
8027
							} else if(refBinding.isInterface()) {
8028
								relevance += computeRelevanceForInterface();
8029
							}
8030
7957
8031
							this.noProposal = false;
7958
		do {
8032
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7959
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
8033
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
7960
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8034
								proposal.setDeclarationSignature(packageName);
7961
				if (interfacesToVisit == null) {
8035
								proposal.setSignature(getSignature(refBinding));
7962
					interfacesToVisit = itsInterfaces;
8036
								proposal.setPackageName(packageName);
7963
					nextPosition = interfacesToVisit.length;
8037
								proposal.setTypeName(typeName);
7964
				} else {
8038
								proposal.setCompletion(completionName);
7965
					int itsLength = itsInterfaces.length;
8039
								proposal.setFlags(refBinding.modifiers);
7966
					if (nextPosition + itsLength >= interfacesToVisit.length)
8040
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7967
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8041
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7968
					nextInterface : for (int a = 0; a < itsLength; a++) {
8042
								proposal.setRelevance(relevance);
7969
						ReferenceBinding next = itsInterfaces[a];
8043
								proposal.setAccessibility(accessibility);
7970
						for (int b = 0; b < nextPosition; b++)
8044
								this.requestor.accept(proposal);
7971
							if (next == interfacesToVisit[b]) continue nextInterface;
8045
								if(DEBUG) {
7972
						interfacesToVisit[nextPosition++] = next;
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
					}
7973
					}
8063
				}
7974
				}
8064
			}
7975
			}
8065
			if(proposeType) {
7976
8066
				int l = typesFound.size();
7977
			findMemberTypes(
8067
				for (int i = 0; i < l; i++) {
7978
				typeName,
8068
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
7979
				currentType.memberTypes(),
8069
					char[] fullyQualifiedTypeName =
7980
				typesFound,
8070
						CharOperation.concat(
7981
				receiverType,
8071
								typeFound.qualifiedPackageName(),
7982
				typeInvocation,
8072
								typeFound.qualifiedSourceName(),
7983
				staticOnly,
8073
								'.');
7984
				staticFieldsAndMethodOnly,
8074
					this.knownTypes.put(fullyQualifiedTypeName, this);
7985
				fromStaticImport,
8075
				}
7986
				checkQualification,
8076
				int searchFor = IJavaSearchConstants.TYPE;
7987
				scope,
8077
				if(this.assistNodeIsClass) {
7988
				missingElements,
8078
					searchFor = IJavaSearchConstants.CLASS;
7989
				missingElementsStarts,
8079
				} else if(this.assistNodeIsInterface) {
7990
				missingElementsEnds,
8080
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
7991
				missingElementsHaveProblems);
8081
				} else if(this.assistNodeIsEnum) {
7992
8082
					searchFor = IJavaSearchConstants.ENUM;
7993
			currentType = currentType.superclass();
8083
				} else if(this.assistNodeIsAnnotation) {
7994
		} while (currentType != null);
8084
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
7995
7996
		if(proposeAllMemberTypes) {
7997
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
7998
			for (int i = 0; i < memberTypes.length; i++) {
7999
				if(memberTypes[i] != typeToIgnore) {
8000
					findSubMemberTypes(
8001
						typeName,
8002
						memberTypes[i],
8003
						scope,
8004
						typeInvocation,
8005
						staticOnly,
8006
						staticFieldsAndMethodOnly,
8007
						fromStaticImport,
8008
						typesFound);
8085
				}
8009
				}
8086
				this.nameEnvironment.findTypes(
8087
						token,
8088
						proposeAllMemberTypes,
8089
						this.options.camelCaseMatch,
8090
						searchFor,
8091
						this);
8092
				acceptTypes(scope);
8093
			}
8010
			}
8094
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
8011
		}
8095
				this.nameEnvironment.findPackages(token, this);
8012
8013
		if (interfacesToVisit != null) {
8014
			for (int i = 0; i < nextPosition; i++) {
8015
				ReferenceBinding anInterface = interfacesToVisit[i];
8016
				findMemberTypes(
8017
					typeName,
8018
					anInterface.memberTypes(),
8019
					typesFound,
8020
					receiverType,
8021
					typeInvocation,
8022
					staticOnly,
8023
					staticFieldsAndMethodOnly,
8024
					fromStaticImport,
8025
					checkQualification,
8026
					scope,
8027
					missingElements,
8028
					missingElementsStarts,
8029
					missingElementsEnds,
8030
					missingElementsHaveProblems);
8031
8032
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
8033
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8034
					int itsLength = itsInterfaces.length;
8035
					if (nextPosition + itsLength >= interfacesToVisit.length)
8036
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8037
					nextInterface : for (int a = 0; a < itsLength; a++) {
8038
						ReferenceBinding next = itsInterfaces[a];
8039
						for (int b = 0; b < nextPosition; b++)
8040
							if (next == interfacesToVisit[b]) continue nextInterface;
8041
						interfacesToVisit[nextPosition++] = next;
8042
					}
8043
				}
8096
			}
8044
			}
8097
		}
8045
		}
8098
	}
8046
	}
8099
8047
8100
	private void findTypesAndSubpackages(
8048
	protected void findMemberTypes(
8101
		char[] token,
8049
		char[] typeName,
8102
		PackageBinding packageBinding,
8050
		ReferenceBinding receiverType,
8103
		Scope scope) {
8051
		Scope scope,
8052
		SourceTypeBinding typeInvocation,
8053
		boolean staticOnly,
8054
		boolean staticFieldsAndMethodOnly,
8055
		ObjectVector typesFound,
8056
		Binding[] missingElements,
8057
		int[] missingElementsStarts,
8058
		int[] missingElementsEnds,
8059
		boolean missingElementsHaveProblems)  {
8060
		findMemberTypes(
8061
				typeName,
8062
				receiverType,
8063
				scope,
8064
				typeInvocation,
8065
				staticOnly,
8066
				staticFieldsAndMethodOnly,
8067
				false,
8068
				false,
8069
				false,
8070
				null,
8071
				typesFound,
8072
				missingElements,
8073
				missingElementsStarts,
8074
				missingElementsEnds,
8075
				missingElementsHaveProblems);
8076
	}
8077
		// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
8078
	private void findMemberTypes(
8079
		char[] typeName,
8080
		ReferenceBinding[] memberTypes,
8081
		ObjectVector typesFound,
8082
		ReferenceBinding receiverType,
8083
		SourceTypeBinding invocationType,
8084
		boolean staticOnly,
8085
		boolean staticFieldsAndMethodOnly,
8086
		boolean fromStaticImport,
8087
		boolean checkQualification,
8088
		Scope scope,
8089
		Binding[] missingElements,
8090
		int[] missingElementsStarts,
8091
		int[] missingElementsEnds,
8092
		boolean missingElementsHaveProblems) {
8104
8093
8105
		boolean proposeType =
8094
		// Inherited member types which are hidden by subclasses are filtered out
8106
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
8095
		// No visibility checks can be performed without the scope & invocationSite
8107
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
8096
		int typeLength = typeName.length;
8097
		next : for (int m = memberTypes.length; --m >= 0;) {
8098
			ReferenceBinding memberType = memberTypes[m];
8099
			//		if (!wantClasses && memberType.isClass()) continue next;
8100
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
8108
8101
8109
		char[] qualifiedName =
8102
			if (staticOnly && !memberType.isStatic()) continue next;
8110
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
8111
8103
8112
		if (token == null || token.length == 0) {
8104
			if (isForbidden(memberType)) continue next;
8113
			int length = qualifiedName.length;
8114
			System.arraycopy(
8115
				qualifiedName,
8116
				0,
8117
				qualifiedName = new char[length + 1],
8118
				0,
8119
				length);
8120
			qualifiedName[length] = '.';
8121
		}
8122
8105
8123
		this.qualifiedCompletionToken = qualifiedName;
8106
			if (typeLength > memberType.sourceName.length)
8107
				continue next;
8124
8108
8125
		if (proposeType && this.unitScope != null) {
8109
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
8126
			int typeLength = qualifiedName.length;
8110
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
8127
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
8111
				continue next;
8128
8112
8129
			for (int i = 0, length = types.length; i < length; i++) {
8113
			if (this.options.checkDeprecation &&
8130
				SourceTypeBinding sourceType = types[i];
8114
					memberType.isViewedAsDeprecated() &&
8115
					!scope.isDefinedInSameUnit(memberType))
8116
				continue next;
8131
8117
8132
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
8118
			if (this.options.checkVisibility) {
8119
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
8120
					continue next;
8121
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
8122
					continue next;
8123
				}
8124
			}
8133
8125
8134
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
8126
			if (this.insideQualifiedReference &&
8135
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
8127
					receiverType.isParameterizedType() &&
8136
				if (typeLength > qualifiedSourceTypeName.length) continue;
8128
					memberType.isStatic()) {
8137
				if (!(packageBinding == sourceType.getPackage())) continue;
8129
				continue next;
8130
			}
8138
8131
8139
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
8132
			for (int i = typesFound.size; --i >= 0;) {
8140
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
8133
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
8141
8134
8142
				if (this.options.checkDeprecation &&
8135
				if (memberType == otherType)
8143
						sourceType.isViewedAsDeprecated() &&
8136
					continue next;
8144
						!scope.isDefinedInSameUnit(sourceType))
8145
					continue;
8146
8137
8147
				int accessibility = IAccessRule.K_ACCESSIBLE;
8138
				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
8148
				if(sourceType.hasRestrictedAccess()) {
8149
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
8150
					if(accessRestriction != null) {
8151
						switch (accessRestriction.getProblemId()) {
8152
							case IProblem.ForbiddenReference:
8153
								if (this.options.checkForbiddenReference) {
8154
									continue;
8155
								}
8156
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
8157
								break;
8158
							case IProblem.DiscouragedReference:
8159
								if (this.options.checkDiscouragedReference) {
8160
									continue;
8161
								}
8162
								accessibility = IAccessRule.K_DISCOURAGED;
8163
								break;
8164
						}
8165
					}
8166
				}
8167
8139
8168
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
8140
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
8141
						continue next;
8169
8142
8170
				int relevance = computeBaseRelevance();
8143
					if (otherType.enclosingType().isInterface())
8171
				relevance += computeRelevanceForResolution();
8144
						if (memberType.enclosingType()
8172
				relevance += computeRelevanceForInterestingProposal();
8145
							.implementsInterface(otherType.enclosingType(), true))
8173
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
8146
							continue next;
8174
				relevance += computeRelevanceForExpectingType(sourceType);
8175
				relevance += computeRelevanceForQualification(false);
8176
				relevance += computeRelevanceForRestrictions(accessibility);
8177
8147
8178
				if (sourceType.isAnnotationType()) {
8148
					if (memberType.enclosingType().isInterface())
8179
					relevance += computeRelevanceForAnnotation();
8149
						if (otherType.enclosingType()
8180
				} else if (sourceType.isInterface()) {
8150
							.implementsInterface(memberType.enclosingType(), true))
8181
					relevance += computeRelevanceForInterface();
8151
							continue next;
8182
				} else if (sourceType.isClass()) {
8183
					relevance += computeRelevanceForClass();
8184
					relevance += computeRelevanceForException(sourceType.sourceName);
8185
				}
8152
				}
8186
				this.noProposal = false;
8187
				if(proposeType) {
8188
					char[] typeName = sourceType.sourceName();
8189
					createTypeProposal(
8190
							sourceType,
8191
							typeName,
8192
							IAccessRule.K_ACCESSIBLE,
8193
							typeName,
8194
							relevance,
8195
							null,
8196
							null,
8197
							null,
8198
							false);
8199
				}
8200
			}
8201
		}
8202
8203
		if(proposeType) {
8204
			int searchFor = IJavaSearchConstants.TYPE;
8205
			if(this.assistNodeIsClass) {
8206
				searchFor = IJavaSearchConstants.CLASS;
8207
			} else if(this.assistNodeIsInterface) {
8208
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
8209
			} else if(this.assistNodeIsEnum) {
8210
				searchFor = IJavaSearchConstants.ENUM;
8211
			} else if(this.assistNodeIsAnnotation) {
8212
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
8213
			}
8153
			}
8214
			this.nameEnvironment.findTypes(
8215
					qualifiedName,
8216
					false,
8217
					this.options.camelCaseMatch,
8218
					searchFor,
8219
					this);
8220
			acceptTypes(scope);
8221
		}
8222
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
8223
			this.nameEnvironment.findPackages(qualifiedName, this);
8224
		}
8225
	}
8226
8227
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
8228
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
8229
		for (int i = 0; i < importBindings.length; i++) {
8230
			ImportBinding importBinding = importBindings[i];
8231
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
8232
				Binding binding = importBinding.resolvedImport;
8233
				if(binding != null && binding.isValidBinding()) {
8234
					if(importBinding.onDemand) {
8235
						if((binding.kind() & Binding.TYPE) != 0) {
8236
							this.findMemberTypes(
8237
									token,
8238
									(ReferenceBinding) binding,
8239
									scope,
8240
									scope.enclosingSourceType(),
8241
									true,
8242
									false,
8243
									true,
8244
									true,
8245
									proposeAllMemberTypes,
8246
									null,
8247
									typesFound,
8248
									null,
8249
									null,
8250
									null,
8251
									false);
8252
						}
8253
					} else {
8254
						if ((binding.kind() & Binding.TYPE) != 0) {
8255
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
8256
							int typeLength = token.length;
8257
8258
							if (!typeBinding.isStatic()) continue;
8259
8154
8260
							if (typeLength > typeBinding.sourceName.length)	continue;
8155
			typesFound.add(memberType);
8261
8156
8262
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
8157
			if(!this.insideQualifiedReference) {
8263
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
8158
				if(this.assistNodeIsClass) {
8159
					if(!memberType.isClass()) continue next;
8160
				} else if(this.assistNodeIsInterface) {
8161
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
8162
				} else if (this.assistNodeIsAnnotation) {
8163
					if(!memberType.isAnnotationType()) continue next;
8164
				}
8165
			}
8264
8166
8265
							if (typesFound.contains(typeBinding))  continue;
8167
			char[] completionName = memberType.sourceName();
8266
8168
8267
							typesFound.add(typeBinding);
8169
			boolean isQualified = false;
8170
			if(checkQualification && !fromStaticImport) {
8171
				char[] memberPackageName = memberType.qualifiedPackageName();
8172
				char[] memberTypeName = memberType.sourceName();
8173
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
8174
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
8175
					if (memberPackageName == null || memberPackageName.length == 0)
8176
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
8177
							break next; // ignore types from the default package from outside it
8178
					isQualified = true;
8179
					completionName =
8180
						CharOperation.concat(
8181
								memberPackageName,
8182
								CharOperation.concat(
8183
										memberEnclosingTypeNames,
8184
										memberTypeName,
8185
										'.'),
8186
								'.');
8187
				}
8188
			}
8268
8189
8269
							if(this.assistNodeIsClass) {
8190
			int relevance = computeBaseRelevance();
8270
								if(!typeBinding.isClass()) continue;
8191
			relevance += computeRelevanceForResolution();
8271
							} else if(this.assistNodeIsInterface) {
8192
			relevance += computeRelevanceForInterestingProposal();
8272
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
8193
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
8273
							} else if (this.assistNodeIsAnnotation) {
8194
			relevance += computeRelevanceForExpectingType(memberType);
8274
								if(!typeBinding.isAnnotationType()) continue;
8195
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8275
							}
8196
			if(!this.insideQualifiedReference) {
8197
				relevance += computeRelevanceForQualification(isQualified);
8198
			}
8199
			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.
8276
8200
8277
							int relevance = computeBaseRelevance();
8201
			if (memberType.isAnnotationType()) {
8278
							relevance += computeRelevanceForResolution();
8202
				relevance += computeRelevanceForAnnotation();
8279
							relevance += computeRelevanceForInterestingProposal();
8203
				relevance += computeRelevanceForAnnotationTarget(memberType);
8280
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
8204
			} else if (memberType.isClass()) {
8281
							relevance += computeRelevanceForExpectingType(typeBinding);
8205
				relevance += computeRelevanceForClass();
8282
							relevance += computeRelevanceForQualification(false);
8206
				relevance += computeRelevanceForException(memberType.sourceName);
8283
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8207
			} else if(memberType.isEnum()) {
8208
				relevance += computeRelevanceForEnum();
8209
			} else if(memberType.isInterface()) {
8210
				relevance += computeRelevanceForInterface();
8211
			}
8284
8212
8285
							if (typeBinding.isClass()) {
8213
			if (missingElements != null) {
8286
								relevance += computeRelevanceForClass();
8214
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
8287
								relevance += computeRelevanceForException(typeBinding.sourceName);
8215
			}
8288
							} else if(typeBinding.isEnum()) {
8289
								relevance += computeRelevanceForEnum();
8290
							} else if(typeBinding.isInterface()) {
8291
								relevance += computeRelevanceForInterface();
8292
							}
8293
8216
8294
							this.noProposal = false;
8217
			this.noProposal = false;
8295
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8218
			createTypeProposal(
8296
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
8219
					memberType,
8297
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
8220
					memberType.qualifiedSourceName(),
8298
								proposal.setSignature(getSignature(typeBinding));
8221
					IAccessRule.K_ACCESSIBLE,
8299
								proposal.setPackageName(typeBinding.qualifiedPackageName());
8222
					completionName,
8300
								proposal.setTypeName(typeBinding.qualifiedSourceName());
8223
					relevance,
8301
								proposal.setCompletion(typeBinding.sourceName());
8224
					missingElements,
8302
								proposal.setFlags(typeBinding.modifiers);
8225
					missingElementsStarts,
8303
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8226
					missingElementsEnds,
8304
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8227
					missingElementsHaveProblems);
8305
								proposal.setRelevance(relevance);
8228
		}
8306
								this.requestor.accept(proposal);
8229
	}
8307
								if(DEBUG) {
8230
	private void findMemberTypesFromMissingType(
8308
									this.printDebug(proposal);
8231
			char[] typeName,
8309
								}
8232
			final long pos,
8310
							}
8233
			final Scope scope)  {
8311
						}
8234
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8235
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8236
			new MissingTypesGuesser.GuessedTypeRequestor() {
8237
				public void accept(
8238
						TypeBinding guessedType,
8239
						Binding[] missingElements,
8240
						int[] missingElementsStarts,
8241
						int[] missingElementsEnds,
8242
						boolean hasProblems) {
8243
					if (guessedType instanceof ReferenceBinding) {
8244
						findMemberTypes(
8245
								CompletionEngine.this.completionToken,
8246
								(ReferenceBinding)guessedType,
8247
								scope,
8248
								scope.enclosingSourceType(),
8249
								false,
8250
								false,
8251
								new ObjectVector(),
8252
								missingElements,
8253
								missingElementsStarts,
8254
								missingElementsEnds,
8255
								hasProblems);
8312
					}
8256
					}
8313
				}
8257
				}
8314
			}
8258
			};
8315
		}
8259
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
8260
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
8261
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8316
	}
8262
	}
8317
	private void findVariablesAndMethods(
8263
	
8318
		char[] token,
8264
	private void findMemberTypesFromMissingType(
8265
			TypeReference typeRef,
8266
			final long pos,
8267
			final Scope scope)  {
8268
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8269
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8270
			new MissingTypesGuesser.GuessedTypeRequestor() {
8271
				public void accept(
8272
						TypeBinding guessedType,
8273
						Binding[] missingElements,
8274
						int[] missingElementsStarts,
8275
						int[] missingElementsEnds,
8276
						boolean hasProblems) {
8277
					if (guessedType instanceof ReferenceBinding) {
8278
						findMemberTypes(
8279
								CompletionEngine.this.completionToken,
8280
								(ReferenceBinding)guessedType,
8281
								scope,
8282
								scope.enclosingSourceType(),
8283
								false,
8284
								false,
8285
								new ObjectVector(),
8286
								missingElements,
8287
								missingElementsStarts,
8288
								missingElementsEnds,
8289
								hasProblems);
8290
					}
8291
				}
8292
			};
8293
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8294
	}
8295
8296
	private void findMethodDeclarations(
8297
		char[] selector,
8298
		ReferenceBinding receiverType,
8319
		Scope scope,
8299
		Scope scope,
8320
		InvocationSite invocationSite,
8300
		ObjectVector methodsFound,
8321
		Scope invocationScope,
8301
		Binding[] missingElements,
8322
		boolean insideTypeAnnotation,
8302
		int[] missingElementsStarts,
8323
		boolean insideAnnotationAttribute) {
8303
		int[] missingElementsEnds,
8304
		boolean missingElementsHaveProblems) {
8324
8305
8325
		if (token == null)
8306
		if (selector == null) {
8326
			return;
8307
			return;
8308
		}
8327
8309
8328
		// Should local variables hide fields from the receiver type or any of its enclosing types?
8310
		MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
8329
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
8311
		if (receiverTypeMethods != null){
8330
8312
			for (int i = 0; i < receiverTypeMethods.length; i++) {
8331
		boolean staticsOnly = false;
8313
				if(!receiverTypeMethods[i].isDefaultAbstract()) {
8332
		// need to know if we're in a static context (or inside a constructor)
8314
					methodsFound.add(receiverTypeMethods[i]);
8333
		int tokenLength = token.length;
8315
				}
8334
8316
			}
8335
		ObjectVector localsFound = new ObjectVector();
8317
		}
8336
		ObjectVector fieldsFound = new ObjectVector();
8337
		ObjectVector methodsFound = new ObjectVector();
8338
8318
8339
		Scope currentScope = scope;
8319
		ReferenceBinding currentType = receiverType;
8320
		
8321
		findInterfacesMethodDeclarations(
8322
			selector,
8323
			receiverType,
8324
			currentType.superInterfaces(),
8325
			scope,
8326
			methodsFound,
8327
			missingElements,
8328
			missingElementsStarts,
8329
			missingElementsEnds,
8330
			missingElementsHaveProblems);
8331
		
8332
		if (receiverType.isInterface()) {
8333
			currentType = scope.getJavaLangObject();
8334
		} else {
8335
			currentType = receiverType.superclass();
8336
		}
8337
		
8338
		boolean hasPotentialDefaultAbstractMethods = true;
8339
		while (currentType != null) {
8340
8340
8341
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
8341
			MethodBinding[] methods = currentType.availableMethods();
8342
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
8342
			if (methods != null) {
8343
				findLocalMethodDeclarations(
8344
					selector,
8345
					methods,
8346
					scope,
8347
					methodsFound,
8348
					false,
8349
					receiverType);
8350
			}
8343
8351
8344
				switch (currentScope.kind) {
8352
			if (hasPotentialDefaultAbstractMethods &&
8353
					(currentType.isAbstract() ||
8354
							currentType.isTypeVariable() ||
8355
							currentType.isIntersectionType() ||
8356
							currentType.isEnum())){
8345
8357
8346
					case Scope.METHOD_SCOPE :
8358
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
8347
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
8348
						MethodScope methodScope = (MethodScope) currentScope;
8349
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
8350
8359
8351
					//$FALL-THROUGH$
8360
				findInterfacesMethodDeclarations(
8352
					case Scope.BLOCK_SCOPE :
8361
					selector,
8353
						BlockScope blockScope = (BlockScope) currentScope;
8362
					receiverType,
8363
					superInterfaces,
8364
					scope,
8365
					methodsFound,
8366
					missingElements,
8367
					missingElementsStarts,
8368
					missingElementsEnds,
8369
					missingElementsHaveProblems);
8370
			} else {
8371
				hasPotentialDefaultAbstractMethods = false;
8372
			}
8373
			currentType = currentType.superclass();
8374
		}
8375
	}
8376
	
8377
	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
8378
		TypeBinding erasure =  method.declaringClass.erasure();
8379
		if(!(erasure instanceof ReferenceBinding)) return null;
8354
8380
8355
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
8381
		char[][] parameterNames = null;
8356
							LocalVariableBinding local = blockScope.locals[i];
8357
8382
8358
							if (local == null)
8383
		int length = parameterTypeNames.length;
8359
								break next;
8360
8384
8361
							if (tokenLength > local.name.length)
8385
		if (length == 0){
8362
								continue next;
8386
			return CharOperation.NO_CHAR_CHAR;
8387
		}
8388
		// look into the corresponding unit if it is available
8389
		if (erasure instanceof SourceTypeBinding){
8390
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
8363
8391
8364
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
8392
			if (sourceType.scope != null){
8365
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
8393
				TypeDeclaration parsedType;
8366
								continue next;
8367
8394
8368
							if (local.isSecret())
8395
				if ((parsedType = sourceType.scope.referenceContext) != null){
8369
								continue next;
8396
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
8370
8397
8371
							for (int f = 0; f < localsFound.size; f++) {
8398
					if (methodDecl != null){
8372
								LocalVariableBinding otherLocal =
8399
						Argument[] arguments = methodDecl.arguments;
8373
									(LocalVariableBinding) localsFound.elementAt(f);
8400
						parameterNames = new char[length][];
8374
								if (CharOperation.equals(otherLocal.name, local.name, true))
8375
									continue next;
8376
							}
8377
							localsFound.add(local);
8378
8401
8379
							int relevance = computeBaseRelevance();
8402
						for(int i = 0 ; i < length ; i++){
8380
							relevance += computeRelevanceForResolution();
8403
							parameterNames[i] = arguments[i].name;
8381
							relevance += computeRelevanceForInterestingProposal(local);
8382
							relevance += computeRelevanceForCaseMatching(token, local.name);
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
						}
8404
						}
8415
						break;
8405
					}
8416
8417
					case Scope.COMPILATION_UNIT_SCOPE :
8418
						break done1;
8419
				}
8406
				}
8420
				currentScope = currentScope.parent;
8421
			}
8407
			}
8422
		}
8408
		}
8409
		// look into the model
8410
		if(parameterNames == null){
8423
8411
8424
		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
8412
			ReferenceBinding bindingType = (ReferenceBinding)erasure;
8425
		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
8426
8427
		staticsOnly = false;
8428
		currentScope = scope;
8429
8430
		if(proposeField || proposeMethod) {
8431
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
8432
8413
8433
				switch (currentScope.kind) {
8414
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
8434
					case Scope.METHOD_SCOPE :
8415
			Object type = this.typeCache.get(compoundName);
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
8416
8498
					case Scope.COMPILATION_UNIT_SCOPE :
8417
			ISourceType sourceType = null;
8499
						break done2;
8418
			if(type != null) {
8419
				if(type instanceof ISourceType) {
8420
					sourceType = (ISourceType) type;
8421
				}
8422
			} else {
8423
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
8424
				if(answer != null && answer.isSourceType()) {
8425
					sourceType = answer.getSourceTypes()[0];
8426
					this.typeCache.put(compoundName, sourceType);
8500
				}
8427
				}
8501
				currentScope = currentScope.parent;
8502
			}
8428
			}
8503
8429
8504
			findFieldsAndMethodsFromStaticImports(
8430
			if(sourceType != null) {
8505
					token,
8431
				IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
8506
					scope,
8507
					invocationSite,
8508
					invocationScope,
8509
					false,
8510
					insideAnnotationAttribute,
8511
					localsFound,
8512
					fieldsFound,
8513
					methodsFound,
8514
					proposeField,
8515
					proposeMethod);
8516
8432
8517
			if (this.assistNodeInJavadoc == 0) {
8433
				String[] parameterTypeSignatures = new String[length];
8518
				// search in favorites import
8434
				for (int i = 0; i < length; i++) {
8519
				findFieldsAndMethodsFromFavorites(
8435
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
8520
						token,
8436
				}
8521
						scope,
8437
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
8522
						invocationSite,
8438
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
8523
						invocationScope,
8524
						localsFound,
8525
						fieldsFound,
8526
						methodsFound);
8527
			}
8528
8439
8529
			findEnumConstantsFromExpectedTypes(
8440
				if(foundMethods != null) {
8530
					token,
8441
					int len = foundMethods.length;
8531
					invocationScope,
8442
					if(len == 1) {
8532
					fieldsFound);
8443
						try {
8533
		}
8444
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
8534
	}
8445
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
8535
8446
						} catch (JavaModelException e) {
8536
	private void findLocalMethodsFromStaticImports(
8447
							// method doesn't exist: ignore
8537
			char[] token,
8538
			Scope scope,
8539
			InvocationSite invocationSite,
8540
			Scope invocationScope,
8541
			boolean exactMatch,
8542
			ObjectVector methodsFound,
8543
			boolean proposeMethod) {
8544
		findFieldsAndMethodsFromStaticImports(
8545
				token,
8546
				scope,
8547
				invocationSite,
8548
				invocationScope,
8549
				exactMatch,
8550
				false,
8551
				new ObjectVector(),
8552
				new ObjectVector(),
8553
				methodsFound,
8554
				false,
8555
				proposeMethod);
8556
	}
8557
8558
	private void findFieldsAndMethodsFromStaticImports(
8559
			char[] token,
8560
			Scope scope,
8561
			InvocationSite invocationSite,
8562
			Scope invocationScope,
8563
			boolean exactMatch,
8564
			boolean insideAnnotationAttribute,
8565
			ObjectVector localsFound,
8566
			ObjectVector fieldsFound,
8567
			ObjectVector methodsFound,
8568
			boolean proposeField,
8569
			boolean proposeMethod) {
8570
		// search in static import
8571
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
8572
		for (int i = 0; i < importBindings.length; i++) {
8573
			ImportBinding importBinding = importBindings[i];
8574
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
8575
				Binding binding = importBinding.resolvedImport;
8576
				if(binding != null && binding.isValidBinding()) {
8577
					if(importBinding.onDemand) {
8578
						if((binding.kind() & Binding.TYPE) != 0) {
8579
							if(proposeField) {
8580
								findFields(
8581
									token,
8582
									(ReferenceBinding)binding,
8583
									scope,
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
						}
8448
						}
8664
					}
8449
					}
8665
				}
8450
				}
8666
			}
8451
			}
8667
		}
8452
		}
8453
		return parameterNames;
8668
	}
8454
	}
8669
	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
8670
		final TypeReference type = variable.type;
8671
		if(type != null &&
8672
				type.resolvedType != null &&
8673
				type.resolvedType.problemId() == ProblemReasons.NoError){
8674
8455
8675
			final ArrayList proposedNames = new ArrayList();
8456
	private void findMethods(
8457
		char[] selector,
8458
		TypeBinding[] typeArgTypes,
8459
		TypeBinding[] argTypes,
8460
		ReferenceBinding receiverType,
8461
		Scope scope,
8462
		ObjectVector methodsFound,
8463
		boolean onlyStaticMethods,
8464
		boolean exactMatch,
8465
		InvocationSite invocationSite,
8466
		Scope invocationScope,
8467
		boolean implicitCall,
8468
		boolean superCall,
8469
		boolean canBePrefixed,
8470
		Binding[] missingElements,
8471
		int[] missingElementsStarts,
8472
		int[] missingElementsEnds,
8473
		boolean missingElementsHaveProblems,
8474
		char[] castedReceiver,
8475
		int receiverStart,
8476
		int receiverEnd) {
8676
8477
8677
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8478
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
8678
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8479
		if (selector == null && notInJavadoc) {
8679
					public void acceptName(char[] name) {
8480
			return;
8680
						int relevance = computeBaseRelevance();
8481
		}
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
8482
8688
						// accept result
8483
		ReferenceBinding currentType = receiverType;
8689
						CompletionEngine.this.noProposal = false;
8484
		if (notInJavadoc) {
8690
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8485
			if (receiverType.isInterface()) {
8691
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8486
				findInterfacesMethods(
8692
							proposal.setSignature(getSignature(type.resolvedType));
8487
					selector,
8693
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
8488
					typeArgTypes,
8694
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
8489
					argTypes,
8695
							proposal.setName(name);
8490
					receiverType,
8696
							proposal.setCompletion(name);
8491
					new ReferenceBinding[]{currentType},
8697
							//proposal.setFlags(Flags.AccDefault);
8492
					scope,
8698
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8493
					methodsFound,
8699
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8494
					onlyStaticMethods,
8700
							proposal.setRelevance(relevance);
8495
					exactMatch,
8701
							CompletionEngine.this.requestor.accept(proposal);
8496
					invocationSite,
8702
							if(DEBUG) {
8497
					invocationScope,
8703
								CompletionEngine.this.printDebug(proposal);
8498
					implicitCall,
8704
							}
8499
					superCall,
8705
						}
8500
					canBePrefixed,
8706
						proposedNames.add(name);
8501
					missingElements,
8707
					}
8502
					missingElementsStarts,
8708
				};
8503
					missingElementsEnds,
8504
					missingElementsHaveProblems,
8505
					castedReceiver,
8506
					receiverStart,
8507
					receiverEnd);
8709
8508
8710
			ReferenceContext referenceContext = scope.referenceContext();
8509
				currentType = scope.getJavaLangObject();
8711
			if (referenceContext instanceof AbstractMethodDeclaration) {
8510
			}
8712
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8511
		}
8512
		boolean hasPotentialDefaultAbstractMethods = true;
8513
		while (currentType != null) {
8713
8514
8714
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8515
			MethodBinding[] methods = currentType.availableMethods();
8715
				nameFinder.find(
8516
			if (methods != null) {
8716
						this.completionToken,
8517
				findLocalMethods(
8717
						md,
8518
					selector,
8718
						variable.declarationSourceEnd + 1,
8519
					typeArgTypes,
8719
						discouragedNames,
8520
					argTypes,
8720
						nameRequestor);
8521
					methods,
8721
			} else if (referenceContext instanceof TypeDeclaration) {
8522
					scope,
8722
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
8523
					methodsFound,
8723
				FieldDeclaration[] fields = typeDeclaration.fields;
8524
					onlyStaticMethods,
8724
				if (fields != null) {
8525
					exactMatch,
8725
					done : for (int i = 0; i < fields.length; i++) {
8526
					receiverType,
8726
						if (fields[i] instanceof Initializer) {
8527
					invocationSite,
8727
							Initializer initializer = (Initializer) fields[i];
8528
					invocationScope,
8728
							if (initializer.bodyStart <= variable.sourceStart &&
8529
					implicitCall,
8729
									variable.sourceStart < initializer.bodyEnd) {
8530
					superCall,
8730
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8531
					canBePrefixed,
8731
								nameFinder.find(
8532
					missingElements,
8732
										this.completionToken,
8533
					missingElementsStarts,
8733
										initializer,
8534
					missingElementsEnds,
8734
										typeDeclaration.scope,
8535
					missingElementsHaveProblems,
8735
										variable.declarationSourceEnd + 1,
8536
					castedReceiver,
8736
										discouragedNames,
8537
					receiverStart,
8737
										nameRequestor);
8538
					receiverEnd);
8738
								break done;
8539
			}
8739
							}
8540
8740
						}
8541
			if (hasPotentialDefaultAbstractMethods &&
8542
					(currentType.isAbstract() ||
8543
							currentType.isTypeVariable() ||
8544
							currentType.isIntersectionType() ||
8545
							currentType.isEnum())){
8546
8547
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
8548
				if (superInterfaces != null && currentType.isIntersectionType()) {
8549
					for (int i = 0; i < superInterfaces.length; i++) {
8550
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
8741
					}
8551
					}
8742
				}
8552
				}
8743
			}
8744
8553
8745
			int proposedNamesCount = proposedNames.size();
8554
				findInterfacesMethods(
8746
			if (proposedNamesCount > 0) {
8555
					selector,
8747
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8556
					typeArgTypes,
8557
					argTypes,
8558
					receiverType,
8559
					superInterfaces,
8560
					scope,
8561
					methodsFound,
8562
					onlyStaticMethods,
8563
					exactMatch,
8564
					invocationSite,
8565
					invocationScope,
8566
					implicitCall,
8567
					superCall,
8568
					canBePrefixed,
8569
					missingElements,
8570
					missingElementsStarts,
8571
					missingElementsEnds,
8572
					missingElementsHaveProblems,
8573
					castedReceiver,
8574
					receiverStart,
8575
					receiverEnd);
8576
			} else {
8577
				hasPotentialDefaultAbstractMethods = false;
8748
			}
8578
			}
8579
			currentType = currentType.superclass();
8749
		}
8580
		}
8750
8751
		return null;
8752
	}
8581
	}
8753
8582
8754
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
8583
	private void findNestedTypes(
8755
		final ArrayList proposedNames = new ArrayList();
8584
		char[] typeName,
8756
8585
		SourceTypeBinding currentType,
8757
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8586
		Scope scope,
8758
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8587
		boolean proposeAllMemberTypes,
8759
				public void acceptName(char[] name) {
8588
		ObjectVector typesFound) {
8760
					CompletionEngine.this.acceptUnresolvedName(name);
8589
		
8761
					proposedNames.add(name);
8590
		if (typeName == null)
8762
				}
8591
			return;
8763
			};
8764
8592
8765
		ReferenceContext referenceContext = scope.referenceContext();
8593
		int typeLength = typeName.length;
8766
		if (referenceContext instanceof AbstractMethodDeclaration) {
8767
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8768
8594
8769
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8595
		SourceTypeBinding nextTypeToIgnore = null;
8770
			nameFinder.findAfter(
8596
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
8771
					this.completionToken,
8772
					md.scope,
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
					}
8799
				}
8800
			}
8801
		}
8802
8597
8803
		int proposedNamesCount = proposedNames.size();
8598
			switch (scope.kind) {
8804
		if (proposedNamesCount > 0) {
8805
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8806
		}
8807
8599
8808
		return null;
8600
				case Scope.METHOD_SCOPE :
8809
	}
8601
				case Scope.BLOCK_SCOPE :
8602
					BlockScope blockScope = (BlockScope) scope;
8810
8603
8811
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
8604
					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
8812
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
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
8605
8823
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
8606
						if (blockScope.subscopes[i] instanceof ClassScope) {
8824
		final ArrayList proposedNames = new ArrayList();
8607
							SourceTypeBinding localType =
8608
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
8825
8609
8826
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8610
							if (!localType.isAnonymousType()) {
8827
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8611
								if (isForbidden(localType))
8828
				public void acceptName(char[] name) {
8612
									continue next;
8829
					CompletionEngine.this.acceptUnresolvedName(name);
8830
					proposedNames.add(name);
8831
				}
8832
			};
8833
8613
8834
		BlockScope upperScope = scope;
8614
								if (typeLength > localType.sourceName.length)
8835
		while (upperScope.enclosingMethodScope() != null) {
8615
									continue next;
8836
			upperScope = upperScope.enclosingMethodScope();
8616
								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
8837
		}
8617
										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
8618
									continue next;
8838
8619
8839
		ReferenceContext referenceContext = upperScope.referenceContext();
8620
								for (int j = typesFound.size; --j >= 0;) {
8840
		if (referenceContext instanceof AbstractMethodDeclaration) {
8621
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
8841
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8842
8622
8843
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8623
									if (localType == otherType)
8844
			nameFinder.findBefore(
8624
										continue next;
8845
					this.completionToken,
8625
								}
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
8626
8627
								if(this.assistNodeIsClass) {
8628
									if(!localType.isClass()) continue next;
8629
								} else if(this.assistNodeIsInterface) {
8630
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
8631
								} else if (this.assistNodeIsAnnotation) {
8632
									if(!localType.isAnnotationType()) continue next;
8633
								}
8856
8634
8857
			done : {
8635
								int relevance = computeBaseRelevance();
8858
				FieldDeclaration[] fields = typeDeclaration.fields;
8636
								relevance += computeRelevanceForResolution();
8859
				if (fields != null) {
8637
								relevance += computeRelevanceForInterestingProposal();
8860
					for (int i = 0; i < fields.length; i++) {
8638
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
8861
						if (fields[i] instanceof Initializer) {
8639
								relevance += computeRelevanceForExpectingType(localType);
8862
							Initializer initializer = (Initializer) fields[i];
8640
								relevance += computeRelevanceForException(localType.sourceName);
8863
							if (initializer.block.sourceStart <= recordTo &&
8641
								relevance += computeRelevanceForClass();
8864
									recordTo < initializer.bodyEnd) {
8642
								relevance += computeRelevanceForQualification(false);
8643
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
8644
								relevance += computeRelevanceForAnnotationTarget(localType);
8865
8645
8866
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8646
								this.noProposal = false;
8867
								nameFinder.findBefore(
8647
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8868
										this.completionToken,
8648
									createTypeProposal(
8869
										typeDeclaration.scope,
8649
											localType,
8870
										typeDeclaration.scope,
8650
											localType.sourceName,
8871
										initializer.block.sourceStart,
8651
											IAccessRule.K_ACCESSIBLE,
8872
										recordTo,
8652
											localType.sourceName,
8873
										parseTo,
8653
											relevance,
8874
										discouragedNames,
8654
											null,
8875
										nameRequestor);
8655
											null,
8876
								break done;
8656
											null,
8657
											false);
8658
								}
8877
							}
8659
							}
8878
						}
8660
						}
8879
					}
8661
					}
8880
				}
8662
					break;
8881
			}
8882
		}
8883
8884
		int proposedNamesCount = proposedNames.size();
8885
		if (proposedNamesCount > 0) {
8886
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8887
		}
8888
8663
8889
		return null;
8664
				case Scope.CLASS_SCOPE :
8890
	}
8665
					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
8891
		// Helper method for private void findVariableNames(char[] name, TypeReference type )
8666
					findMemberTypes(
8892
	private void findVariableName(
8667
							typeName,
8893
			char[] token,
8668
							enclosingSourceType,
8894
			char[] qualifiedPackageName,
8669
							scope,
8895
			char[] qualifiedSourceName,
8670
							currentType,
8896
			char[] sourceName,
8671
							false,
8897
			final TypeBinding typeBinding,
8672
							false,
8898
			char[][] discouragedNames,
8673
							false,
8899
			final char[][] forbiddenNames,
8674
							false,
8900
			int dim,
8675
							proposeAllMemberTypes,
8901
			int kind,
8676
							nextTypeToIgnore,
8902
			int modifiers){
8677
							typesFound,
8903
		findVariableName(
8678
							null,
8904
				token,
8679
							null,
8905
				qualifiedPackageName,
8680
							null,
8906
				qualifiedSourceName,
8681
							false);
8907
				sourceName,
8682
					nextTypeToIgnore = enclosingSourceType;
8908
				typeBinding,
8683
					if (typeLength == 0)
8909
				discouragedNames,
8684
						return; // do not search outside the class scope if no prefix was provided
8910
				forbiddenNames,
8685
					break;
8911
				false,
8912
				dim,
8913
				kind,
8914
				modifiers);
8915
	}
8916
	private void findVariableName(
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
8929
		if(sourceName == null || sourceName.length == 0)
8930
			return;
8931
8686
8932
		// compute variable name for non base type
8687
				case Scope.COMPILATION_UNIT_SCOPE :
8933
		final char[] displayName;
8688
					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
			}
8689
			}
8946
		} else {
8690
			scope = scope.parent;
8947
			displayName = typeBinding.qualifiedSourceName();
8948
		}
8691
		}
8692
	}
8949
8693
8950
		final char[] t = token;
8694
	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
8695
8964
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
8696
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
8965
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
8697
		if (this.completionToken.length == 0)
8966
			}
8698
			return;
8967
8699
8968
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
8700
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
8969
				accept(name, 0, reusedCharacters);
8701
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
8970
			}
8702
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
8971
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
8703
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
8972
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
8704
	}
8973
				for (int i = 0; i < l; i++) {
8974
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
8975
				}
8976
8705
8977
				if (CharOperation.prefixEquals(t, name, false)) {
8706
	private void findParameterizedType(TypeReference ref, Scope scope) {
8978
					int relevance = computeBaseRelevance();
8707
		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
8979
					relevance += computeRelevanceForInterestingProposal();
8708
		if(refBinding != null) {
8980
					relevance += computeRelevanceForCaseMatching(t, name);
8709
			if (this.options.checkDeprecation &&
8981
					relevance += prefixAndSuffixRelevance;
8710
					refBinding.isViewedAsDeprecated() &&
8982
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
8711
					!scope.isDefinedInSameUnit(refBinding))
8983
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
8712
				return;
8984
8713
8985
					// accept result
8714
			int accessibility = IAccessRule.K_ACCESSIBLE;
8986
					CompletionEngine.this.noProposal = false;
8715
			if(refBinding.hasRestrictedAccess()) {
8987
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8716
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
8988
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8717
				if(accessRestriction != null) {
8989
						proposal.setSignature(getSignature(typeBinding));
8718
					switch (accessRestriction.getProblemId()) {
8990
						proposal.setPackageName(q);
8719
						case IProblem.ForbiddenReference:
8991
						proposal.setTypeName(displayName);
8720
							if (this.options.checkForbiddenReference) {
8992
						proposal.setName(name);
8721
								return;
8993
						proposal.setCompletion(name);
8722
							}
8994
						//proposal.setFlags(Flags.AccDefault);
8723
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
8995
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8724
							break;
8996
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8725
						case IProblem.DiscouragedReference:
8997
						proposal.setRelevance(relevance);
8726
							if (this.options.checkDiscouragedReference) {
8998
						CompletionEngine.this.requestor.accept(proposal);
8727
								return;
8999
						if(DEBUG) {
8728
							}
9000
							CompletionEngine.this.printDebug(proposal);
8729
							accessibility = IAccessRule.K_DISCOURAGED;
9001
						}
8730
							break;
9002
					}
8731
					}
9003
				}
8732
				}
9004
			}
8733
			}
9005
		};
9006
8734
9007
		switch (kind) {
8735
			int relevance = computeBaseRelevance();
9008
			case FIELD :
8736
			relevance += computeRelevanceForResolution();
9009
				InternalNamingConventions.suggestFieldNames(
8737
			relevance += computeRelevanceForInterestingProposal();
9010
					this.javaProject,
8738
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
9011
					qualifiedPackageName,
8739
			relevance += computeRelevanceForExpectingType(refBinding);
9012
					qualifiedSourceName,
8740
			relevance += computeRelevanceForQualification(false);
9013
					dim,
8741
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
9014
					modifiers,
8742
9015
					token,
8743
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9016
					discouragedNames,
8744
				createTypeProposal(
9017
					namingRequestor);
8745
						refBinding,
9018
				break;
8746
						refBinding.qualifiedSourceName(),
9019
			case LOCAL :
8747
						IAccessRule.K_ACCESSIBLE,
9020
				InternalNamingConventions.suggestLocalVariableNames(
8748
						CharOperation.NO_CHAR,
9021
					this.javaProject,
8749
						relevance,
9022
					qualifiedPackageName,
8750
						null,
9023
					qualifiedSourceName,
8751
						null,
9024
					dim,
8752
						null,
9025
					token,
8753
						false);
9026
					discouragedNames,
8754
			}
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
		}
8755
		}
9040
	}
8756
	}
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
8757
9053
		findVariableName(
8758
	private void findSubMemberTypes(
9054
				token,
8759
		char[] typeName,
9055
				qualifiedPackageName,
8760
		ReferenceBinding receiverType,
9056
				qualifiedSourceName,
8761
		Scope scope,
9057
				sourceName,
8762
		SourceTypeBinding typeInvocation,
9058
				typeBinding,
8763
		boolean staticOnly,
9059
				discouragedNames,
8764
		boolean staticFieldsAndMethodOnly,
9060
				forbiddenNames,
8765
		boolean fromStaticImport,
9061
				false,
8766
		ObjectVector typesFound) {
9062
				1,
9063
				kind,
9064
				modifiers);
9065
	}
9066
8767
9067
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
8768
		ReferenceBinding currentType = receiverType;
9068
		if(type != null &&
8769
		if (typeName == null || typeName.length == 0)
9069
			type.resolvedType != null) {
8770
			return;
9070
			TypeBinding tb = type.resolvedType;
9071
8771
9072
			if (tb.problemId() == ProblemReasons.NoError &&
8772
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
9073
					tb != Scope.getBaseType(VOID)) {
8773
9074
				findVariableName(
8774
		findMemberTypes(
9075
					name,
8775
				typeName,
9076
					tb.leafComponentType().qualifiedPackageName(),
8776
				currentType.memberTypes(),
9077
					tb.leafComponentType().qualifiedSourceName(),
8777
				typesFound,
9078
					tb.leafComponentType().sourceName(),
8778
				receiverType,
9079
					tb,
8779
				typeInvocation,
9080
					discouragedNames,
8780
				staticOnly,
9081
					forbiddenNames,
8781
				staticFieldsAndMethodOnly,
9082
					type.dimensions(),
8782
				fromStaticImport,
9083
					kind,
8783
				true,
9084
					modifiers);
8784
				scope,
9085
				
8785
				null,
9086
				if (tb.isParameterizedType() &&
8786
				null,
9087
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
8787
				null,
9088
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
8788
				false);
9089
					TypeBinding[] arguments = ptb.arguments;
8789
9090
					if (arguments != null && arguments.length == 1) {
8790
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
9091
						TypeBinding argument = arguments[0];
8791
		next : for (int i = 0; i < memberTypes.length; i++) {
9092
						findVariableNameForCollection(
8792
			if (this.options.checkVisibility) {
9093
							name,
8793
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
9094
							argument.leafComponentType().qualifiedPackageName(),
8794
					continue next;
9095
							argument.leafComponentType().qualifiedSourceName(),
8795
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
9096
							argument.leafComponentType().sourceName(),
8796
					continue next;
9097
							tb,
9098
							discouragedNames,
9099
							forbiddenNames,
9100
							kind,
9101
							modifiers);
9102
					}
9103
				}
8797
				}
9104
			}
8798
			}
8799
			findSubMemberTypes(
8800
				typeName,
8801
				memberTypes[i],
8802
				scope,
8803
				typeInvocation,
8804
				staticOnly,
8805
				staticFieldsAndMethodOnly,
8806
				fromStaticImport,
8807
				typesFound);
9105
		}
8808
		}
9106
9107
	}
8809
	}
9108
8810
9109
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
8811
	private void findTrueOrFalseKeywords(char[][] choices) {
9110
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
8812
		if(choices == null || choices.length == 0) return;
9111
8813
9112
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
8814
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
9113
8815
9114
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
8816
		for (int i = 0; i < choices.length; i++) {
8817
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
8818
					CharOperation.equals(choices[i], Keywords.FALSE)
8819
			){
8820
				int relevance = computeBaseRelevance();
8821
				relevance += computeRelevanceForResolution();
8822
				relevance += computeRelevanceForInterestingProposal();
8823
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
8824
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
8825
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
8826
				relevance += computeRelevanceForQualification(false);
8827
				relevance += R_TRUE_OR_FALSE;
9115
8828
9116
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
8829
				this.noProposal = false;
8830
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
8831
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
8832
					proposal.setName(choices[i]);
8833
					proposal.setCompletion(choices[i]);
8834
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8835
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8836
					proposal.setRelevance(relevance);
8837
					this.requestor.accept(proposal);
8838
					if(DEBUG) {
8839
						this.printDebug(proposal);
8840
					}
8841
				}
8842
			}
8843
		}
8844
	}
9117
8845
9118
		int count = 0;
8846
	private void findTypeParameters(char[] token, Scope scope) {
9119
		next : for (int i = 0; i < favoriteReferences.length; i++) {
8847
		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
9120
			String favoriteReference = favoriteReferences[i];
9121
8848
9122
			int length;
8849
		TypeParameter[] typeParameters = null;
9123
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
8850
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
8851
			typeParameters = null;
8852
			switch (scope.kind) {
8853
				case Scope.METHOD_SCOPE :
8854
					MethodScope methodScope = (MethodScope) scope;
8855
					if(methodScope.referenceContext instanceof MethodDeclaration) {
8856
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
8857
						typeParameters = methodDeclaration.typeParameters;
8858
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
8859
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
8860
						typeParameters = methodDeclaration.typeParameters;
8861
					}
8862
					break;
8863
				case Scope.CLASS_SCOPE :
8864
					ClassScope classScope = (ClassScope) scope;
8865
					typeParameters = classScope.referenceContext.typeParameters;
8866
					break;
8867
				case Scope.COMPILATION_UNIT_SCOPE :
8868
					return;
8869
			}
8870
			if(typeParameters != null) {
8871
				for (int i = 0; i < typeParameters.length; i++) {
8872
					int typeLength = token.length;
8873
					TypeParameter typeParameter = typeParameters[i];
9124
8874
9125
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
8875
					if(typeParameter.binding == null) continue;
9126
8876
9127
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
8877
					if (typeLength > typeParameter.name.length) continue;
9128
			if (onDemand) {
9129
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
9130
			}
9131
8878
9132
			// remove duplicate and conflicting
8879
					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
9133
			for (int j = 0; j < count; j++) {
8880
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
9134
				ImportReference f = resolvedImports[j].reference;
9135
8881
9136
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
8882
					int relevance = computeBaseRelevance();
8883
					relevance += computeRelevanceForResolution();
8884
					relevance += computeRelevanceForInterestingProposal();
8885
					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
8886
					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
8887
					relevance += computeRelevanceForQualification(false);
8888
					relevance += computeRelevanceForException(typeParameter.name);
8889
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
9137
8890
9138
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
8891
					this.noProposal = false;
9139
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
8892
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9140
						continue next;
8893
						createTypeParameterProposal(typeParameter, relevance);
8894
					}
9141
				}
8895
				}
9142
			}
8896
			}
8897
			scope = scope.parent;
8898
		}
8899
	}
9143
8900
9144
			boolean isStatic = true;
8901
	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
9145
9146
			ImportReference importReference =
9147
				new ImportReference(
9148
						compoundName,
9149
						new long[compoundName.length],
9150
						onDemand,
9151
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
9152
8902
9153
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
8903
		if (token == null)
8904
			return;
9154
8905
9155
			if (!importBinding.isValidBinding()) {
8906
		// do not propose type if completion token is empty
9156
				continue next;
8907
		boolean skip = false;
8908
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
8909
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
8910
				return;
9157
			}
8911
			}
8912
			skip = true;
8913
		}
9158
8914
9159
			if (importBinding instanceof PackageBinding) {
8915
		boolean proposeType =
9160
				continue next;
8916
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9161
			}
8917
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9162
8918
9163
			resolvedImports[count++] =
8919
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
9164
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
8920
8921
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
8922
			
8923
			checkCancel();
8924
			
8925
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
8926
			if(!this.assistNodeIsInterface &&
8927
					!this.assistNodeIsConstructor &&
8928
					!this.assistNodeIsAnnotation &&
8929
					this.assistNodeInJavadoc == 0) {
8930
				
8931
				checkCancel();
8932
				
8933
				// don't propose type parameters if the completion is a constructor ('new |')
8934
				findTypeParameters(token, scope);
8935
			}
9165
		}
8936
		}
9166
8937
9167
		if (resolvedImports.length > count)
8938
		boolean isEmptyPrefix = token.length == 0;
9168
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
9169
8939
9170
		return this.favoriteReferenceBindings = resolvedImports;
8940
		if (!skip && proposeType && this.unitScope != null) {
9171
	}
8941
			
8942
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
8943
			if(outerInvocationType != null) {
8944
				ReferenceBinding temp = outerInvocationType.enclosingType();
8945
				while(temp != null) {
8946
					outerInvocationType = temp;
8947
					temp = temp.enclosingType();
8948
				}
8949
			}
9172
8950
9173
	public AssistParser getParser() {
8951
			int typeLength = token.length;
8952
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9174
8953
9175
		return this.parser;
8954
			next : for (int i = 0, length = types.length; i < length; i++) {
9176
	}
8955
				
8956
				checkCancel();
8957
				
8958
				SourceTypeBinding sourceType = types[i];
9177
8959
9178
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
8960
				if(isForbidden(sourceType)) 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
8961
9189
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
8962
				if(proposeAllMemberTypes &&
9190
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
8963
					sourceType != outerInvocationType) {
9191
				    sig.append(Signature.C_GENERIC_START);
8964
					findSubMemberTypes(
9192
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
8965
							token,
9193
				        sig.append(typeVariables[i].genericTypeSignature());
8966
							sourceType,
9194
				    }
8967
							scope,
9195
				    sig.append(Signature.C_GENERIC_END);
8968
							scope.enclosingSourceType(),
8969
							false,
8970
							false,
8971
							false,
8972
							typesFound);
9196
				}
8973
				}
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
9208
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9209
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9210
				    sig.append(Signature.C_GENERIC_START);
9211
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9212
				        sig.append(typeVariables[i].genericTypeSignature());
9213
				    }
9214
				    sig.append(Signature.C_GENERIC_END);
9215
				}
9216
			} else {
9217
				char[] typeSig = referenceBinding.signature();
9218
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9219
9220
				if (referenceBinding.isStatic()) {
9221
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9222
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9223
					    sig.append(Signature.C_GENERIC_START);
9224
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
9225
					        sig.append(typeVariables[i].genericTypeSignature());
9226
					    }
9227
					    sig.append(Signature.C_GENERIC_END);
9228
					}
9229
				}
9230
			}
9231
			sig.append(Signature.C_SEMICOLON);
9232
		}
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
8974
9240
	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
8975
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
9241
		char[] result = null;
8976
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
9242
		StringBuffer sig = new StringBuffer(10);
9243
8977
9244
		sig.append(typeBinding.signature());
8978
				if (typeLength > sourceType.sourceName.length) continue next;
9245
8979
9246
		int sigLength = sig.length();
8980
				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
9247
		result = new char[sigLength];
8981
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
9248
		sig.getChars(0, sigLength, result, 0);
9249
		result = CharOperation.replaceOnCopy(result, '/', '.');
9250
		return result;
9251
	}
9252
8982
9253
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
8983
				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
9254
		if (this.targetedElement == TagBits.AnnotationForPackage) {
8984
					continue next;
9255
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9256
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
9257
				return false;
9258
			}
9259
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
9260
			if (scope.parent != null &&
9261
					scope.parent.parent != null &&
9262
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
9263
					scope.parent.parent instanceof CompilationUnitScope) {
9264
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9265
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
9266
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
9267
						return false;
9268
					}
9269
				} else {
9270
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
9271
						return false;
9272
					}
9273
				}
8985
				}
9274
			}
9275
		}
9276
		return true;
9277
	}
9278
8986
9279
	protected void reset() {
8987
				for (int j = typesFound.size; --j >= 0;) {
8988
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
9280
8989
9281
		super.reset(false);
8990
					if (sourceType == otherType) continue next;
9282
		this.knownPkgs = new HashtableOfObject(10);
8991
				}
9283
		this.knownTypes = new HashtableOfObject(10);
9284
	}
9285
8992
9286
	private void setSourceAndTokenRange(int start, int end) {
8993
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9287
		this.setSourceAndTokenRange(start, end, true);
9288
	}
9289
8994
9290
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
8995
				if(this.assistNodeIsClass) {
9291
		this.setSourceRange(start, end, emptyTokenAdjstment);
8996
					if(!sourceType.isClass()) continue next;
9292
		this.setTokenRange(start, end, emptyTokenAdjstment);
8997
				} else if(this.assistNodeIsInterface) {
9293
	}
8998
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
8999
				} else if (this.assistNodeIsAnnotation) {
9000
					if(!sourceType.isAnnotationType()) continue next;
9001
				} else if (isEmptyPrefix && this.assistNodeIsException) {
9002
					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
9003
						continue next;
9004
					}
9005
				}
9294
9006
9295
	private void setSourceRange(int start, int end) {
9007
				int relevance = computeBaseRelevance();
9296
		this.setSourceRange(start, end, true);
9008
				relevance += computeRelevanceForResolution();
9297
	}
9009
				relevance += computeRelevanceForInterestingProposal();
9010
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
9011
				relevance += computeRelevanceForExpectingType(sourceType);
9012
				relevance += computeRelevanceForQualification(false);
9013
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
9298
9014
9299
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
9015
				if (sourceType.isAnnotationType()) {
9300
		this.startPosition = start;
9016
					relevance += computeRelevanceForAnnotation();
9301
		if(emptyTokenAdjstment) {
9017
					relevance += computeRelevanceForAnnotationTarget(sourceType);
9302
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
9018
				} else if (sourceType.isInterface()) {
9303
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
9019
					relevance += computeRelevanceForInterface();
9304
		} else {
9020
				} else if(sourceType.isClass()){
9305
			this.endPosition = end + 1;
9021
					relevance += computeRelevanceForClass();
9022
					relevance += computeRelevanceForException(sourceType.sourceName);
9023
				}
9024
				this.noProposal = false;
9025
				if(proposeType) {
9026
					char[] typeName = sourceType.sourceName();
9027
					createTypeProposal(
9028
							sourceType,
9029
							typeName,
9030
							IAccessRule.K_ACCESSIBLE,
9031
							typeName,
9032
							relevance,
9033
							null,
9034
							null,
9035
							null,
9036
							false);
9037
				}
9038
			}
9306
		}
9039
		}
9307
	}
9308
9040
9309
	private void setTokenRange(int start, int end) {
9041
		if(!skip && proposeType) {
9310
		this.setTokenRange(start, end, true);
9042
			
9311
	}
9043
			checkCancel();
9312
9044
			
9313
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
9045
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
9314
		this.tokenStart = start;
9315
		if(emptyTokenAdjstment) {
9316
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
9317
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
9318
		} else {
9319
			this.tokenEnd = end + 1;
9320
		}
9046
		}
9321
	}
9322
9047
9323
	private char[][] computeAlreadyDefinedName(
9048
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
9324
			BlockScope scope,
9049
			if(proposeType && this.expectedTypesPtr > -1) {
9325
			InvocationSite invocationSite) {
9050
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
9326
		ArrayList result = new ArrayList();
9051
					
9052
					checkCancel();
9053
					
9054
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
9055
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
9327
9056
9328
		boolean staticsOnly = false;
9057
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
9058
							// don't propose type variable if the completion is a constructor ('new |')
9059
							continue next;
9060
						}
9061
						if (this.options.checkDeprecation &&
9062
								refBinding.isViewedAsDeprecated() &&
9063
								!scope.isDefinedInSameUnit(refBinding))
9064
							continue next;
9329
9065
9330
		Scope currentScope = scope;
9066
						int accessibility = IAccessRule.K_ACCESSIBLE;
9067
						if(refBinding.hasRestrictedAccess()) {
9068
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
9069
							if(accessRestriction != null) {
9070
								switch (accessRestriction.getProblemId()) {
9071
									case IProblem.ForbiddenReference:
9072
										if (this.options.checkForbiddenReference) {
9073
											continue next;
9074
										}
9075
										accessibility = IAccessRule.K_NON_ACCESSIBLE;
9076
										break;
9077
									case IProblem.DiscouragedReference:
9078
										if (this.options.checkDiscouragedReference) {
9079
											continue next;
9080
										}
9081
										accessibility = IAccessRule.K_DISCOURAGED;
9082
										break;
9083
								}
9084
							}
9085
						}
9331
9086
9332
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9087
						for (int j = 0; j < typesFound.size(); j++) {
9088
							ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
9089
							if (typeFound == refBinding) {
9090
								continue next;
9091
							}
9092
						}
9333
9093
9334
			switch (currentScope.kind) {
9094
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
9335
9095
9336
				case Scope.METHOD_SCOPE :
9096
						// top level types of the current unit are already proposed.
9337
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9097
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
9338
					MethodScope methodScope = (MethodScope) currentScope;
9098
							char[] packageName = refBinding.qualifiedPackageName();
9339
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9099
							char[] typeName = refBinding.sourceName();
9100
							char[] completionName = typeName;
9340
9101
9341
				//$FALL-THROUGH$
9102
							boolean isQualified = false;
9342
				case Scope.BLOCK_SCOPE :
9103
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
9343
					BlockScope blockScope = (BlockScope) currentScope;
9104
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
9105
									if (packageName == null || packageName.length == 0)
9106
										if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
9107
											continue next; // ignore types from the default package from outside it
9108
									completionName = CharOperation.concat(packageName, typeName, '.');
9109
									isQualified = true;
9110
								}
9111
							}
9344
9112
9345
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9113
							if(this.assistNodeIsClass) {
9346
						LocalVariableBinding local = blockScope.locals[i];
9114
								if(!refBinding.isClass()) continue next;
9115
							} else if(this.assistNodeIsInterface) {
9116
								if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
9117
							} else if (this.assistNodeIsAnnotation) {
9118
								if(!refBinding.isAnnotationType()) continue next;
9119
							}
9347
9120
9348
						if (local == null)
9121
							int relevance = computeBaseRelevance();
9349
							break next;
9122
							relevance += computeRelevanceForResolution();
9123
							relevance += computeRelevanceForInterestingProposal();
9124
							relevance += computeRelevanceForCaseMatching(token, typeName);
9125
							relevance += computeRelevanceForExpectingType(refBinding);
9126
							relevance += computeRelevanceForQualification(isQualified);
9127
							relevance += computeRelevanceForRestrictions(accessibility);
9350
9128
9351
						if (local.isSecret())
9129
							if(refBinding.isClass()) {
9352
							continue next;
9130
								relevance += computeRelevanceForClass();
9131
								relevance += computeRelevanceForException(typeName);
9132
							} else if(refBinding.isEnum()) {
9133
								relevance += computeRelevanceForEnum();
9134
							} else if(refBinding.isInterface()) {
9135
								relevance += computeRelevanceForInterface();
9136
							}
9353
9137
9354
						result.add(local.name);
9138
							this.noProposal = false;
9139
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9140
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9141
								proposal.setDeclarationSignature(packageName);
9142
								proposal.setSignature(getSignature(refBinding));
9143
								proposal.setPackageName(packageName);
9144
								proposal.setTypeName(typeName);
9145
								proposal.setCompletion(completionName);
9146
								proposal.setFlags(refBinding.modifiers);
9147
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9148
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9149
								proposal.setRelevance(relevance);
9150
								proposal.setAccessibility(accessibility);
9151
								this.requestor.accept(proposal);
9152
								if(DEBUG) {
9153
									this.printDebug(proposal);
9154
								}
9155
							}
9156
						}
9355
					}
9157
					}
9356
					break;
9158
				}
9357
9358
				case Scope.CLASS_SCOPE :
9359
					ClassScope classScope = (ClassScope) currentScope;
9360
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
9361
					computeAlreadyDefinedName(
9362
							enclosingType,
9363
							classScope,
9364
							staticsOnly,
9365
							invocationSite,
9366
							result);
9367
					staticsOnly |= enclosingType.isStatic();
9368
					break;
9369
9370
				case Scope.COMPILATION_UNIT_SCOPE :
9371
					break done1;
9372
			}
9159
			}
9373
			currentScope = currentScope.parent;
9160
		} else {
9374
		}
9161
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
9375
9162
				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
9376
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
9163
					if (proposeBaseTypes) {
9377
9164
						if (proposeVoidType) {
9378
		return (char[][])result.toArray(new char[result.size()][]);
9165
							findKeywords(token, BASE_TYPE_NAMES, false, false);
9379
	}
9166
						} else {
9380
9167
							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
9381
	private void computeAlreadyDefinedName(
9168
						}
9382
			SourceTypeBinding receiverType,
9383
			ClassScope scope,
9384
			boolean onlyStaticFields,
9385
			InvocationSite invocationSite,
9386
			ArrayList result) {
9387
9388
		ReferenceBinding currentType = receiverType;
9389
		ReferenceBinding[] interfacesToVisit = null;
9390
		int nextPosition = 0;
9391
		do {
9392
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
9393
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9394
				if (interfacesToVisit == null) {
9395
					interfacesToVisit = itsInterfaces;
9396
					nextPosition = interfacesToVisit.length;
9397
				} else {
9398
					int itsLength = itsInterfaces.length;
9399
					if (nextPosition + itsLength >= interfacesToVisit.length)
9400
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9401
					nextInterface : for (int a = 0; a < itsLength; a++) {
9402
						ReferenceBinding next = itsInterfaces[a];
9403
						for (int b = 0; b < nextPosition; b++)
9404
							if (next == interfacesToVisit[b]) continue nextInterface;
9405
						interfacesToVisit[nextPosition++] = next;
9406
					}
9169
					}
9407
				}
9170
				}
9408
			}
9171
			}
9409
9172
			if(proposeType) {
9410
			FieldBinding[] fields = currentType.availableFields();
9173
				int l = typesFound.size();
9411
			if(fields != null && fields.length > 0) {
9174
				for (int i = 0; i < l; i++) {
9412
				computeAlreadyDefinedName(
9175
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
9413
					fields,
9176
					char[] fullyQualifiedTypeName =
9414
					scope,
9177
						CharOperation.concat(
9415
					onlyStaticFields,
9178
								typeFound.qualifiedPackageName(),
9416
					receiverType,
9179
								typeFound.qualifiedSourceName(),
9417
					invocationSite,
9180
								'.');
9418
					result);
9181
					this.knownTypes.put(fullyQualifiedTypeName, this);
9419
			}
9420
			currentType = currentType.superclass();
9421
		} while ( currentType != null);
9422
9423
		if (interfacesToVisit != null) {
9424
			for (int i = 0; i < nextPosition; i++) {
9425
				ReferenceBinding anInterface = interfacesToVisit[i];
9426
				FieldBinding[] fields = anInterface.availableFields();
9427
				if(fields !=  null) {
9428
					computeAlreadyDefinedName(
9429
						fields,
9430
						scope,
9431
						onlyStaticFields,
9432
						receiverType,
9433
						invocationSite,
9434
						result);
9435
				}
9182
				}
9436
9183
				int searchFor = IJavaSearchConstants.TYPE;
9437
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
9184
				if(this.assistNodeIsClass) {
9438
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9185
					searchFor = IJavaSearchConstants.CLASS;
9439
					int itsLength = itsInterfaces.length;
9186
				} else if(this.assistNodeIsInterface) {
9440
					if (nextPosition + itsLength >= interfacesToVisit.length)
9187
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9441
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9188
				} else if(this.assistNodeIsEnum) {
9442
					nextInterface : for (int a = 0; a < itsLength; a++) {
9189
					searchFor = IJavaSearchConstants.ENUM;
9443
						ReferenceBinding next = itsInterfaces[a];
9190
				} else if(this.assistNodeIsAnnotation) {
9444
						for (int b = 0; b < nextPosition; b++)
9191
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9445
							if (next == interfacesToVisit[b]) continue nextInterface;
9446
						interfacesToVisit[nextPosition++] = next;
9447
					}
9448
				}
9192
				}
9193
				
9194
				checkCancel();
9195
				
9196
				this.foundTypesCount = 0;
9197
				this.nameEnvironment.findTypes(
9198
						token,
9199
						proposeAllMemberTypes,
9200
						this.options.camelCaseMatch,
9201
						searchFor,
9202
						this);
9203
				acceptTypes(scope);
9204
			}
9205
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9206
				
9207
				checkCancel();
9208
				
9209
				this.nameEnvironment.findPackages(token, this);
9449
			}
9210
			}
9450
		}
9211
		}
9451
	}
9212
	}
9452
9213
9453
	private void computeAlreadyDefinedName(
9214
	private void findTypesAndSubpackages(
9454
			FieldBinding[] fields,
9215
		char[] token,
9455
			Scope scope,
9216
		PackageBinding packageBinding,
9456
			boolean onlyStaticFields,
9217
		Scope scope) {
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
9218
9466
			if (onlyStaticFields && !field.isStatic()) continue next;
9219
		boolean proposeType =
9220
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9221
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9467
9222
9468
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
9223
		char[] qualifiedName =
9224
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
9469
9225
9470
			result.add(field.name);
9226
		if (token == null || token.length == 0) {
9227
			int length = qualifiedName.length;
9228
			System.arraycopy(
9229
				qualifiedName,
9230
				0,
9231
				qualifiedName = new char[length + 1],
9232
				0,
9233
				length);
9234
			qualifiedName[length] = '.';
9471
		}
9235
		}
9472
	}
9473
9236
9474
	int computeBaseRelevance(){
9237
		this.qualifiedCompletionToken = qualifiedName;
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
		}
9484
		return 0;
9485
	}
9486
	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
9487
9238
9488
		// default filter
9239
		if (proposeType && this.unitScope != null) {
9489
		this.expectedTypesFilter = SUBTYPE;
9240
			int typeLength = qualifiedName.length;
9490
		this.hasJavaLangObjectAsExpectedType = false;
9241
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9491
9242
9492
		// find types from parent
9243
			for (int i = 0, length = types.length; i < length; i++) {
9493
		if(parent instanceof AbstractVariableDeclaration) {
9244
				
9494
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
9245
				checkCancel();
9495
			TypeBinding binding = variable.type.resolvedType;
9246
				
9496
			if(binding != null) {
9247
				SourceTypeBinding sourceType = types[i];
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
9248
9524
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
9249
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
9525
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
9526
				boolean isStatic = messageSend.receiver.isTypeReference();
9527
9250
9528
				while(binding != null) {
9251
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
9529
					computeExpectedTypesForMessageSend(
9252
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
9530
						binding,
9253
				if (typeLength > qualifiedSourceTypeName.length) continue;
9531
						messageSend.selector,
9254
				if (!(packageBinding == sourceType.getPackage())) continue;
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
9255
9551
			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
9256
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
9257
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
9552
9258
9553
			if(binding != null) {
9259
				if (this.options.checkDeprecation &&
9554
				computeExpectedTypesForAllocationExpression(
9260
						sourceType.isViewedAsDeprecated() &&
9555
					binding,
9261
						!scope.isDefinedInSameUnit(sourceType))
9556
					allocationExpression.arguments,
9262
					continue;
9557
					scope,
9558
					allocationExpression);
9559
			}
9560
		} else if(parent instanceof OperatorExpression) {
9561
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
9562
			if(parent instanceof ConditionalExpression) {
9563
				// for future use
9564
			} else if(parent instanceof InstanceOfExpression) {
9565
				InstanceOfExpression e = (InstanceOfExpression) parent;
9566
				TypeBinding binding = e.expression.resolvedType;
9567
				if(binding != null){
9568
					addExpectedType(binding, scope);
9569
					this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
9570
				}
9571
			} else if(parent instanceof BinaryExpression) {
9572
				BinaryExpression binaryExpression = (BinaryExpression) parent;
9573
				switch(operator) {
9574
					case OperatorIds.EQUAL_EQUAL :
9575
						// expected type is not relevant in this case
9576
						TypeBinding binding = binaryExpression.left.resolvedType;
9577
						if (binding != null) {
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
							}
9616
9263
9264
				int accessibility = IAccessRule.K_ACCESSIBLE;
9265
				if(sourceType.hasRestrictedAccess()) {
9266
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
9267
					if(accessRestriction != null) {
9268
						switch (accessRestriction.getProblemId()) {
9269
							case IProblem.ForbiddenReference:
9270
								if (this.options.checkForbiddenReference) {
9271
									continue;
9272
								}
9273
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
9274
								break;
9275
							case IProblem.DiscouragedReference:
9276
								if (this.options.checkDiscouragedReference) {
9277
									continue;
9278
								}
9279
								accessibility = IAccessRule.K_DISCOURAGED;
9280
								break;
9617
						}
9281
						}
9618
					}
9282
					}
9619
				}
9283
				}
9620
			} else if(parent instanceof UnaryExpression) {
9284
9621
				switch(operator) {
9285
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9622
					case OperatorIds.NOT :
9286
9623
						addExpectedType(TypeBinding.BOOLEAN, scope);
9287
				int relevance = computeBaseRelevance();
9624
						break;
9288
				relevance += computeRelevanceForResolution();
9625
					case OperatorIds.TWIDDLE :
9289
				relevance += computeRelevanceForInterestingProposal();
9626
						addExpectedType(TypeBinding.SHORT, scope);
9290
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
9627
						addExpectedType(TypeBinding.INT, scope);
9291
				relevance += computeRelevanceForExpectingType(sourceType);
9628
						addExpectedType(TypeBinding.LONG, scope);
9292
				relevance += computeRelevanceForQualification(false);
9629
						addExpectedType(TypeBinding.CHAR, scope);
9293
				relevance += computeRelevanceForRestrictions(accessibility);
9630
						addExpectedType(TypeBinding.BYTE, scope);
9294
9631
						break;
9295
				if (sourceType.isAnnotationType()) {
9632
					case OperatorIds.PLUS :
9296
					relevance += computeRelevanceForAnnotation();
9633
					case OperatorIds.MINUS :
9297
				} else if (sourceType.isInterface()) {
9634
					case OperatorIds.PLUS_PLUS :
9298
					relevance += computeRelevanceForInterface();
9635
					case OperatorIds.MINUS_MINUS :
9299
				} else if (sourceType.isClass()) {
9636
						addExpectedType(TypeBinding.SHORT, scope);
9300
					relevance += computeRelevanceForClass();
9637
						addExpectedType(TypeBinding.INT, scope);
9301
					relevance += computeRelevanceForException(sourceType.sourceName);
9638
						addExpectedType(TypeBinding.LONG, scope);
9302
				}
9639
						addExpectedType(TypeBinding.FLOAT, scope);
9303
				this.noProposal = false;
9640
						addExpectedType(TypeBinding.DOUBLE, scope);
9304
				if(proposeType) {
9641
						addExpectedType(TypeBinding.CHAR, scope);
9305
					char[] typeName = sourceType.sourceName();
9642
						addExpectedType(TypeBinding.BYTE, scope);
9306
					createTypeProposal(
9643
						break;
9307
							sourceType,
9308
							typeName,
9309
							IAccessRule.K_ACCESSIBLE,
9310
							typeName,
9311
							relevance,
9312
							null,
9313
							null,
9314
							null,
9315
							false);
9644
				}
9316
				}
9645
			}
9317
			}
9646
		} else if(parent instanceof ArrayReference) {
9318
		}
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
9319
9658
				TypeBinding bound = typeVariables[index].firstBound;
9320
		if(proposeType) {
9659
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9321
			int searchFor = IJavaSearchConstants.TYPE;
9322
			if(this.assistNodeIsClass) {
9323
				searchFor = IJavaSearchConstants.CLASS;
9324
			} else if(this.assistNodeIsInterface) {
9325
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9326
			} else if(this.assistNodeIsEnum) {
9327
				searchFor = IJavaSearchConstants.ENUM;
9328
			} else if(this.assistNodeIsAnnotation) {
9329
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9660
			}
9330
			}
9661
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
9331
			
9662
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
9332
			checkCancel();
9663
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
9333
			
9664
			TypeReference[][] arguments = ref.typeArguments;
9334
			this.foundTypesCount = 0;
9665
			if(typeVariables != null) {
9335
			this.nameEnvironment.findTypes(
9666
				int iLength = arguments == null ? 0 : arguments.length;
9336
					qualifiedName,
9667
				done: for (int i = 0; i < iLength; i++) {
9337
					false,
9668
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
9338
					this.options.camelCaseMatch,
9669
					for (int j = 0; j < jLength; j++) {
9339
					searchFor,
9670
						if(arguments[i][j] == node && typeVariables.length > j) {
9340
					this);
9671
							TypeBinding bound = typeVariables[j].firstBound;
9341
			acceptTypes(scope);
9672
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9342
		}
9673
							break done;
9343
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9344
			this.nameEnvironment.findPackages(qualifiedName, this);
9345
		}
9346
	}
9347
9348
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
9349
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
9350
		for (int i = 0; i < importBindings.length; i++) {
9351
			ImportBinding importBinding = importBindings[i];
9352
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
9353
				Binding binding = importBinding.resolvedImport;
9354
				if(binding != null && binding.isValidBinding()) {
9355
					if(importBinding.onDemand) {
9356
						if((binding.kind() & Binding.TYPE) != 0) {
9357
							this.findMemberTypes(
9358
									token,
9359
									(ReferenceBinding) binding,
9360
									scope,
9361
									scope.enclosingSourceType(),
9362
									true,
9363
									false,
9364
									true,
9365
									true,
9366
									proposeAllMemberTypes,
9367
									null,
9368
									typesFound,
9369
									null,
9370
									null,
9371
									null,
9372
									false);
9674
						}
9373
						}
9675
					}
9374
					} else {
9676
				}
9375
						if ((binding.kind() & Binding.TYPE) != 0) {
9677
			}
9376
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
9678
		} else if(parent instanceof MemberValuePair) {
9377
							int typeLength = token.length;
9679
			MemberValuePair memberValuePair = (MemberValuePair) parent;
9378
9680
			if(memberValuePair.binding != null) {
9379
							if (!typeBinding.isStatic()) continue;
9681
				addExpectedType(memberValuePair.binding.returnType, scope);
9380
9682
			}
9381
							if (typeLength > typeBinding.sourceName.length)	continue;
9683
		} else if (parent instanceof NormalAnnotation) {
9382
9684
			NormalAnnotation annotation = (NormalAnnotation) parent;
9383
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
9685
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
9384
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
9686
			if(memberValuePairs == null || memberValuePairs.length == 0) {
9385
9687
				if(annotation.resolvedType instanceof ReferenceBinding) {
9386
							if (typesFound.contains(typeBinding))  continue;
9688
					MethodBinding[] methodBindings =
9387
9689
						((ReferenceBinding)annotation.resolvedType).availableMethods();
9388
							typesFound.add(typeBinding);
9690
					if (methodBindings != null &&
9389
9691
							methodBindings.length > 0 &&
9390
							if(this.assistNodeIsClass) {
9692
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
9391
								if(!typeBinding.isClass()) continue;
9693
						boolean canBeSingleMemberAnnotation = true;
9392
							} else if(this.assistNodeIsInterface) {
9694
						done : for (int i = 1; i < methodBindings.length; i++) {
9393
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
9695
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
9394
							} else if (this.assistNodeIsAnnotation) {
9696
								canBeSingleMemberAnnotation = false;
9395
								if(!typeBinding.isAnnotationType()) continue;
9396
							}
9397
9398
							int relevance = computeBaseRelevance();
9399
							relevance += computeRelevanceForResolution();
9400
							relevance += computeRelevanceForInterestingProposal();
9401
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
9402
							relevance += computeRelevanceForExpectingType(typeBinding);
9403
							relevance += computeRelevanceForQualification(false);
9404
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
9405
9406
							if (typeBinding.isClass()) {
9407
								relevance += computeRelevanceForClass();
9408
								relevance += computeRelevanceForException(typeBinding.sourceName);
9409
							} else if(typeBinding.isEnum()) {
9410
								relevance += computeRelevanceForEnum();
9411
							} else if(typeBinding.isInterface()) {
9412
								relevance += computeRelevanceForInterface();
9413
							}
9414
9415
							this.noProposal = false;
9416
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9417
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9418
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
9419
								proposal.setSignature(getSignature(typeBinding));
9420
								proposal.setPackageName(typeBinding.qualifiedPackageName());
9421
								proposal.setTypeName(typeBinding.qualifiedSourceName());
9422
								proposal.setCompletion(typeBinding.sourceName());
9423
								proposal.setFlags(typeBinding.modifiers);
9424
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9425
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9426
								proposal.setRelevance(relevance);
9427
								this.requestor.accept(proposal);
9428
								if(DEBUG) {
9429
									this.printDebug(proposal);
9430
								}
9431
							}
9432
						}
9433
					}
9434
				}
9435
			}
9436
		}
9437
	}
9438
9439
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
9440
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
9441
		if (foundNames != null && foundNames.length > 1) {
9442
			int discouragedNamesLength = discouragedNames.length;
9443
			int foundNamesLength = foundNames.length;
9444
			int newLength = discouragedNamesLength + foundNamesLength;
9445
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
9446
			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
9447
		}
9448
		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
9449
	}
9450
9451
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
9452
		final ArrayList proposedNames = new ArrayList();
9453
9454
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9455
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9456
				public void acceptName(char[] name) {
9457
					CompletionEngine.this.acceptUnresolvedName(name);
9458
					proposedNames.add(name);
9459
				}
9460
			};
9461
9462
		ReferenceContext referenceContext = scope.referenceContext();
9463
		if (referenceContext instanceof AbstractMethodDeclaration) {
9464
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9465
9466
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9467
			nameFinder.findAfter(
9468
					this.completionToken,
9469
					md.scope,
9470
					md.scope.classScope(),
9471
					from,
9472
					md.bodyEnd,
9473
					discouragedNames,
9474
					nameRequestor);
9475
		} else if (referenceContext instanceof TypeDeclaration) {
9476
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9477
			FieldDeclaration[] fields = typeDeclaration.fields;
9478
			if (fields != null) {
9479
				done : for (int i = 0; i < fields.length; i++) {
9480
					if (fields[i] instanceof Initializer) {
9481
						Initializer initializer = (Initializer) fields[i];
9482
						if (initializer.block.sourceStart <= from &&
9483
								from < initializer.bodyEnd) {
9484
							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9485
							nameFinder.findAfter(
9486
										this.completionToken,
9487
										typeDeclaration.scope,
9488
										typeDeclaration.scope,
9489
										from,
9490
										initializer.bodyEnd,
9491
										discouragedNames,
9492
										nameRequestor);
9493
							break done;
9494
						}
9495
					}
9496
				}
9497
			}
9498
		}
9499
9500
		int proposedNamesCount = proposedNames.size();
9501
		if (proposedNamesCount > 0) {
9502
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9503
		}
9504
9505
		return null;
9506
	}
9507
9508
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
9509
		final ArrayList proposedNames = new ArrayList();
9510
9511
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9512
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9513
				public void acceptName(char[] name) {
9514
					CompletionEngine.this.acceptUnresolvedName(name);
9515
					proposedNames.add(name);
9516
				}
9517
			};
9518
9519
		BlockScope upperScope = scope;
9520
		while (upperScope.enclosingMethodScope() != null) {
9521
			upperScope = upperScope.enclosingMethodScope();
9522
		}
9523
9524
		ReferenceContext referenceContext = upperScope.referenceContext();
9525
		if (referenceContext instanceof AbstractMethodDeclaration) {
9526
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9527
9528
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9529
			nameFinder.findBefore(
9530
					this.completionToken,
9531
					md.scope,
9532
					md.scope.classScope(),
9533
					md.bodyStart,
9534
					recordTo,
9535
					parseTo,
9536
					discouragedNames,
9537
					nameRequestor);
9538
		} else if (referenceContext instanceof TypeDeclaration) {
9539
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9540
9541
9542
			done : {
9543
				FieldDeclaration[] fields = typeDeclaration.fields;
9544
				if (fields != null) {
9545
					for (int i = 0; i < fields.length; i++) {
9546
						if (fields[i] instanceof Initializer) {
9547
							Initializer initializer = (Initializer) fields[i];
9548
							if (initializer.block.sourceStart <= recordTo &&
9549
									recordTo < initializer.bodyEnd) {
9550
9551
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9552
								nameFinder.findBefore(
9553
										this.completionToken,
9554
										typeDeclaration.scope,
9555
										typeDeclaration.scope,
9556
										initializer.block.sourceStart,
9557
										recordTo,
9558
										parseTo,
9559
										discouragedNames,
9560
										nameRequestor);
9697
								break done;
9561
								break done;
9698
							}
9562
							}
9699
						}
9563
						}
9700
						if (canBeSingleMemberAnnotation) {
9564
					}
9701
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
9565
				}
9702
							addExpectedType(methodBindings[0].returnType, scope);
9566
			}
9567
		}
9568
9569
		int proposedNamesCount = proposedNames.size();
9570
		if (proposedNamesCount > 0) {
9571
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9572
		}
9573
9574
		return null;
9575
	}
9576
9577
	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
9578
		final TypeReference type = variable.type;
9579
		if(type != null &&
9580
				type.resolvedType != null &&
9581
				type.resolvedType.problemId() == ProblemReasons.NoError){
9582
9583
			final ArrayList proposedNames = new ArrayList();
9584
9585
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9586
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9587
					public void acceptName(char[] name) {
9588
						int relevance = computeBaseRelevance();
9589
						relevance += computeRelevanceForInterestingProposal();
9590
						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
9591
						relevance += R_NAME_FIRST_PREFIX;
9592
						relevance += R_NAME_FIRST_SUFFIX;
9593
						relevance += R_NAME_LESS_NEW_CHARACTERS;
9594
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9595
9596
						// accept result
9597
						CompletionEngine.this.noProposal = false;
9598
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9599
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9600
							proposal.setSignature(getSignature(type.resolvedType));
9601
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
9602
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
9603
							proposal.setName(name);
9604
							proposal.setCompletion(name);
9605
							//proposal.setFlags(Flags.AccDefault);
9606
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9607
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9608
							proposal.setRelevance(relevance);
9609
							CompletionEngine.this.requestor.accept(proposal);
9610
							if(DEBUG) {
9611
								CompletionEngine.this.printDebug(proposal);
9612
							}
9613
						}
9614
						proposedNames.add(name);
9615
					}
9616
				};
9617
9618
			ReferenceContext referenceContext = scope.referenceContext();
9619
			if (referenceContext instanceof AbstractMethodDeclaration) {
9620
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9621
9622
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9623
				nameFinder.find(
9624
						this.completionToken,
9625
						md,
9626
						variable.declarationSourceEnd + 1,
9627
						discouragedNames,
9628
						nameRequestor);
9629
			} else if (referenceContext instanceof TypeDeclaration) {
9630
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9631
				FieldDeclaration[] fields = typeDeclaration.fields;
9632
				if (fields != null) {
9633
					done : for (int i = 0; i < fields.length; i++) {
9634
						if (fields[i] instanceof Initializer) {
9635
							Initializer initializer = (Initializer) fields[i];
9636
							if (initializer.bodyStart <= variable.sourceStart &&
9637
									variable.sourceStart < initializer.bodyEnd) {
9638
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9639
								nameFinder.find(
9640
										this.completionToken,
9641
										initializer,
9642
										typeDeclaration.scope,
9643
										variable.declarationSourceEnd + 1,
9644
										discouragedNames,
9645
										nameRequestor);
9646
								break done;
9647
							}
9648
						}
9649
					}
9650
				}
9651
			}
9652
9653
			int proposedNamesCount = proposedNames.size();
9654
			if (proposedNamesCount > 0) {
9655
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9656
			}
9657
		}
9658
9659
		return null;
9660
	}
9661
9662
	private void findVariableName(
9663
			char[] token,
9664
			char[] qualifiedPackageName,
9665
			char[] qualifiedSourceName,
9666
			char[] sourceName,
9667
			final TypeBinding typeBinding,
9668
			char[][] discouragedNames,
9669
			final char[][] forbiddenNames,
9670
			boolean forCollection,
9671
			int dim,
9672
			int kind,
9673
			int modifiers){
9674
9675
		if(sourceName == null || sourceName.length == 0)
9676
			return;
9677
9678
		// compute variable name for non base type
9679
		final char[] displayName;
9680
		if (!forCollection) {
9681
			if (dim > 0){
9682
				int l = qualifiedSourceName.length;
9683
				displayName = new char[l+(2*dim)];
9684
				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
9685
				for(int i = 0; i < dim; i++){
9686
					displayName[l+(i*2)] = '[';
9687
					displayName[l+(i*2)+1] = ']';
9688
				}
9689
			} else {
9690
				displayName = qualifiedSourceName;
9691
			}
9692
		} else {
9693
			displayName = typeBinding.qualifiedSourceName();
9694
		}
9695
9696
		final char[] t = token;
9697
		final char[] q = qualifiedPackageName;
9698
		INamingRequestor namingRequestor = new INamingRequestor() {
9699
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
9700
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
9701
				for (int i = 0; i < l; i++) {
9702
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
9703
				}
9704
9705
				if (CharOperation.prefixEquals(t, name, false)) {
9706
					int relevance = computeBaseRelevance();
9707
					relevance += computeRelevanceForInterestingProposal();
9708
					relevance += computeRelevanceForCaseMatching(t, name);
9709
					relevance += prefixAndSuffixRelevance;
9710
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
9711
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9712
9713
					// accept result
9714
					CompletionEngine.this.noProposal = false;
9715
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9716
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9717
						proposal.setSignature(getSignature(typeBinding));
9718
						proposal.setPackageName(q);
9719
						proposal.setTypeName(displayName);
9720
						proposal.setName(name);
9721
						proposal.setCompletion(name);
9722
						//proposal.setFlags(Flags.AccDefault);
9723
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9724
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9725
						proposal.setRelevance(relevance);
9726
						CompletionEngine.this.requestor.accept(proposal);
9727
						if(DEBUG) {
9728
							CompletionEngine.this.printDebug(proposal);
9729
						}
9730
					}
9731
				}
9732
			}
9733
9734
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
9735
				accept(name, 0, reusedCharacters);
9736
			}
9737
9738
			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
9739
				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
9740
			}
9741
9742
			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
9743
				accept(
9744
						name,
9745
						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
9746
						reusedCharacters);
9747
			}
9748
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
9749
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
9750
			}
9751
		};
9752
9753
		switch (kind) {
9754
			case FIELD :
9755
				InternalNamingConventions.suggestFieldNames(
9756
					this.javaProject,
9757
					qualifiedPackageName,
9758
					qualifiedSourceName,
9759
					dim,
9760
					modifiers,
9761
					token,
9762
					discouragedNames,
9763
					namingRequestor);
9764
				break;
9765
			case LOCAL :
9766
				InternalNamingConventions.suggestLocalVariableNames(
9767
					this.javaProject,
9768
					qualifiedPackageName,
9769
					qualifiedSourceName,
9770
					dim,
9771
					token,
9772
					discouragedNames,
9773
					namingRequestor);
9774
				break;
9775
			case ARGUMENT :
9776
				InternalNamingConventions.suggestArgumentNames(
9777
					this.javaProject,
9778
					qualifiedPackageName,
9779
					qualifiedSourceName,
9780
					dim,
9781
					token,
9782
					discouragedNames,
9783
					namingRequestor);
9784
				break;
9785
		}
9786
	}
9787
9788
	// Helper method for private void findVariableNames(char[] name, TypeReference type )
9789
	private void findVariableName(
9790
			char[] token,
9791
			char[] qualifiedPackageName,
9792
			char[] qualifiedSourceName,
9793
			char[] sourceName,
9794
			final TypeBinding typeBinding,
9795
			char[][] discouragedNames,
9796
			final char[][] forbiddenNames,
9797
			int dim,
9798
			int kind,
9799
			int modifiers){
9800
		findVariableName(
9801
				token,
9802
				qualifiedPackageName,
9803
				qualifiedSourceName,
9804
				sourceName,
9805
				typeBinding,
9806
				discouragedNames,
9807
				forbiddenNames,
9808
				false,
9809
				dim,
9810
				kind,
9811
				modifiers);
9812
	}
9813
	private void findVariableNameForCollection(
9814
			char[] token,
9815
			char[] qualifiedPackageName,
9816
			char[] qualifiedSourceName,
9817
			char[] sourceName,
9818
			final TypeBinding typeBinding,
9819
			char[][] discouragedNames,
9820
			final char[][] forbiddenNames,
9821
			int kind,
9822
			int modifiers){
9823
9824
		findVariableName(
9825
				token,
9826
				qualifiedPackageName,
9827
				qualifiedSourceName,
9828
				sourceName,
9829
				typeBinding,
9830
				discouragedNames,
9831
				forbiddenNames,
9832
				false,
9833
				1,
9834
				kind,
9835
				modifiers);
9836
	}
9837
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
9838
		if(type != null &&
9839
			type.resolvedType != null) {
9840
			TypeBinding tb = type.resolvedType;
9841
9842
			if (tb.problemId() == ProblemReasons.NoError &&
9843
					tb != Scope.getBaseType(VOID)) {
9844
				findVariableName(
9845
					name,
9846
					tb.leafComponentType().qualifiedPackageName(),
9847
					tb.leafComponentType().qualifiedSourceName(),
9848
					tb.leafComponentType().sourceName(),
9849
					tb,
9850
					discouragedNames,
9851
					forbiddenNames,
9852
					type.dimensions(),
9853
					kind,
9854
					modifiers);
9855
				
9856
				if (tb.isParameterizedType() &&
9857
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
9858
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
9859
					TypeBinding[] arguments = ptb.arguments;
9860
					if (arguments != null && arguments.length == 1) {
9861
						TypeBinding argument = arguments[0];
9862
						findVariableNameForCollection(
9863
							name,
9864
							argument.leafComponentType().qualifiedPackageName(),
9865
							argument.leafComponentType().qualifiedSourceName(),
9866
							argument.leafComponentType().sourceName(),
9867
							tb,
9868
							discouragedNames,
9869
							forbiddenNames,
9870
							kind,
9871
							modifiers);
9872
					}
9873
				}
9874
			}
9875
		}
9876
9877
	}
9878
	private void findVariablesAndMethods(
9879
		char[] token,
9880
		Scope scope,
9881
		InvocationSite invocationSite,
9882
		Scope invocationScope,
9883
		boolean insideTypeAnnotation,
9884
		boolean insideAnnotationAttribute) {
9885
9886
		if (token == null)
9887
			return;
9888
9889
		// Should local variables hide fields from the receiver type or any of its enclosing types?
9890
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
9891
9892
		boolean staticsOnly = false;
9893
		// need to know if we're in a static context (or inside a constructor)
9894
		int tokenLength = token.length;
9895
9896
		ObjectVector localsFound = new ObjectVector();
9897
		ObjectVector fieldsFound = new ObjectVector();
9898
		ObjectVector methodsFound = new ObjectVector();
9899
9900
		Scope currentScope = scope;
9901
9902
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9903
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9904
9905
				switch (currentScope.kind) {
9906
9907
					case Scope.METHOD_SCOPE :
9908
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9909
						MethodScope methodScope = (MethodScope) currentScope;
9910
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9911
9912
					//$FALL-THROUGH$
9913
					case Scope.BLOCK_SCOPE :
9914
						BlockScope blockScope = (BlockScope) currentScope;
9915
9916
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9917
							LocalVariableBinding local = blockScope.locals[i];
9918
9919
							if (local == null)
9920
								break next;
9921
9922
							if (tokenLength > local.name.length)
9923
								continue next;
9924
9925
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
9926
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
9927
								continue next;
9928
9929
							if (local.isSecret())
9930
								continue next;
9931
9932
							for (int f = 0; f < localsFound.size; f++) {
9933
								LocalVariableBinding otherLocal =
9934
									(LocalVariableBinding) localsFound.elementAt(f);
9935
								if (CharOperation.equals(otherLocal.name, local.name, true))
9936
									continue next;
9937
							}
9938
							localsFound.add(local);
9939
9940
							int relevance = computeBaseRelevance();
9941
							relevance += computeRelevanceForResolution();
9942
							relevance += computeRelevanceForInterestingProposal(local);
9943
							relevance += computeRelevanceForCaseMatching(token, local.name);
9944
							relevance += computeRelevanceForExpectingType(local.type);
9945
							relevance += computeRelevanceForEnumConstant(local.type);
9946
							relevance += computeRelevanceForQualification(false);
9947
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
9948
							this.noProposal = false;
9949
							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9950
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
9951
								proposal.setSignature(
9952
									local.type == null
9953
									? createTypeSignature(
9954
											CharOperation.NO_CHAR,
9955
											local.declaration.type.toString().toCharArray())
9956
									: getSignature(local.type));
9957
								if(local.type == null) {
9958
									//proposal.setPackageName(null);
9959
									proposal.setTypeName(local.declaration.type.toString().toCharArray());
9960
								} else {
9961
									proposal.setPackageName(local.type.qualifiedPackageName());
9962
									proposal.setTypeName(local.type.qualifiedSourceName());
9963
								}
9964
								proposal.setName(local.name);
9965
								proposal.setCompletion(local.name);
9966
								proposal.setFlags(local.modifiers);
9967
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9968
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9969
								proposal.setRelevance(relevance);
9970
								this.requestor.accept(proposal);
9971
								if(DEBUG) {
9972
									this.printDebug(proposal);
9973
								}
9974
							}
9703
						}
9975
						}
9704
					}
9976
						break;
9705
				}
9706
			}
9707
		} else if (parent instanceof TryStatement) {
9708
			boolean isException = false;
9709
			if (node instanceof CompletionOnSingleTypeReference) {
9710
				isException = ((CompletionOnSingleTypeReference)node).isException();
9711
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
9712
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
9713
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
9714
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
9715
			}
9716
			if (isException) {
9717
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
9718
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
9719
				if (bindings != null && bindings.length > 0) {
9720
					for (int i = 0; i < bindings.length; i++) {
9721
						addExpectedType(bindings[i], scope);
9722
					}
9723
					this.expectedTypesFilter = SUPERTYPE;
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
9977
9733
		// Expected types for javadoc
9978
					case Scope.COMPILATION_UNIT_SCOPE :
9734
		} else if (parent instanceof Javadoc) {
9979
						break done1;
9735
			if (scope.kind == Scope.METHOD_SCOPE) {
9736
				MethodScope methodScope = (MethodScope) scope;
9737
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
9738
				if (methodDecl != null && methodDecl.binding != null) {
9739
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
9740
					if (exceptions != null) {
9741
						for (int i = 0; i < exceptions.length; i++) {
9742
							addExpectedType(exceptions[i], scope);
9743
						}
9744
					}
9745
				}
9980
				}
9981
				currentScope = currentScope.parent;
9746
			}
9982
			}
9747
		}
9983
		}
9984
		
9985
		checkCancel();
9748
9986
9749
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
9987
		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
9750
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
9988
		boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
9751
		}
9752
	}
9753
9754
	private void computeExpectedTypesForAllocationExpression(
9755
		ReferenceBinding binding,
9756
		Expression[] arguments,
9757
		Scope scope,
9758
		InvocationSite invocationSite) {
9759
9760
		MethodBinding[] methods = binding.availableMethods();
9761
		nextMethod : for (int i = 0; i < methods.length; i++) {
9762
			MethodBinding method = methods[i];
9763
9764
			if (!method.isConstructor()) continue nextMethod;
9765
9766
			if (method.isSynthetic()) continue nextMethod;
9767
9989
9768
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
9990
		staticsOnly = false;
9991
		currentScope = scope;
9769
9992
9770
			TypeBinding[] parameters = method.parameters;
9993
		if(proposeField || proposeMethod) {
9771
			if(parameters.length < arguments.length)
9994
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9772
				continue nextMethod;
9773
9995
9774
			int length = arguments.length - 1;
9996
				switch (currentScope.kind) {
9997
					case Scope.METHOD_SCOPE :
9998
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9999
						MethodScope methodScope = (MethodScope) currentScope;
10000
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
10001
						break;
10002
					case Scope.CLASS_SCOPE :
10003
						ClassScope classScope = (ClassScope) currentScope;
10004
						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
10005
						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
10006
											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
10007
											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
10008
											break done;
10009
										} else { */
10010
						if(!insideTypeAnnotation) {
10011
							if(proposeField) {
10012
								findFields(
10013
									token,
10014
									enclosingType,
10015
									classScope,
10016
									fieldsFound,
10017
									localsFound,
10018
									staticsOnly,
10019
									invocationSite,
10020
									invocationScope,
10021
									true,
10022
									true,
10023
									null,
10024
									null,
10025
									null,
10026
									false,
10027
									null,
10028
									-1,
10029
									-1);
10030
							}
10031
							if(proposeMethod && !insideAnnotationAttribute) {
10032
								findMethods(
10033
									token,
10034
									null,
10035
									null,
10036
									enclosingType,
10037
									classScope,
10038
									methodsFound,
10039
									staticsOnly,
10040
									false,
10041
									invocationSite,
10042
									invocationScope,
10043
									true,
10044
									false,
10045
									true,
10046
									null,
10047
									null,
10048
									null,
10049
									false,
10050
									null,
10051
									-1,
10052
									-1);
10053
							}
10054
						}
10055
						staticsOnly |= enclosingType.isStatic();
10056
						insideTypeAnnotation = false;
10057
						//				}
10058
						break;
9775
10059
9776
			for (int j = 0; j < length; j++) {
10060
					case Scope.COMPILATION_UNIT_SCOPE :
9777
				Expression argument = arguments[j];
10061
						break done2;
9778
				TypeBinding argType = argument.resolvedType;
10062
				}
9779
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
10063
				currentScope = currentScope.parent;
9780
					continue nextMethod;
9781
			}
10064
			}
10065
			
10066
			checkCancel();
10067
			
10068
			findFieldsAndMethodsFromStaticImports(
10069
					token,
10070
					scope,
10071
					invocationSite,
10072
					invocationScope,
10073
					false,
10074
					insideAnnotationAttribute,
10075
					localsFound,
10076
					fieldsFound,
10077
					methodsFound,
10078
					proposeField,
10079
					proposeMethod);
9782
10080
9783
			TypeBinding expectedType = method.parameters[arguments.length - 1];
10081
			if (this.assistNodeInJavadoc == 0) {
9784
			if(expectedType != null) {
10082
				
9785
				addExpectedType(expectedType, scope);
10083
				checkCancel();
10084
				
10085
				// search in favorites import
10086
				findFieldsAndMethodsFromFavorites(
10087
						token,
10088
						scope,
10089
						invocationSite,
10090
						invocationScope,
10091
						localsFound,
10092
						fieldsFound,
10093
						methodsFound);
9786
			}
10094
			}
10095
			
10096
			checkCancel();
10097
			
10098
			findEnumConstantsFromExpectedTypes(
10099
					token,
10100
					invocationScope,
10101
					fieldsFound);
9787
		}
10102
		}
9788
	}
10103
	}
9789
10104
9790
	private void computeExpectedTypesForMessageSendForInterface(
10105
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
9791
		ReferenceBinding binding,
10106
		char[] result = null;
9792
		char[] selector,
10107
		StringBuffer sig = new StringBuffer(10);
9793
		Expression[] arguments,
10108
		if (!referenceBinding.isMemberType()) {
9794
		ReferenceBinding receiverType,
10109
			char[] typeSig = referenceBinding.genericTypeSignature();
9795
		Scope scope,
10110
			sig.append(typeSig, 0, typeSig.length);
9796
		InvocationSite invocationSite,
10111
		} else if (!this.insideQualifiedReference) {
9797
		boolean isStatic) {
10112
			if (referenceBinding.isStatic()) {
10113
				char[] typeSig = referenceBinding.signature();
10114
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9798
10115
9799
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
10116
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9800
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
10117
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9801
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
10118
				    sig.append(Signature.C_GENERIC_START);
9802
			int nextPosition = interfacesToVisit.length;
10119
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
10120
				        sig.append(typeVariables[i].genericTypeSignature());
10121
				    }
10122
				    sig.append(Signature.C_GENERIC_END);
10123
				}
10124
				sig.append(Signature.C_SEMICOLON);
10125
			} else {
10126
				char[] typeSig = referenceBinding.genericTypeSignature();
10127
				sig.append(typeSig, 0, typeSig.length);
10128
			}
10129
		} else {
10130
			ReferenceBinding enclosingType = referenceBinding.enclosingType();
10131
			if (enclosingType.isParameterizedType()) {
10132
				char[] typeSig = referenceBinding.genericTypeSignature();
10133
				sig.append(typeSig, 0, typeSig.length-1);
9803
10134
9804
			for (int i = 0; i < nextPosition; i++) {
10135
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9805
				ReferenceBinding currentType = interfacesToVisit[i];
10136
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9806
				computeExpectedTypesForMessageSend(
10137
				    sig.append(Signature.C_GENERIC_START);
9807
					currentType,
10138
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9808
					selector,
10139
				        sig.append(typeVariables[i].genericTypeSignature());
9809
					arguments,
10140
				    }
9810
					receiverType,
10141
				    sig.append(Signature.C_GENERIC_END);
9811
					scope,
10142
				}
9812
					invocationSite,
10143
			} else {
9813
					isStatic);
10144
				char[] typeSig = referenceBinding.signature();
10145
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9814
10146
9815
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
10147
				if (referenceBinding.isStatic()) {
9816
					int itsLength = itsInterfaces.length;
10148
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9817
					if (nextPosition + itsLength >= interfacesToVisit.length)
10149
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9818
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
10150
					    sig.append(Signature.C_GENERIC_START);
9819
					nextInterface : for (int a = 0; a < itsLength; a++) {
10151
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
9820
						ReferenceBinding next = itsInterfaces[a];
10152
					        sig.append(typeVariables[i].genericTypeSignature());
9821
						for (int b = 0; b < nextPosition; b++)
10153
					    }
9822
							if (next == interfacesToVisit[b]) continue nextInterface;
10154
					    sig.append(Signature.C_GENERIC_END);
9823
						interfacesToVisit[nextPosition++] = next;
9824
					}
10155
					}
9825
				}
10156
				}
9826
			}
10157
			}
10158
			sig.append(Signature.C_SEMICOLON);
9827
		}
10159
		}
10160
		int sigLength = sig.length();
10161
		result = new char[sigLength];
10162
		sig.getChars(0, sigLength, result, 0);
10163
		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
10164
		return result;
9828
	}
10165
	}
9829
10166
9830
	private void computeExpectedTypesForMessageSend(
10167
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
9831
		ReferenceBinding binding,
10168
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
9832
		char[] selector,
9833
		Expression[] arguments,
9834
		ReferenceBinding receiverType,
9835
		Scope scope,
9836
		InvocationSite invocationSite,
9837
		boolean isStatic) {
9838
10169
9839
		MethodBinding[] methods = binding.availableMethods();
10170
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
9840
		nextMethod : for (int i = 0; i < methods.length; i++) {
9841
			MethodBinding method = methods[i];
9842
10171
9843
			if (method.isSynthetic()) continue nextMethod;
10172
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
9844
10173
9845
			if (method.isDefaultAbstract())	continue nextMethod;
10174
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
9846
10175
9847
			if (method.isConstructor()) continue nextMethod;
10176
		int count = 0;
10177
		next : for (int i = 0; i < favoriteReferences.length; i++) {
10178
			String favoriteReference = favoriteReferences[i];
9848
10179
9849
			if (isStatic && !method.isStatic()) continue nextMethod;
10180
			int length;
10181
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
9850
10182
9851
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
10183
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
9852
10184
9853
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
10185
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
10186
			if (onDemand) {
10187
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
10188
			}
9854
10189
9855
			TypeBinding[] parameters = method.parameters;
10190
			// remove duplicate and conflicting
9856
			if(parameters.length < arguments.length)
10191
			for (int j = 0; j < count; j++) {
9857
				continue nextMethod;
10192
				ImportReference f = resolvedImports[j].reference;
9858
10193
9859
			int length = arguments.length - 1;
10194
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
9860
10195
9861
			for (int j = 0; j < length; j++) {
10196
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
9862
				Expression argument = arguments[j];
10197
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
9863
				TypeBinding argType = argument.resolvedType;
10198
						continue next;
9864
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
10199
				}
9865
					continue nextMethod;
9866
			}
10200
			}
9867
10201
9868
			TypeBinding expectedType = method.parameters[arguments.length - 1];
10202
			boolean isStatic = true;
9869
			if(expectedType != null) {
10203
9870
				addExpectedType(expectedType, scope);
10204
			ImportReference importReference =
10205
				new ImportReference(
10206
						compoundName,
10207
						new long[compoundName.length],
10208
						onDemand,
10209
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
10210
10211
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
10212
10213
			if (!importBinding.isValidBinding()) {
10214
				continue next;
9871
			}
10215
			}
9872
		}
9873
	}
9874
	private void addExpectedType(TypeBinding type, Scope scope){
9875
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
9876
10216
9877
		// do not add twice the same type
10217
			if (importBinding instanceof PackageBinding) {
9878
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
10218
				continue next;
9879
			if (this.expectedTypes[i] == type) return;
10219
			}
10220
10221
			resolvedImports[count++] =
10222
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
9880
		}
10223
		}
9881
10224
9882
		int length = this.expectedTypes.length;
10225
		if (resolvedImports.length > count)
9883
		if (++this.expectedTypesPtr >= length)
10226
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
9884
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
9885
		this.expectedTypes[this.expectedTypesPtr] = type;
9886
10227
9887
		if(type == scope.getJavaLangObject()) {
10228
		return this.favoriteReferenceBindings = resolvedImports;
9888
			this.hasJavaLangObjectAsExpectedType = true;
9889
		}
9890
	}
10229
	}
9891
	private void addForbiddenBindings(Binding binding){
9892
		if (binding == null) return;
9893
10230
9894
		int length = this.forbbidenBindings.length;
10231
	public AssistParser getParser() {
9895
		if (++this.forbbidenBindingsPtr >= length)
9896
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
9897
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
9898
	}
9899
	private void addUninterestingBindings(Binding binding){
9900
		if (binding == null) return;
9901
10232
9902
		int length = this.uninterestingBindings.length;
10233
		return this.parser;
9903
		if (++this.uninterestingBindingsPtr >= length)
9904
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
9905
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
9906
	}
10234
	}
9907
10235
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
9908
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
10236
		if (this.targetedElement == TagBits.AnnotationForPackage) {
9909
		this.forbbidenBindingsFilter = NONE;
10237
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9910
		if(scope instanceof ClassScope) {
10238
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
9911
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
10239
				return false;
9912
			if(typeDeclaration.superclass == astNode) {
9913
				addForbiddenBindings(typeDeclaration.binding);
9914
				return scope.parent;
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
				}
9923
			}
10240
			}
9924
		} else {
10241
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
9925
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
10242
			if (scope.parent != null &&
9926
				boolean isException = false;
10243
					scope.parent.parent != null &&
9927
				if (astNode instanceof CompletionOnSingleTypeReference) {
10244
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
9928
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
10245
					scope.parent.parent instanceof CompilationUnitScope) {
9929
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
10246
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9930
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
10247
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
9931
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
10248
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
9932
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
10249
						return false;
9933
				}
10250
					}
9934
				if (isException) {
10251
				} else {
9935
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
10252
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
9936
					int length = catchArguments == null ? 0 : catchArguments.length;
10253
						return false;
9937
					for (int i = 0; i < length; i++) {
9938
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
9939
						if (caughtException != null) {
9940
							addForbiddenBindings(caughtException);
9941
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
9942
						}
9943
					}
10254
					}
9944
					this.forbbidenBindingsFilter = SUBTYPE;
9945
				}
10255
				}
9946
			}
10256
			}
9947
		}
10257
		}
9948
//		else if(scope instanceof MethodScope) {
10258
		return true;
9949
//			MethodScope methodScope = (MethodScope) scope;
9950
//			if(methodScope.insideTypeAnnotation) {
9951
//				return methodScope.parent.parent;
9952
//			}
9953
//		}
9954
		return scope;
9955
	}
9956
	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
9957
9958
		StringBuffer completion = new StringBuffer(10);
9959
9960
		if (isStatic) {
9961
			completion.append(declarationType.sourceName());
9962
9963
		} else if (declarationType == invocationType) {
9964
			completion.append(THIS);
9965
9966
		} else {
9967
9968
			if (!declarationType.isNestedType()) {
9969
9970
				completion.append(declarationType.sourceName());
9971
				completion.append('.');
9972
				completion.append(THIS);
9973
9974
			} else if (!declarationType.isAnonymousType()) {
9975
9976
				completion.append(declarationType.sourceName());
9977
				completion.append('.');
9978
				completion.append(THIS);
9979
9980
			}
9981
		}
9982
9983
		return completion.toString().toCharArray();
9984
	}
10259
	}
9985
10260
	/**
9986
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10261
	 * Returns completion string inserted inside a specified inline tag.
9987
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10262
	 * @param completionName
9988
			int relevance = computeBaseRelevance();
10263
	 * @return char[] Completion text inclunding specified inline tag
9989
			relevance += computeRelevanceForResolution();
10264
	 */
9990
			relevance += computeRelevanceForInterestingProposal();
10265
	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
9991
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
10266
		int tagLength= inlineTag.length;
9992
10267
		int completionLength = completionName.length;
9993
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10268
		int inlineLength = 2+tagLength+1+completionLength+1;
9994
			proposal.setDeclarationSignature(getSignature(reference));
10269
		char[] inlineCompletion = new char[inlineLength];
9995
			proposal.setSignature(
10270
		inlineCompletion[0] = '{';
9996
					createMethodSignature(
10271
		inlineCompletion[1] = '@';
9997
							CharOperation.NO_CHAR_CHAR,
10272
		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
9998
							CharOperation.NO_CHAR_CHAR,
10273
		inlineCompletion[tagLength+2] = ' ';
9999
							CharOperation.NO_CHAR,
10274
		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
10000
							VOID));
10275
		// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
10001
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
10276
		//inlineCompletion[inlineLength-2] = ' ';
10002
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10277
		inlineCompletion[inlineLength-1] = '}';
10003
10278
		return inlineCompletion;
10004
			//proposal.setPackageName(null);
10005
			proposal.setTypeName(VOID);
10006
			proposal.setName(token);
10007
			//proposal.setParameterPackageNames(null);
10008
			//proposal.setParameterTypeNames(null);
10009
			//proposal.setPackageName(null);
10010
			proposal.setCompletion(token);
10011
			proposal.setFlags(Flags.AccPublic);
10012
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10013
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10014
			proposal.setRelevance(relevance);
10015
			this.requestor.accept(proposal);
10016
			if(DEBUG) {
10017
				this.printDebug(proposal);
10018
			}
10019
		}
10020
	}
10279
	}
10021
	private boolean isForbidden(Binding binding) {
10280
	private boolean isForbidden(Binding binding) {
10022
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
10281
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
Lines 10033-10038 Link Here
10033
		}
10292
		}
10034
		return false;
10293
		return false;
10035
	}
10294
	}
10295
10296
	private boolean isIgnored(int kind) {
10297
		return this.requestor.isIgnored(kind);
10298
	}
10299
	private boolean isIgnored(int kind, boolean missingTypes) {
10300
		return this.requestor.isIgnored(kind) ||
10301
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
10302
	}
10303
10304
	private boolean isIgnored(int kind, int requiredProposalKind) {
10305
		return this.requestor.isIgnored(kind) ||
10306
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
10307
	}
10036
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10308
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10037
10309
10038
		if(parent instanceof ParameterizedSingleTypeReference) {
10310
		if(parent instanceof ParameterizedSingleTypeReference) {
Lines 10112-10371 Link Here
10112
		}
10384
		}
10113
		return true;
10385
		return true;
10114
	}
10386
	}
10115
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
10387
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
10116
		return Signature.createCharArrayTypeSignature(
10388
		StringBuffer prefix = new StringBuffer();
10117
				CharOperation.concat(
10389
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
10118
						qualifiedPackageName,
10390
		if(isStatic) {
10119
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
10391
			prefix.append("static "); //$NON-NLS-1$
10120
	}
10121
	public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
10122
		char[] name = new char[qualifiedTypeName.length];
10123
		System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
10124
10125
		int depth = 0;
10126
		int length = name.length;
10127
		for (int i = length -1; i >= 0; i--) {
10128
			switch (name[i]) {
10129
				case '.':
10130
					if (depth == 0 && name[i - 1] != '>') {
10131
						name[i] = '$';
10132
					}
10133
					break;
10134
				case '<':
10135
					depth--;
10136
					break;
10137
				case '>':
10138
					depth++;
10139
					break;
10140
			}
10141
		}
10142
		return Signature.createCharArrayTypeSignature(
10143
				CharOperation.concat(
10144
						qualifiedPackageName,
10145
						name, '.'), true);
10146
	}
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
		}
10392
		}
10280
10393
		prefix.append("{\n"); //$NON-NLS-1$
10281
		// Create javadoc text proposal if necessary
10394
		for (int i = 0; i < localVariableTypeNames.length; i++) {
10282
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10395
			ASTNode.printModifiers(localVariableModifiers[i], prefix);
10283
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10396
			prefix.append(' ');
10284
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10397
			prefix.append(localVariableTypeNames[i]);
10285
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10398
			prefix.append(' ');
10286
			proposal.completionEngine = this;
10399
			prefix.append(localVariableNames[i]);
10287
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
10400
			prefix.append(';');
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
		}
10401
		}
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
10402
10310
		// Create standard type proposal
10403
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
10311
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10404
		this.offset = prefix.length();
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
10405
10328
		// Create javadoc text proposal if necessary
10406
		String encoding = this.compilerOptions.defaultEncoding;
10329
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10407
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
10330
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10408
			fakeSource,
10331
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10409
			null,
10332
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10410
			"FakeType.java", //$NON-NLS-1$
10333
			proposal.completionEngine = this;
10411
			encoding);
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
10412
10348
	/**
10413
		this.actualCompletionPosition = prefix.length() + position - 1;
10349
	 * Returns completion string inserted inside a specified inline tag.
10414
10350
	 * @param completionName
10415
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
10351
	 * @return char[] Completion text inclunding specified inline tag
10416
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
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
10417
10418
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
10419
10420
		return (Initializer)fakeAST.types[0].fields[0];
10421
	}
10369
	protected void printDebug(CategorizedProblem error) {
10422
	protected void printDebug(CategorizedProblem error) {
10370
		if(CompletionEngine.DEBUG) {
10423
		if(CompletionEngine.DEBUG) {
10371
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
10424
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
Lines 10373-10390 Link Here
10373
			System.out.println(")"); //$NON-NLS-1$
10426
			System.out.println(")"); //$NON-NLS-1$
10374
		}
10427
		}
10375
	}
10428
	}
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){
10429
	protected void printDebug(CompletionProposal proposal){
10384
		StringBuffer buffer = new StringBuffer();
10430
		StringBuffer buffer = new StringBuffer();
10385
		printDebug(proposal, 0, buffer);
10431
		printDebug(proposal, 0, buffer);
10386
		System.out.println(buffer.toString());
10432
		System.out.println(buffer.toString());
10387
	}
10433
	}
10434
10388
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10435
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10389
		printDebugTab(tab, buffer);
10436
		printDebugTab(tab, buffer);
10390
		buffer.append("COMPLETION - "); //$NON-NLS-1$
10437
		buffer.append("COMPLETION - "); //$NON-NLS-1$
Lines 10509-10550 Link Here
10509
		buffer.append("}\n");//$NON-NLS-1$
10556
		buffer.append("}\n");//$NON-NLS-1$
10510
	}
10557
	}
10511
10558
10512
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10559
	private void printDebugTab(int tab, StringBuffer buffer) {
10513
		char[][] substituedParameterNames = new char[typeVariables.length][];
10560
		for (int i = 0; i < tab; i++) {
10561
			buffer.append('\t');
10562
		}
10563
	}
10514
10564
10515
		for (int i = 0; i < substituedParameterNames.length; i++) {
10565
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10516
			substituedParameterNames[i] = typeVariables[i].sourceName;
10566
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10567
			int relevance = computeBaseRelevance();
10568
			relevance += computeRelevanceForResolution();
10569
			relevance += computeRelevanceForInterestingProposal();
10570
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
10571
10572
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10573
			proposal.setDeclarationSignature(getSignature(reference));
10574
			proposal.setSignature(
10575
					createMethodSignature(
10576
							CharOperation.NO_CHAR_CHAR,
10577
							CharOperation.NO_CHAR_CHAR,
10578
							CharOperation.NO_CHAR,
10579
							VOID));
10580
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
10581
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10582
10583
			//proposal.setPackageName(null);
10584
			proposal.setTypeName(VOID);
10585
			proposal.setName(token);
10586
			//proposal.setParameterPackageNames(null);
10587
			//proposal.setParameterTypeNames(null);
10588
			//proposal.setPackageName(null);
10589
			proposal.setCompletion(token);
10590
			proposal.setFlags(Flags.AccPublic);
10591
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10592
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10593
			proposal.setRelevance(relevance);
10594
			this.requestor.accept(proposal);
10595
			if(DEBUG) {
10596
				this.printDebug(proposal);
10597
			}
10517
		}
10598
		}
10599
	}
10518
10600
10519
		boolean foundConflicts = false;
10601
	private void proposeType(
10602
			char[] packageName,
10603
			char[] simpleTypeName,
10604
			int modifiers,
10605
			int accessibility,
10606
			char[] typeName,
10607
			char[] fullyQualifiedName,
10608
			boolean isQualified,
10609
			Scope scope) {
10610
		char[] completionName = fullyQualifiedName;
10611
		if(isQualified) {
10612
			if (packageName == null || packageName.length == 0)
10613
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
10614
					return; // ignore types from the default package from outside it
10615
		} else {
10616
			completionName = simpleTypeName;
10617
		}
10520
10618
10521
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10619
		TypeBinding guessedType = null;
10522
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10620
		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
10523
			char[] methodParameterName = typeVariableBinding.sourceName;
10621
				this.assistNodeIsAnnotation &&
10622
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
10623
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
10524
10624
10525
			for (int j = 0; j < excludedNames.length; j++) {
10625
			TypeReference ref;
10526
				char[] typeParameterName = excludedNames[j];
10626
			if (cn.length == 1) {
10527
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10627
				ref = new SingleTypeReference(simpleTypeName, 0);
10528
					char[] substitution;
10628
			} else {
10529
					if(methodParameterName.length == 1) {
10629
				ref = new QualifiedTypeReference(cn,new long[cn.length]);
10530
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10630
			}
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
10631
10540
					foundConflicts = true;
10632
			switch (scope.kind) {
10541
					continue nextTypeParameter;
10633
				case Scope.METHOD_SCOPE :
10542
				}
10634
				case Scope.BLOCK_SCOPE :
10635
					guessedType = ref.resolveType((BlockScope)scope);
10636
					break;
10637
				case Scope.CLASS_SCOPE :
10638
					guessedType = ref.resolveType((ClassScope)scope);
10639
					break;
10543
			}
10640
			}
10641
10642
			if (guessedType == null || !guessedType.isValidBinding()) return;
10643
10644
			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
10544
		}
10645
		}
10545
10646
10546
		if(foundConflicts) return substituedParameterNames;
10647
		int relevance = computeBaseRelevance();
10547
		return null;
10648
		relevance += computeRelevanceForResolution();
10649
		relevance += computeRelevanceForInterestingProposal();
10650
		relevance += computeRelevanceForRestrictions(accessibility);
10651
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
10652
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
10653
		relevance += computeRelevanceForQualification(isQualified);
10654
10655
		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
10656
		switch (kind) {
10657
			case ClassFileConstants.AccAnnotation:
10658
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
10659
				relevance += computeRelevanceForAnnotation();
10660
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
10661
				relevance += computeRelevanceForInterface();
10662
				break;
10663
			case ClassFileConstants.AccEnum:
10664
				relevance += computeRelevanceForEnum();
10665
				break;
10666
			case ClassFileConstants.AccInterface:
10667
				relevance += computeRelevanceForInterface();
10668
				break;
10669
			default:
10670
				relevance += computeRelevanceForClass();
10671
				relevance += computeRelevanceForException(simpleTypeName);
10672
				break;
10673
		}
10674
10675
		this.noProposal = false;
10676
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10677
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
10678
		}
10679
	}
10680
10681
	protected void reset() {
10682
10683
		super.reset(false);
10684
		this.knownPkgs = new HashtableOfObject(10);
10685
		this.knownTypes = new HashtableOfObject(10);
10686
	}
10687
10688
	private void setSourceAndTokenRange(int start, int end) {
10689
		this.setSourceAndTokenRange(start, end, true);
10690
	}
10691
10692
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10693
		this.setSourceRange(start, end, emptyTokenAdjstment);
10694
		this.setTokenRange(start, end, emptyTokenAdjstment);
10695
	}
10696
10697
	private void setSourceRange(int start, int end) {
10698
		this.setSourceRange(start, end, true);
10699
	}
10700
10701
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
10702
		this.startPosition = start;
10703
		if(emptyTokenAdjstment) {
10704
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10705
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10706
		} else {
10707
			this.endPosition = end + 1;
10708
		}
10709
	}
10710
10711
	private void setTokenRange(int start, int end) {
10712
		this.setTokenRange(start, end, true);
10713
	}
10714
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10715
		this.tokenStart = start;
10716
		if(emptyTokenAdjstment) {
10717
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10718
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10719
		} else {
10720
			this.tokenEnd = end + 1;
10721
		}
10548
	}
10722
	}
10549
10723
10550
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
10724
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
Lines 10596-10599 Link Here
10596
		}
10770
		}
10597
		return name;
10771
		return name;
10598
	}
10772
	}
10773
10774
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10775
		char[][] substituedParameterNames = new char[typeVariables.length][];
10776
10777
		for (int i = 0; i < substituedParameterNames.length; i++) {
10778
			substituedParameterNames[i] = typeVariables[i].sourceName;
10779
		}
10780
10781
		boolean foundConflicts = false;
10782
10783
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10784
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10785
			char[] methodParameterName = typeVariableBinding.sourceName;
10786
10787
			for (int j = 0; j < excludedNames.length; j++) {
10788
				char[] typeParameterName = excludedNames[j];
10789
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10790
					char[] substitution;
10791
					if(methodParameterName.length == 1) {
10792
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10793
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
10794
						} else {
10795
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
10796
						}
10797
					} else {
10798
						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
10799
					}
10800
					substituedParameterNames[i] = substitution;
10801
10802
					foundConflicts = true;
10803
					continue nextTypeParameter;
10804
				}
10805
			}
10806
		}
10807
10808
		if(foundConflicts) return substituedParameterNames;
10809
		return null;
10810
	}
10599
}
10811
}
(-)model/org/eclipse/jdt/internal/core/util/messages.properties (+3 lines)
Lines 368-370 Link Here
368
classfileformat_exceptiontableentry = [pc: {0}, pc: {1}] -> {2} when : {3}
368
classfileformat_exceptiontableentry = [pc: {0}, pc: {1}] -> {2} when : {3}
369
classfileformat_linenumbertableentry = [pc: {0}, line: {1}]
369
classfileformat_linenumbertableentry = [pc: {0}, line: {1}]
370
classfileformat_localvariabletableentry = [pc: {0}, pc: {1}] local: {2} index: {3} type: {4}
370
classfileformat_localvariabletableentry = [pc: {0}, pc: {1}] local: {2} index: {3} type: {4}
371
372
### Eclipse Java Core completion messages.
373
engine_completing = Computing proposals...
(-)model/org/eclipse/jdt/internal/core/util/Messages.java (+1 lines)
Lines 218-223 Link Here
218
	public static String importRewrite_processDescription;
218
	public static String importRewrite_processDescription;
219
	public static String correction_nullRequestor;
219
	public static String correction_nullRequestor;
220
	public static String correction_nullUnit;
220
	public static String correction_nullUnit;
221
	public static String engine_completing;
221
	public static String engine_searching;
222
	public static String engine_searching;
222
	public static String engine_searching_indexing;
223
	public static String engine_searching_indexing;
223
	public static String engine_searching_matching;
224
	public static String engine_searching_matching;
(-)model/org/eclipse/jdt/internal/core/eval/EvaluationContextWrapper.java (-14 / +19 lines)
Lines 15-27 Link Here
15
15
16
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.core.runtime.IProgressMonitor;
17
import org.eclipse.jdt.core.*;
17
import org.eclipse.jdt.core.*;
18
import org.eclipse.jdt.core.ICompilationUnit;
19
import org.eclipse.jdt.core.IImportDeclaration;
20
import org.eclipse.jdt.core.IJavaElement;
21
import org.eclipse.jdt.core.IJavaModelStatusConstants;
22
import org.eclipse.jdt.core.IJavaProject;
23
import org.eclipse.jdt.core.IType;
24
import org.eclipse.jdt.core.JavaModelException;
25
import org.eclipse.jdt.core.compiler.IProblem;
18
import org.eclipse.jdt.core.compiler.IProblem;
26
import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
19
import org.eclipse.jdt.core.eval.ICodeSnippetRequestor;
27
import org.eclipse.jdt.core.eval.IEvaluationContext;
20
import org.eclipse.jdt.core.eval.IEvaluationContext;
Lines 30-41 Link Here
30
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
23
import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
31
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
24
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
32
import org.eclipse.jdt.internal.core.*;
25
import org.eclipse.jdt.internal.core.*;
33
import org.eclipse.jdt.internal.core.BinaryType;
34
import org.eclipse.jdt.internal.core.ClassFile;
35
import org.eclipse.jdt.internal.core.JavaModelStatus;
36
import org.eclipse.jdt.internal.core.JavaProject;
37
import org.eclipse.jdt.internal.core.SelectionRequestor;
38
import org.eclipse.jdt.internal.core.SourceMapper;
39
import org.eclipse.jdt.internal.core.builder.NameEnvironment;
26
import org.eclipse.jdt.internal.core.builder.NameEnvironment;
40
import org.eclipse.jdt.internal.core.builder.ProblemFactory;
27
import org.eclipse.jdt.internal.core.builder.ProblemFactory;
41
import org.eclipse.jdt.internal.eval.EvaluationContext;
28
import org.eclipse.jdt.internal.eval.EvaluationContext;
Lines 100-108 Link Here
100
	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY);
87
	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY);
101
}
88
}
102
/**
89
/**
90
 * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, IProgressMonitor)
91
 */
92
public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException {
93
	codeComplete(codeSnippet, position, requestor, DefaultWorkingCopyOwner.PRIMARY, null);
94
}
95
/**
103
 * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, WorkingCopyOwner)
96
 * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, WorkingCopyOwner)
104
 */
97
 */
105
public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
98
public void codeComplete(String codeSnippet, int position, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException {
99
	codeComplete(codeSnippet, position, requestor, owner, null);
100
}
101
/**
102
 * @see org.eclipse.jdt.core.eval.IEvaluationContext#codeComplete(String, int, CompletionRequestor, WorkingCopyOwner, IProgressMonitor)
103
 */
104
public void codeComplete(
105
		String codeSnippet,
106
		int position,
107
		CompletionRequestor requestor,
108
		WorkingCopyOwner owner,
109
		IProgressMonitor monitor) throws JavaModelException {
106
	SearchableEnvironment environment = this.project.newSearchableNameEnvironment(owner);
110
	SearchableEnvironment environment = this.project.newSearchableNameEnvironment(owner);
107
	this.context.complete(
111
	this.context.complete(
108
		codeSnippet.toCharArray(),
112
		codeSnippet.toCharArray(),
Lines 111-117 Link Here
111
		requestor,
115
		requestor,
112
		this.project.getOptions(true),
116
		this.project.getOptions(true),
113
		this.project,
117
		this.project,
114
		owner
118
		owner,
119
		monitor
115
	);
120
	);
116
}
121
}
117
/**
122
/**
(-)model/org/eclipse/jdt/core/ICodeAssist.java (+55 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.jdt.core;
11
package org.eclipse.jdt.core;
12
12
13
import org.eclipse.core.runtime.IProgressMonitor;
14
13
/**
15
/**
14
 * Common protocol for Java elements that support source code assist and code
16
 * Common protocol for Java elements that support source code assist and code
15
 * resolve.
17
 * resolve.
Lines 82-87 Link Here
82
 	 */
84
 	 */
83
	void codeComplete(int offset, CompletionRequestor requestor)
85
	void codeComplete(int offset, CompletionRequestor requestor)
84
		throws JavaModelException;
86
		throws JavaModelException;
87
	
88
	/**
89
	 * Performs code completion at the given offset position in this compilation unit,
90
	 * reporting results to the given completion requestor. The <code>offset</code>
91
	 * is the 0-based index of the character, after which code assist is desired.
92
	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
93
	 * compilation unit.
94
	 * <p>
95
	 *
96
	 * @param offset the given offset position
97
	 * @param requestor the given completion requestor
98
	 * @param monitor the progress monitor used to report progress
99
	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
100
	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
101
	 *  <li> The position specified is < -1 or is greater than this compilation unit's
102
	 *      source length (INDEX_OUT_OF_BOUNDS)
103
	 * </ul>
104
	 *
105
	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
106
	 * @since 3.5
107
 	 */
108
	void codeComplete(int offset, CompletionRequestor requestor, IProgressMonitor monitor)
109
		throws JavaModelException;
85
110
86
	/**
111
	/**
87
	 * Performs code completion at the given offset position in this compilation unit,
112
	 * Performs code completion at the given offset position in this compilation unit,
Lines 141-146 Link Here
141
	 */
166
	 */
142
	void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner)
167
	void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner)
143
		throws JavaModelException;
168
		throws JavaModelException;
169
	
170
	/**
171
	 * Performs code completion at the given offset position in this compilation unit,
172
	 * reporting results to the given completion requestor. The <code>offset</code>
173
	 * is the 0-based index of the character, after which code assist is desired.
174
	 * An <code>offset</code> of -1 indicates to code assist at the beginning of this
175
	 * compilation unit.
176
	 * It considers types in the working copies with the given owner first. In other words,
177
	 * the owner's working copies will take precedence over their original compilation units
178
	 * in the workspace.
179
	 * <p>
180
	 * Note that if a working copy is empty, it will be as if the original compilation
181
	 * unit had been deleted.
182
	 * </p>
183
	 *
184
	 * @param offset the given offset position
185
	 * @param requestor the given completion requestor
186
	 * @param owner the owner of working copies that take precedence over their original compilation units
187
	 * @param monitor the progress monitor used to report progress
188
	 * @exception JavaModelException if code assist could not be performed. Reasons include:<ul>
189
	 *  <li>This Java element does not exist (ELEMENT_DOES_NOT_EXIST)</li>
190
	 *  <li> The position specified is < -1 or is greater than this compilation unit's
191
	 *      source length (INDEX_OUT_OF_BOUNDS)
192
	 * </ul>
193
	 *
194
	 * @exception IllegalArgumentException if <code>requestor</code> is <code>null</code>
195
	 * @since 3.5
196
	 */
197
	void codeComplete(int offset, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor)
198
		throws JavaModelException;
144
199
145
	/**
200
	/**
146
	 * Returns the Java elements corresponding to the given selected text in this compilation unit.
201
	 * Returns the Java elements corresponding to the given selected text in this compilation unit.
(-)model/org/eclipse/jdt/core/IType.java (+85 lines)
Lines 154-159 Link Here
154
		boolean isStatic,
154
		boolean isStatic,
155
		CompletionRequestor requestor)
155
		CompletionRequestor requestor)
156
		throws JavaModelException;
156
		throws JavaModelException;
157
	
158
	/**
159
	 * Do code completion inside a code snippet in the context of the current type.
160
	 *
161
	 * If the type can access to his source code and the insertion position is valid,
162
	 * then completion is performed against source. Otherwise the completion is performed
163
	 * against type structure and given locals variables.
164
	 *
165
	 * @param snippet the code snippet
166
	 * @param insertion the position with in source where the snippet
167
	 * is inserted. This position must not be in comments.
168
	 * A possible value is -1, if the position is not known.
169
	 * @param position the position within snippet where the user
170
	 * is performing code assist.
171
	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
172
	 * type names of local variables visible at the current scope
173
	 * @param localVariableNames an array (possibly empty) of local variable names
174
	 * that are visible at the current scope
175
	 * @param localVariableModifiers an array (possible empty) of modifiers for
176
	 * local variables
177
	 * @param isStatic whether the current scope is in a static context
178
	 * @param requestor the completion requestor
179
	 * @param monitor the progress monitor used to report progress
180
	 * @exception JavaModelException if this element does not exist or if an
181
	 *		exception occurs while accessing its corresponding resource.
182
	 * @since 3.5
183
	 */
184
	void codeComplete(
185
		char[] snippet,
186
		int insertion,
187
		int position,
188
		char[][] localVariableTypeNames,
189
		char[][] localVariableNames,
190
		int[] localVariableModifiers,
191
		boolean isStatic,
192
		CompletionRequestor requestor,
193
		IProgressMonitor monitor)
194
		throws JavaModelException;
157
195
158
	/**
196
	/**
159
	 * Do code completion inside a code snippet in the context of the current type.
197
	 * Do code completion inside a code snippet in the context of the current type.
Lines 199-204 Link Here
199
		CompletionRequestor requestor,
237
		CompletionRequestor requestor,
200
		WorkingCopyOwner owner)
238
		WorkingCopyOwner owner)
201
		throws JavaModelException;
239
		throws JavaModelException;
240
	
241
	/**
242
	 * Do code completion inside a code snippet in the context of the current type.
243
	 * It considers types in the working copies with the given owner first. In other words,
244
	 * the owner's working copies will take precedence over their original compilation units
245
	 * in the workspace.
246
	 * <p>
247
	 * Note that if a working copy is empty, it will be as if the original compilation
248
	 * unit had been deleted.
249
	 * </p><p>
250
	 * If the type can access to his source code and the insertion position is valid,
251
	 * then completion is performed against source. Otherwise the completion is performed
252
	 * against type structure and given locals variables.
253
	 * </p>
254
	 *
255
	 * @param snippet the code snippet
256
	 * @param insertion the position with in source where the snippet
257
	 * is inserted. This position must not be in comments.
258
	 * A possible value is -1, if the position is not known.
259
	 * @param position the position with in snippet where the user
260
	 * is performing code assist.
261
	 * @param localVariableTypeNames an array (possibly empty) of fully qualified
262
	 * type names of local variables visible at the current scope
263
	 * @param localVariableNames an array (possibly empty) of local variable names
264
	 * that are visible at the current scope
265
	 * @param localVariableModifiers an array (possible empty) of modifiers for
266
	 * local variables
267
	 * @param isStatic whether the current scope is in a static context
268
	 * @param requestor the completion requestor
269
	 * @param owner the owner of working copies that take precedence over their original compilation units
270
	 * @param monitor the progress monitor used to report progress
271
	 * @exception JavaModelException if this element does not exist or if an
272
	 *		exception occurs while accessing its corresponding resource.
273
	 * @since 3.5
274
	 */
275
	void codeComplete(
276
		char[] snippet,
277
		int insertion,
278
		int position,
279
		char[][] localVariableTypeNames,
280
		char[][] localVariableNames,
281
		int[] localVariableModifiers,
282
		boolean isStatic,
283
		CompletionRequestor requestor,
284
		WorkingCopyOwner owner,
285
		IProgressMonitor monitor)
286
		throws JavaModelException;
202
287
203
288
204
	/**
289
	/**
(-)eval/org/eclipse/jdt/internal/eval/EvaluationContext.java (-3 / +15 lines)
Lines 13-18 Link Here
13
import java.util.Locale;
13
import java.util.Locale;
14
import java.util.Map;
14
import java.util.Map;
15
15
16
import org.eclipse.core.runtime.IProgressMonitor;
16
import org.eclipse.jdt.core.CompletionRequestor;
17
import org.eclipse.jdt.core.CompletionRequestor;
17
import org.eclipse.jdt.core.IJavaProject;
18
import org.eclipse.jdt.core.IJavaProject;
18
import org.eclipse.jdt.core.WorkingCopyOwner;
19
import org.eclipse.jdt.core.WorkingCopyOwner;
Lines 104-111 Link Here
104
 *
105
 *
105
 *  @param owner
106
 *  @param owner
106
 *  	the owner of working copies that take precedence over their original compilation units
107
 *  	the owner of working copies that take precedence over their original compilation units
107
 */
108
 *  
108
public void complete(char[] codeSnippet, int completionPosition, SearchableEnvironment environment, CompletionRequestor requestor, Map options, final IJavaProject project, WorkingCopyOwner owner) {
109
 *  @param monitor
110
 *  	the progress monitor used to report progress
111
 */
112
public void complete(
113
		char[] codeSnippet,
114
		int completionPosition,
115
		SearchableEnvironment environment,
116
		CompletionRequestor requestor,
117
		Map options,
118
		final IJavaProject project,
119
		WorkingCopyOwner owner,
120
		IProgressMonitor monitor) {
109
	try {
121
	try {
110
		IRequestor variableRequestor = new IRequestor() {
122
		IRequestor variableRequestor = new IRequestor() {
111
			public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
123
			public boolean acceptClassFiles(ClassFile[] classFiles, char[] codeSnippetClassName) {
Lines 148-154 Link Here
148
		}
160
		}
149
	};
161
	};
150
162
151
	CompletionEngine engine = new CompletionEngine(environment, mapper.getCompletionRequestor(requestor), options, project, owner);
163
	CompletionEngine engine = new CompletionEngine(environment, mapper.getCompletionRequestor(requestor), options, project, owner, monitor);
152
164
153
	if (this.installedVars != null) {
165
	if (this.installedVars != null) {
154
		IBinaryType binaryType = getRootCodeSnippetBinary();
166
		IBinaryType binaryType = getRootCodeSnippetBinary();
(-)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
}
(-)src/org/eclipse/jdt/core/tests/model/CompletionTests.java (+60 lines)
Lines 16-21 Link Here
16
import junit.framework.Test;
16
import junit.framework.Test;
17
17
18
import org.eclipse.core.runtime.CoreException;
18
import org.eclipse.core.runtime.CoreException;
19
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.NullProgressMonitor;
21
import org.eclipse.core.runtime.OperationCanceledException;
19
import org.eclipse.jdt.core.CompletionContext;
22
import org.eclipse.jdt.core.CompletionContext;
20
import org.eclipse.jdt.core.CompletionProposal;
23
import org.eclipse.jdt.core.CompletionProposal;
21
import org.eclipse.jdt.core.CompletionRequestor;
24
import org.eclipse.jdt.core.CompletionRequestor;
Lines 55-60 Link Here
55
	char[] varClassName = ((EvaluationContextWrapper)context).getVarClassName();
58
	char[] varClassName = ((EvaluationContextWrapper)context).getVarClassName();
56
	return Signature.createTypeSignature(varClassName, true);
59
	return Signature.createTypeSignature(varClassName, true);
57
}
60
}
61
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247941
62
public void testAbortCompletion1() throws JavaModelException {
63
	this.workingCopies = new ICompilationUnit[1];
64
	this.workingCopies[0] = getWorkingCopy(
65
		"/Completion/src/AbortCompletion.java",
66
		"public class AbortCompletion {\n"+
67
		"	void foo() {\n"+
68
		"		Objec\n"+
69
		"	}\n"+
70
		"}\n");
71
72
	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
73
	
74
	String str = this.workingCopies[0].getSource();
75
	String completeBehind = "Objec";
76
	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
77
	IProgressMonitor monitor = new NullProgressMonitor();
78
	try {
79
		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
80
		assertResults(
81
				"Object[TYPE_REF]{Object, java.lang, Ljava.lang.Object;, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
82
				requestor.getResults());
83
	} catch (OperationCanceledException e) {
84
		assertTrue("Should not be cancelled", false);
85
	}
86
	
87
}
88
89
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247941
90
public void testAbortCompletion2() throws JavaModelException {
91
	this.workingCopies = new ICompilationUnit[1];
92
	this.workingCopies[0] = getWorkingCopy(
93
		"/Completion/src/AbortCompletion.java",
94
		"public class AbortCompletion {\n"+
95
		"	void foo() {\n"+
96
		"		Objec\n"+
97
		"	}\n"+
98
		"}\n");
99
100
	CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
101
	
102
	String str = this.workingCopies[0].getSource();
103
	String completeBehind = "Objec";
104
	int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
105
	
106
	try {
107
		IProgressMonitor monitor = new NullProgressMonitor();
108
		monitor.setCanceled(true); /*force completion to abort*/
109
		this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner, monitor);
110
		assertTrue("Should not be cancelled", false);
111
	} catch (OperationCanceledException e) {
112
		assertResults(
113
				"",
114
				requestor.getResults());
115
	}
116
}
117
58
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=164311
118
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=164311
59
public void testBug164311() throws JavaModelException {
119
public void testBug164311() throws JavaModelException {
60
	this.workingCopies = new ICompilationUnit[1];
120
	this.workingCopies = new ICompilationUnit[1];

Return to bug 247941