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 (-8340 / +8560 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-254 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[] { ';' };
238
239
	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
318
	private final static char[] CLASS = "Class".toCharArray();  //$NON-NLS-1$
240
	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
319
	private final static char[] VOID = "void".toCharArray();  //$NON-NLS-1$
320
241
	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
321
	private final static char[] INT = "int".toCharArray();  //$NON-NLS-1$
322
242
	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
323
	private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
324
243
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
325
	private final static char[] VALUE = "value".toCharArray();  //$NON-NLS-1$
244
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
326
	private final static char[] EXTENDS = "extends".toCharArray();  //$NON-NLS-1$
245
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
327
	private final static char[] SUPER = "super".toCharArray();  //$NON-NLS-1$
246
247
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
328
	private final static char[] DOT = ".".toCharArray();  //$NON-NLS-1$
248
329
249
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
330
	private final static char[] VARARGS = "...".toCharArray();  //$NON-NLS-1$
250
251
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
331
	private final static char[] IMPORT = "import".toCharArray();  //$NON-NLS-1$
332
252
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
333
	private final static char[] STATIC = "static".toCharArray();  //$NON-NLS-1$
253
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
334
	private final static char[] ON_DEMAND = ".*".toCharArray();  //$NON-NLS-1$
254
	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$
335
	private final static char[] IMPORT_END = ";\n".toCharArray();  //$NON-NLS-1$
Lines 257-296 Link Here
257
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
338
		createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
258
	private final static char[] JAVA_LANG_NAME =
339
	private final static char[] JAVA_LANG_NAME =
259
		CharOperation.concatWith(JAVA_LANG, '.');
340
		CharOperation.concatWith(JAVA_LANG, '.');
260
261
	private final static int NONE = 0;
341
	private final static int NONE = 0;
342
262
	private final static int SUPERTYPE = 1;
343
	private final static int SUPERTYPE = 1;
263
	private final static int SUBTYPE = 2;
344
	private final static int SUBTYPE = 2;
264
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
269
	int expectedTypesPtr = -1;
348
	int expectedTypesPtr = -1;
270
	TypeBinding[] expectedTypes = new TypeBinding[1];
349
	TypeBinding[] expectedTypes = new TypeBinding[1];
271
	int expectedTypesFilter;
350
	int expectedTypesFilter;
272
	boolean hasJavaLangObjectAsExpectedType = false;
351
	boolean hasJavaLangObjectAsExpectedType = false;
352
273
	int uninterestingBindingsPtr = -1;
353
	int uninterestingBindingsPtr = -1;
354
274
	Binding[] uninterestingBindings = new Binding[1];
355
	Binding[] uninterestingBindings = new Binding[1];
275
	int forbbidenBindingsPtr = -1;
356
	int forbbidenBindingsPtr = -1;
276
	Binding[] forbbidenBindings = new Binding[1];
357
	Binding[] forbbidenBindings = new Binding[1];
277
	int forbbidenBindingsFilter;
358
	int forbbidenBindingsFilter;
278
279
	ImportBinding[] favoriteReferenceBindings;
359
	ImportBinding[] favoriteReferenceBindings;
280
281
	boolean assistNodeIsClass;
360
	boolean assistNodeIsClass;
282
	boolean assistNodeIsEnum;
361
	boolean assistNodeIsEnum;
283
	boolean assistNodeIsException;
362
	boolean assistNodeIsException;
284
	boolean assistNodeIsInterface;
363
	boolean assistNodeIsInterface;
364
285
	boolean assistNodeIsAnnotation;
365
	boolean assistNodeIsAnnotation;
366
286
	boolean assistNodeIsConstructor;
367
	boolean assistNodeIsConstructor;
287
	boolean assistNodeIsSuperType;
368
	boolean assistNodeIsSuperType;
288
	int  assistNodeInJavadoc = 0;
369
	int  assistNodeInJavadoc = 0;
289
	boolean assistNodeCanBeSingleMemberAnnotation = false;
370
	boolean assistNodeCanBeSingleMemberAnnotation = false;
290
291
	long targetedElement;
371
	long targetedElement;
292
293
	WorkingCopyOwner owner;
372
	WorkingCopyOwner owner;
373
	IProgressMonitor monitor;
294
	IJavaProject javaProject;
374
	IJavaProject javaProject;
295
	ITypeRoot typeRoot;
375
	ITypeRoot typeRoot;
296
	CompletionParser parser;
376
	CompletionParser parser;
Lines 307-319 Link Here
307
	CategorizedProblem problem = null;
387
	CategorizedProblem problem = null;
308
	char[] fileName = null;
388
	char[] fileName = null;
309
	int startPosition, actualCompletionPosition, endPosition, offset;
389
	int startPosition, actualCompletionPosition, endPosition, offset;
390
	
310
	int tokenStart, tokenEnd;
391
	int tokenStart, tokenEnd;
392
311
	int javadocTagPosition; // Position of previous tag while completing in javadoc
393
	int javadocTagPosition; // Position of previous tag while completing in javadoc
312
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
394
	HashtableOfObject knownPkgs = new HashtableOfObject(10);
313
	HashtableOfObject knownTypes = new HashtableOfObject(10);
395
	HashtableOfObject knownTypes = new HashtableOfObject(10);
314
	Scanner nameScanner;
396
	Scanner nameScanner;
315
397
	
316
	/*
398
 	/*
317
		static final char[][] mainDeclarations =
399
		static final char[][] mainDeclarations =
318
			new char[][] {
400
			new char[][] {
319
				"package".toCharArray(),
401
				"package".toCharArray(),
Lines 349-371 Link Here
349
		TypeBinding.SHORT,
431
		TypeBinding.SHORT,
350
		TypeBinding.VOID
432
		TypeBinding.VOID
351
	};
433
	};
434
352
	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
435
	static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
353
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
436
	static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
354
	static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
437
	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][];
438
	static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
356
 	static {
357
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
358
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
359
 		}
360
		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
361
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
362
		}
363
 	}
364
365
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
439
	static final char[] classField = "class".toCharArray();  //$NON-NLS-1$
440
366
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
441
	static final char[] lengthField = "length".toCharArray();  //$NON-NLS-1$
442
367
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
443
	static final char[] cloneMethod = "clone".toCharArray();  //$NON-NLS-1$
444
368
	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
445
	static final char[] THIS = "this".toCharArray();  //$NON-NLS-1$
446
369
	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$
447
	static final char[] THROWS = "throws".toCharArray();  //$NON-NLS-1$
370
448
371
	static InvocationSite FakeInvocationSite = new InvocationSite(){
449
	static InvocationSite FakeInvocationSite = new InvocationSite(){
Lines 375-384 Link Here
375
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
453
		public void setActualReceiverType(ReferenceBinding receiverType) {/* empty */}
376
		public void setDepth(int depth){/* empty */}
454
		public void setDepth(int depth){/* empty */}
377
		public void setFieldIndex(int depth){/* empty */}
455
		public void setFieldIndex(int depth){/* empty */}
378
		public int sourceStart() { return 0; 	}
379
		public int sourceEnd() { return 0; 	}
456
		public int sourceEnd() { return 0; 	}
457
		public int sourceStart() { return 0; 	}
380
	};
458
	};
381
459
460
	static {
461
 		for (int i=0; i<BASE_TYPES_LENGTH; i++) {
462
 			BASE_TYPE_NAMES[i] = BASE_TYPES[i].simpleName;
463
 		}
464
		for (int i=0; i<BASE_TYPES_WITHOUT_VOID_LENGTH; i++) {
465
			BASE_TYPE_NAMES_WITHOUT_VOID[i] = BASE_TYPES[i].simpleName;
466
		}
467
 	}
468
469
	private int foundTypesCount;
382
	private ObjectVector acceptedTypes;
470
	private ObjectVector acceptedTypes;
383
471
384
	/**
472
	/**
Lines 403-409 Link Here
403
			CompletionRequestor requestor,
491
			CompletionRequestor requestor,
404
			Map settings,
492
			Map settings,
405
			IJavaProject javaProject,
493
			IJavaProject javaProject,
406
			WorkingCopyOwner owner) {
494
			WorkingCopyOwner owner,
495
			IProgressMonitor monitor) {
407
		super(settings);
496
		super(settings);
408
		this.javaProject = javaProject;
497
		this.javaProject = javaProject;
409
		this.requestor = requestor;
498
		this.requestor = requestor;
Lines 429-434 Link Here
429
				null/*taskPriorities*/,
518
				null/*taskPriorities*/,
430
				true/*taskCaseSensitive*/);
519
				true/*taskCaseSensitive*/);
431
		this.owner = owner;
520
		this.owner = owner;
521
		this.monitor = monitor;
522
	}
523
524
	/**
525
	 * One result of the search consists of a new package.
526
	 *
527
	 * NOTE - All package names are presented in their readable form:
528
	 *    Package names are in the form "a.b.c".
529
	 *    The default package is represented by an empty array.
530
	 */
531
	public void acceptPackage(char[] packageName) {
532
533
		if (this.knownPkgs.containsKey(packageName)) return;
534
535
		this.knownPkgs.put(packageName, this);
536
537
		char[] completion;
538
		if(this.resolvingImports) {
539
			if(this.resolvingStaticImports) {
540
				completion = CharOperation.concat(packageName, new char[] { '.' });
541
			} else {
542
				completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
543
			}
544
		} else {
545
			completion = packageName;
546
		}
547
548
		int relevance = computeBaseRelevance();
549
		relevance += computeRelevanceForResolution();
550
		relevance += computeRelevanceForInterestingProposal();
551
		relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
552
		if(!this.resolvingImports) {
553
			relevance += computeRelevanceForQualification(true);
554
		}
555
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
556
557
		this.noProposal = false;
558
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
559
			InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
560
			proposal.setDeclarationSignature(packageName);
561
			proposal.setPackageName(packageName);
562
			proposal.setCompletion(completion);
563
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
564
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
565
			proposal.setRelevance(relevance);
566
			this.requestor.accept(proposal);
567
			if(DEBUG) {
568
				this.printDebug(proposal);
569
			}
570
		}
432
	}
571
	}
433
572
434
	/**
573
	/**
Lines 445-451 Link Here
445
		char[][] enclosingTypeNames,
584
		char[][] enclosingTypeNames,
446
		int modifiers,
585
		int modifiers,
447
		AccessRestriction accessRestriction) {
586
		AccessRestriction accessRestriction) {
448
587
		
588
		// does not check cancellation for every types to avoid performance loss
589
		if ((this.foundTypesCount % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
590
		this.foundTypesCount++;
591
		
449
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
592
		if (this.options.checkDeprecation && (modifiers & ClassFileConstants.AccDeprecated) != 0) return;
450
593
451
		if (this.options.checkVisibility) {
594
		if (this.options.checkVisibility) {
Lines 489-555 Link Here
489
		if(length == 0) return;
632
		if(length == 0) return;
490
633
491
		HashtableOfObject onDemandFound = new HashtableOfObject();
634
		HashtableOfObject onDemandFound = new HashtableOfObject();
492
635
		
493
		next : for (int i = 0; i < length; i++) {
636
		try {
494
			AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
637
			next : for (int i = 0; i < length; i++) {
495
			char[] packageName = acceptedType.packageName;
638
				
496
			char[] simpleTypeName = acceptedType.simpleTypeName;
639
				// does not check cancellation for every types to avoid performance loss
497
			char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
640
				if ((i % CHECK_CANCEL_FREQUENCY_IN_FIND_TYPES) == 0) checkCancel();
498
			int modifiers = acceptedType.modifiers;
641
				
499
			int accessibility = acceptedType.accessibility;
642
				AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
500
643
				char[] packageName = acceptedType.packageName;
501
			char[] typeName;
644
				char[] simpleTypeName = acceptedType.simpleTypeName;
502
			char[] flatEnclosingTypeNames;
645
				char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
503
			if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
646
				int modifiers = acceptedType.modifiers;
504
				flatEnclosingTypeNames = null;
647
				int accessibility = acceptedType.accessibility;
505
				typeName = simpleTypeName;
648
	
506
			} else {
649
				char[] typeName;
507
				flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
650
				char[] flatEnclosingTypeNames;
508
				typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
651
				if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
509
			}
652
					flatEnclosingTypeNames = null;
510
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
653
					typeName = simpleTypeName;
511
654
				} else {
512
			if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
655
					flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
513
656
					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
				}
657
				}
520
658
				char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
521
				char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
659
	
522
660
				if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
523
				if(this.resolvingStaticImports) {
661
	
524
					if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
662
				this.knownTypes.put(fullyQualifiedName, this);
525
						completionName = CharOperation.concat(completionName, new char[] { '.' });
663
	
526
					} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
664
				if (this.resolvingImports) {
527
						continue next;
665
					if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
666
						continue next; // import of default package is forbidden when compliance is 1.4 or higher
667
					}
668
	
669
					char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
670
	
671
					if(this.resolvingStaticImports) {
672
						if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
673
							completionName = CharOperation.concat(completionName, new char[] { '.' });
674
						} else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
675
							continue next;
676
						} else {
677
							completionName = CharOperation.concat(completionName, new char[] { ';' });
678
						}
528
					} else {
679
					} else {
529
						completionName = CharOperation.concat(completionName, new char[] { ';' });
680
						completionName = CharOperation.concat(completionName, new char[] { ';' });
530
					}
681
					}
682
	
683
					int relevance = computeBaseRelevance();
684
					relevance += computeRelevanceForResolution();
685
					relevance += computeRelevanceForInterestingProposal();
686
					relevance += computeRelevanceForRestrictions(accessibility);
687
					relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
688
	
689
					this.noProposal = false;
690
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
691
						createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
692
					}
531
				} else {
693
				} else {
532
					completionName = CharOperation.concat(completionName, new char[] { ';' });
694
					if(!this.importCachesInitialized) {
533
				}
695
						initializeImportCaches();
534
696
					}
535
				int relevance = computeBaseRelevance();
697
	
536
				relevance += computeRelevanceForResolution();
698
					for (int j = 0; j < this.importCacheCount; j++) {
537
				relevance += computeRelevanceForInterestingProposal();
699
						char[][] importName = this.importsCache[j];
538
				relevance += computeRelevanceForRestrictions(accessibility);
700
						if(CharOperation.equals(typeName, importName[0])) {
539
				relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
701
							proposeType(
540
702
									packageName,
541
				this.noProposal = false;
703
									simpleTypeName,
542
				if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
704
									modifiers,
543
					createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
705
									accessibility,
544
				}
706
									typeName,
545
			} else {
707
									fullyQualifiedName,
546
				if(!this.importCachesInitialized) {
708
									!CharOperation.equals(fullyQualifiedName, importName[1]),
547
					initializeImportCaches();
709
									scope);
548
				}
710
							continue next;
549
711
						}
550
				for (int j = 0; j < this.importCacheCount; j++) {
712
					}
551
					char[][] importName = this.importsCache[j];
713
	
552
					if(CharOperation.equals(typeName, importName[0])) {
714
	
715
					if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
553
						proposeType(
716
						proposeType(
554
								packageName,
717
								packageName,
555
								simpleTypeName,
718
								simpleTypeName,
Lines 557-606 Link Here
557
								accessibility,
720
								accessibility,
558
								typeName,
721
								typeName,
559
								fullyQualifiedName,
722
								fullyQualifiedName,
560
								!CharOperation.equals(fullyQualifiedName, importName[1]),
723
								false,
561
								scope);
724
								scope);
562
						continue next;
725
						continue next;
563
					}
726
					} else {
564
				}
727
						char[] fullyQualifiedEnclosingTypeOrPackageName = null;
565
728
	
566
729
						AcceptedType foundType = null;
567
				if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
730
						if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
568
					proposeType(
731
							for (int j = 0; j < this.onDemandImportCacheCount; j++) {
569
							packageName,
732
								ImportBinding importBinding = this.onDemandImportsCache[j];
570
							simpleTypeName,
733
	
571
							modifiers,
734
								char[][] importName = importBinding.compoundName;
572
							accessibility,
735
								char[] importFlatName = CharOperation.concatWith(importName, '.');
573
							typeName,
736
	
574
							fullyQualifiedName,
737
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
575
							false,
738
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
576
							scope);
739
										fullyQualifiedEnclosingTypeOrPackageName =
577
					continue next;
740
											CharOperation.concat(
578
				} else {
741
													packageName,
579
					char[] fullyQualifiedEnclosingTypeOrPackageName = null;
742
													flatEnclosingTypeNames,
580
743
													'.');
581
					AcceptedType foundType = null;
744
									} else {
582
					if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
745
										fullyQualifiedEnclosingTypeOrPackageName =
583
						for (int j = 0; j < this.onDemandImportCacheCount; j++) {
746
											packageName;
584
							ImportBinding importBinding = this.onDemandImportsCache[j];
747
									}
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
								}
748
								}
600
							}
749
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
601
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
750
									if(importBinding.isStatic()) {
602
								if(importBinding.isStatic()) {
751
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
603
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
752
											acceptedType.qualifiedTypeName = typeName;
753
											acceptedType.fullyQualifiedName = fullyQualifiedName;
754
											onDemandFound.put(
755
													simpleTypeName,
756
													acceptedType);
757
											continue next;
758
										}
759
									} else {
604
										acceptedType.qualifiedTypeName = typeName;
760
										acceptedType.qualifiedTypeName = typeName;
605
										acceptedType.fullyQualifiedName = fullyQualifiedName;
761
										acceptedType.fullyQualifiedName = fullyQualifiedName;
606
										onDemandFound.put(
762
										onDemandFound.put(
Lines 608-689 Link Here
608
												acceptedType);
764
												acceptedType);
609
										continue next;
765
										continue next;
610
									}
766
									}
611
								} else {
612
									acceptedType.qualifiedTypeName = typeName;
613
									acceptedType.fullyQualifiedName = fullyQualifiedName;
614
									onDemandFound.put(
615
											simpleTypeName,
616
											acceptedType);
617
									continue next;
618
								}
767
								}
619
							}
768
							}
620
						}
769
						} else if(!foundType.mustBeQualified){
621
					} else if(!foundType.mustBeQualified){
770
							done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
622
						done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
771
								ImportBinding importBinding = this.onDemandImportsCache[j];
623
							ImportBinding importBinding = this.onDemandImportsCache[j];
772
	
624
773
								char[][] importName = importBinding.compoundName;
625
							char[][] importName = importBinding.compoundName;
774
								char[] importFlatName = CharOperation.concatWith(importName, '.');
626
							char[] importFlatName = CharOperation.concatWith(importName, '.');
775
	
627
776
								if(fullyQualifiedEnclosingTypeOrPackageName == null) {
628
							if(fullyQualifiedEnclosingTypeOrPackageName == null) {
777
									if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
629
								if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
778
										fullyQualifiedEnclosingTypeOrPackageName =
630
									fullyQualifiedEnclosingTypeOrPackageName =
779
											CharOperation.concat(
631
										CharOperation.concat(
780
													packageName,
632
												packageName,
781
													flatEnclosingTypeNames,
633
												flatEnclosingTypeNames,
782
													'.');
634
												'.');
783
									} else {
635
								} else {
784
										fullyQualifiedEnclosingTypeOrPackageName =
636
									fullyQualifiedEnclosingTypeOrPackageName =
785
											packageName;
637
										packageName;
786
									}
638
								}
787
								}
639
							}
788
								if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
640
							if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
789
									if(importBinding.isStatic()) {
641
								if(importBinding.isStatic()) {
790
										if((modifiers & ClassFileConstants.AccStatic) != 0) {
642
									if((modifiers & ClassFileConstants.AccStatic) != 0) {
791
											foundType.mustBeQualified = true;
792
											break done;
793
										}
794
									} else {
643
										foundType.mustBeQualified = true;
795
										foundType.mustBeQualified = true;
644
										break done;
796
										break done;
645
									}
797
									}
646
								} else {
647
									foundType.mustBeQualified = true;
648
									break done;
649
								}
798
								}
650
							}
799
							}
651
						}
800
						}
801
						proposeType(
802
								packageName,
803
								simpleTypeName,
804
								modifiers,
805
								accessibility,
806
								typeName,
807
								fullyQualifiedName,
808
								true,
809
								scope);
652
					}
810
					}
653
					proposeType(
654
							packageName,
655
							simpleTypeName,
656
							modifiers,
657
							accessibility,
658
							typeName,
659
							fullyQualifiedName,
660
							true,
661
							scope);
662
				}
811
				}
663
			}
812
			}
664
		}
813
		
665
		char[][] keys = onDemandFound.keyTable;
814
			char[][] keys = onDemandFound.keyTable;
666
		Object[] values = onDemandFound.valueTable;
815
			Object[] values = onDemandFound.valueTable;
667
		int max = keys.length;
816
			int max = keys.length;
668
		for (int i = 0; i < max; i++) {
817
			for (int i = 0; i < max; i++) {
669
			if(keys[i] != null) {
818
				if(keys[i] != null) {
670
				AcceptedType value = (AcceptedType) values[i];
819
					AcceptedType value = (AcceptedType) values[i];
671
				if(value != null) {
820
					if(value != null) {
672
					proposeType(
821
						proposeType(
673
							value.packageName,
822
								value.packageName,
674
							value.simpleTypeName,
823
								value.simpleTypeName,
675
							value.modifiers,
824
								value.modifiers,
676
							value.accessibility,
825
								value.accessibility,
677
							value.qualifiedTypeName,
826
								value.qualifiedTypeName,
678
							value.fullyQualifiedName,
827
								value.fullyQualifiedName,
679
							value.mustBeQualified,
828
								value.mustBeQualified,
680
							scope);
829
								scope);
830
					}
681
				}
831
				}
682
			}
832
			}
833
		} finally {
834
			this.acceptedTypes = null; // reset
683
		}
835
		}
684
		this.acceptedTypes = null; // reset
836
		
837
		
685
	}
838
	}
686
839
	
687
	public void acceptUnresolvedName(char[] name) {
840
	public void acceptUnresolvedName(char[] name) {
688
		int relevance = computeBaseRelevance();
841
		int relevance = computeBaseRelevance();
689
		relevance += computeRelevanceForResolution(false);
842
		relevance += computeRelevanceForResolution(false);
Lines 709-714 Link Here
709
			}
862
			}
710
		}
863
		}
711
	}
864
	}
865
	private void addExpectedType(TypeBinding type, Scope scope){
866
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
867
868
		// do not add twice the same type
869
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
870
			if (this.expectedTypes[i] == type) return;
871
		}
872
873
		int length = this.expectedTypes.length;
874
		if (++this.expectedTypesPtr >= length)
875
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
876
		this.expectedTypes[this.expectedTypesPtr] = type;
877
878
		if(type == scope.getJavaLangObject()) {
879
			this.hasJavaLangObjectAsExpectedType = true;
880
		}
881
	}
882
883
	private void addForbiddenBindings(Binding binding){
884
		if (binding == null) return;
885
886
		int length = this.forbbidenBindings.length;
887
		if (++this.forbbidenBindingsPtr >= length)
888
			System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
889
		this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
890
	}
891
892
	private void addUninterestingBindings(Binding binding){
893
		if (binding == null) return;
894
895
		int length = this.uninterestingBindings.length;
896
		if (++this.uninterestingBindingsPtr >= length)
897
			System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
898
		this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
899
	}
712
900
713
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
901
	// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
714
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
902
	private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
Lines 741-867 Link Here
741
		return true;
929
		return true;
742
	}
930
	}
743
931
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(
932
	private void buildContext(
866
			ASTNode astNode,
933
			ASTNode astNode,
867
			ASTNode astNodeParent,
934
			ASTNode astNodeParent,
Lines 991-996 Link Here
991
		}
1058
		}
992
	}
1059
	}
993
1060
1061
	private void checkCancel() {
1062
		if (this.monitor != null && this.monitor.isCanceled()) {
1063
			throw new OperationCanceledException();
1064
		}
1065
	}
1066
994
	private boolean complete(
1067
	private boolean complete(
995
			ASTNode astNode,
1068
			ASTNode astNode,
996
			ASTNode astNodeParent,
1069
			ASTNode astNodeParent,
Lines 1012-1512 Link Here
1012
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1085
		buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
1013
1086
1014
		if (astNode instanceof CompletionOnFieldType) {
1087
		if (astNode instanceof CompletionOnFieldType) {
1015
1088
			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) {
1089
		} else if (astNode instanceof CompletionOnMethodReturnType) {
1059
1090
			completionOnMethodReturnType(astNode, scope);
1060
			CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
1091
		} else if (astNode instanceof CompletionOnSingleNameReference) {
1061
			SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
1092
			completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
1062
			this.completionToken = type.token;
1093
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1063
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1094
			completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1064
			findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
1095
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
1065
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1096
			completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1066
				findKeywordsForMember(this.completionToken, method.modifiers);
1097
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1098
			completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1099
		} else if (astNode instanceof CompletionOnMemberAccess) {
1100
			completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
1101
		} else if (astNode instanceof CompletionOnMessageSend) {
1102
			completionOnMessageSend(astNode, qualifiedBinding, scope);
1103
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1104
			completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
1105
		} else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
1106
			completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
1107
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1108
			completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
1109
		} else if (astNode instanceof CompletionOnMethodName) {
1110
			completionOnMethodName(astNode, scope);
1111
		} else if (astNode instanceof CompletionOnFieldName) {
1112
			completionOnFieldName(astNode, scope);
1113
		} else if (astNode instanceof CompletionOnLocalName) {
1114
			completionOnLocalOrArgumentName(astNode, scope);
1115
		} else if (astNode instanceof CompletionOnArgumentName) {
1116
			completionOnLocalOrArgumentName(astNode, scope);
1117
		} else if (astNode instanceof CompletionOnKeyword) {
1118
			completionOnKeyword(astNode);
1119
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1120
			completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
1121
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1122
			completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
1123
		} else if (astNode instanceof CompletionOnMemberValueName) {
1124
			completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
1125
		} else if(astNode instanceof CompletionOnBranchStatementLabel) {
1126
			completionOnBranchStatementLabel(astNode);
1127
		} else if(astNode instanceof CompletionOnMessageSendName) {
1128
			completionOnMessageSendName(astNode, qualifiedBinding, scope);
1129
		// Completion on Javadoc nodes
1130
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
1131
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
1132
				completionOnJavadocSingleTypeReference(astNode, scope);
1133
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
1134
				completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
1135
			} else if (astNode instanceof CompletionOnJavadocFieldReference) {
1136
				completionOnJavadocFieldReference(astNode, scope);
1137
			} else if (astNode instanceof CompletionOnJavadocMessageSend) {
1138
				completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
1139
			} else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
1140
				completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
1141
			} else if (astNode instanceof CompletionOnJavadocParamNameReference) {
1142
				completionOnJavadocParamNameReference(astNode);
1143
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
1144
				completionOnJavadocTypeParamReference(astNode);
1145
			} else if (astNode instanceof CompletionOnJavadocTag) {
1146
				completionOnJavadocTag(astNode);
1067
			}
1147
			}
1148
		}
1149
		return true;
1150
	}
1068
1151
1069
			if (method.modifiers == ClassFileConstants.AccDefault) {
1152
	/**
1070
				SourceTypeBinding enclosingType = scope.enclosingSourceType();
1153
	 * Ask the engine to compute a completion at the specified position
1071
				if (!enclosingType.isAnnotationType()) {
1154
	 * of the given compilation unit.
1072
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1155
	 *
1073
						findMethods(
1156
	 *  No return
1074
								this.completionToken,
1157
	 *      completion results are answered through a requestor.
1075
								null,null,
1158
	 *
1076
								scope.enclosingSourceType(),
1159
	 *  @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
1077
								scope,
1160
	 *      the source of the current compilation unit.
1078
								new ObjectVector(),
1161
	 *
1079
								false,
1162
	 *  @param completionPosition int
1080
								false,
1163
	 *      a position in the source where the completion is taking place.
1081
								true,
1164
	 *      This position is relative to the source provided.
1082
								null,
1165
	 */
1083
								null,
1166
	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
1167
1102
			CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
1168
		if(DEBUG) {
1103
			this.completionToken = singleNameReference.token;
1169
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
1104
			SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
1170
			System.out.print(sourceUnit.getFileName());
1105
			if (switchStatement != null
1171
			System.out.print(" AT POSITION "); //$NON-NLS-1$
1106
					&& switchStatement.expression.resolvedType != null
1172
			System.out.println(completionPosition);
1107
					&& switchStatement.expression.resolvedType.isEnum()) {
1173
			System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
1108
				if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1174
			System.out.println(sourceUnit.getContents());
1109
					this.assistNodeIsEnum = true;
1175
		}
1110
					findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
1176
		if (this.monitor != null) this.monitor.beginTask(Messages.engine_completing, IProgressMonitor.UNKNOWN);
1111
				}
1177
		this.requestor.beginReporting();
1112
			} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1178
		boolean contextAccepted = false;
1113
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1179
		try {
1114
			} else {
1180
			this.fileName = sourceUnit.getFileName();
1115
				if (this.expectedTypesPtr > -1) {
1181
			this.actualCompletionPosition = completionPosition - 1;
1116
					this.assistNodeIsEnum = true;
1182
			this.offset = pos;
1117
					done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1183
			this.typeRoot = root;
1118
						if (!this.expectedTypes[i].isEnum()) {
1184
			
1119
							this.assistNodeIsEnum = false;
1185
			this.checkCancel();
1120
							break done;
1186
			
1121
						}
1187
			// for now until we can change the UI.
1122
					}
1188
			CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1189
			CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
1123
1190
1191
			//		boolean completionNodeFound = false;
1192
			if (parsedUnit != null) {
1193
				if(DEBUG) {
1194
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
1195
					System.out.println(parsedUnit.toString());
1124
				}
1196
				}
1125
				if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1126
					char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
1127
1197
1128
					findUnresolvedReference(
1198
				// scan the package & import statements first
1129
							singleNameReference.sourceStart,
1199
				if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
1130
							singleNameReference.sourceEnd,
1200
					contextAccepted = true;
1131
							(BlockScope)scope,
1201
					buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
1132
							alreadyDefinedName);
1202
					if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
1133
				}
1203
						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
					}
1204
					}
1149
				}
1205
					if(this.noProposal && this.problem != null) {
1150
				if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
1206
						this.requestor.completionFailure(this.problem);
1151
					if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
1207
						if(DEBUG) {
1152
						ReferenceBinding ref = scope.enclosingSourceType();
1208
							this.printDebug(this.problem);
1153
						findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
1209
						}
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
					}
1210
					}
1211
					return;
1158
				}
1212
				}
1159
			}
1160
1213
1161
		} else if (astNode instanceof CompletionOnSingleTypeReference) {
1214
				ImportReference[] imports = parsedUnit.imports;
1162
1215
				if (imports != null) {
1163
			CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
1216
					for (int i = 0, length = imports.length; i < length; i++) {
1217
						ImportReference importReference = imports[i];
1218
						if (importReference instanceof CompletionOnImportReference) {
1219
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1220
							if ((this.unitScope = parsedUnit.scope) != null) {
1221
								contextAccepted = true;
1222
								buildContext(importReference, null, parsedUnit, null, null);
1164
1223
1165
			this.completionToken = singleRef.token;
1224
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
1225
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
1166
1226
1167
			this.assistNodeIsClass = singleRef.isClass();
1227
								char[][] oldTokens = importReference.tokens;
1168
			this.assistNodeIsException = singleRef.isException();
1228
								int tokenCount = oldTokens.length;
1169
			this.assistNodeIsInterface = singleRef.isInterface();
1229
								if (tokenCount == 1) {
1170
			this.assistNodeIsConstructor = singleRef.isConstructorType;
1230
									findImports((CompletionOnImportReference)importReference, true);
1171
			this.assistNodeIsSuperType = singleRef.isSuperType();
1231
								} else if(tokenCount > 1){
1232
									this.insideQualifiedReference = true;
1172
1233
1173
			// can be the start of a qualified type name
1234
									char[] lastToken = oldTokens[tokenCount - 1];
1174
			if (qualifiedBinding == null) {
1235
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
1175
				if (this.completionToken.length == 0 &&
1176
						(astNodeParent instanceof ParameterizedSingleTypeReference ||
1177
								astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
1178
					this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
1179
1236
1180
					findParameterizedType((TypeReference)astNodeParent, scope);
1237
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
1181
				} else {
1238
									if(binding != null) {
1182
					ObjectVector typesFound = new ObjectVector();
1239
										if(binding instanceof PackageBinding) {
1183
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1240
											findImports((CompletionOnImportReference)importReference, false);
1184
						findExceptionFromTryStatement(
1241
										} else {
1185
								this.completionToken,
1242
											ReferenceBinding ref = (ReferenceBinding) binding;
1186
								null,
1187
								scope.enclosingSourceType(),
1188
								(BlockScope)scope,
1189
								typesFound);
1190
					}
1191
					findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
1192
				}
1193
			} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1194
				findMemberTypes(
1195
					this.completionToken,
1196
					(ReferenceBinding) qualifiedBinding,
1197
					scope,
1198
					scope.enclosingSourceType(),
1199
					false,
1200
					false,
1201
					false,
1202
					false,
1203
					!this.assistNodeIsConstructor,
1204
					null,
1205
					new ObjectVector(),
1206
					null,
1207
					null,
1208
					null,
1209
					false);
1210
			}
1211
		} else if (astNode instanceof CompletionOnQualifiedNameReference) {
1212
1243
1213
			this.insideQualifiedReference = true;
1244
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1214
			CompletionOnQualifiedNameReference ref =
1245
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
1215
				(CompletionOnQualifiedNameReference) astNode;
1246
											}
1216
			this.completionToken = ref.completionIdentifier;
1247
											if(importReference.isStatic()) {
1217
			long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
1218
1248
1219
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1249
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1220
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1250
													findImportsOfStaticFields(lastToken, ref);
1221
				// complete field members with missing fields type
1251
												}
1222
				// class X {
1252
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
1223
				//   Missing f;
1253
													findImportsOfStaticMethods(lastToken, ref);
1224
				//   void foo() {
1254
												}
1225
				//     f.|
1255
											}
1226
				//   }
1256
										}
1227
				// }
1257
									}
1228
				if (this.assistNodeInJavadoc == 0 &&
1258
								}
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
1259
1235
						if (!foundSomeFields) {
1260
								if(this.noProposal && this.problem != null) {
1236
							findMembersFromMissingType(
1261
									this.requestor.completionFailure(this.problem);
1237
									ref.tokens[0],
1262
									if(DEBUG) {
1238
									ref.sourcePositions[0],
1263
										this.printDebug(this.problem);
1239
									null,
1264
									}
1240
									scope,
1265
								}
1241
									ref,
1266
							}
1242
									ref.isInsideAnnotationAttribute);
1267
							return;
1268
						} else if(importReference instanceof CompletionOnKeyword) {
1269
							contextAccepted = true;
1270
							buildContext(importReference, null, parsedUnit, null, null);
1271
							if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1272
								setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
1273
								CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
1274
								findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
1275
							}
1276
							if(this.noProposal && this.problem != null) {
1277
								this.requestor.completionFailure(this.problem);
1278
								if(DEBUG) {
1279
									this.printDebug(this.problem);
1280
								}
1281
							}
1282
							return;
1243
						}
1283
						}
1244
					}
1284
					}
1245
				}
1285
				}
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
1286
1253
					findFieldsAndMethods(
1287
				if (parsedUnit.types != null) {
1254
							this.completionToken,
1288
					try {
1255
							receiverType.capture(scope, ref.sourceEnd),
1289
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
1256
							scope,
1257
							fieldsFound,
1258
							methodsFound,
1259
							ref,
1260
							scope,
1261
							false,
1262
							false,
1263
							null,
1264
							null,
1265
							null,
1266
							false,
1267
							null,
1268
							-1,
1269
							-1);
1270
1271
					findFieldsAndMethodsFromCastedReceiver(
1272
							enclosingNode,
1273
							qualifiedBinding,
1274
							scope,
1275
							fieldsFound,
1276
							methodsFound,
1277
							ref,
1278
							scope,
1279
							ref);
1280
1290
1281
				} else if (this.assistNodeInJavadoc == 0 &&
1291
						if ((this.unitScope = parsedUnit.scope) != null) {
1282
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1292
							this.source = sourceUnit.getContents();
1283
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1293
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
1284
					boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
1294
							parsedUnit.scope.faultInTypes();
1285
					boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
1295
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
1286
					if (proposeField || proposeMethod) {
1296
							if(DEBUG) {
1287
						if(ref.tokens.length == 1) {
1297
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
1288
							if (qualifiedBinding instanceof LocalVariableBinding) {
1298
								System.out.println(parsedUnit.toString());
1289
								// complete local variable members with missing variables type
1290
								// class X {
1291
								//   void foo() {
1292
								//     Missing f;
1293
								//     f.|
1294
								//   }
1295
								// }
1296
								LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
1297
								findFieldsAndMethodsFromMissingType(
1298
										localVariableBinding.declaration.type,
1299
										localVariableBinding.declaringScope,
1300
										ref,
1301
										scope);
1302
							} else {
1303
								// complete field members with missing fields type
1304
								// class X {
1305
								//   Missing f;
1306
								//   void foo() {
1307
								//     f.|
1308
								//   }
1309
								// }
1310
								findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
1311
							}
1299
							}
1312
1300
							parsedUnit.resolve();
1301
						}
1302
					} catch (CompletionNodeFound e) {
1303
						//					completionNodeFound = true;
1304
						if (e.astNode != null) {
1305
							// if null then we found a problem in the completion node
1306
							if(DEBUG) {
1307
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
1308
								System.out.println(e.astNode.toString());
1309
								if(this.parser.assistNodeParent != null) {
1310
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
1311
									System.out.println(this.parser.assistNodeParent);
1312
								}
1313
							}
1314
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
1315
							contextAccepted =
1316
								complete(
1317
									e.astNode,
1318
									this.parser.assistNodeParent,
1319
									this.parser.enclosingNode,
1320
									parsedUnit,
1321
									e.qualifiedBinding,
1322
									e.scope,
1323
									e.insideTypeAnnotation);
1313
						}
1324
						}
1314
					}
1325
					}
1315
				}
1326
				}
1327
			}
1316
1328
1317
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1329
			if(this.noProposal && this.problem != null) {
1318
				boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
1330
				if(!contextAccepted) {
1319
				ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
1331
					contextAccepted = true;
1320
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1332
					InternalCompletionContext context = new InternalCompletionContext();
1333
					context.setOffset(completionPosition - this.offset);
1334
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1335
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
1336
					this.requestor.acceptContext(context);
1337
				}
1338
				this.requestor.completionFailure(this.problem);
1339
				if(DEBUG) {
1340
					this.printDebug(this.problem);
1341
				}
1342
			}
1343
			/* Ignore package, import, class & interface keywords for now...
1344
					if (!completionNodeFound) {
1345
						if (parsedUnit == null || parsedUnit.types == null) {
1346
							// this is not good enough... can still be trying to define a second type
1347
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
1348
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
1349
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
1350
						}
1351
						// currently have no way to know if extends/implements are possible keywords
1352
					}
1353
			*/
1354
		} catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
1355
			if(DEBUG) {
1356
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1357
				e.printStackTrace(System.out);
1358
			}
1359
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error
1360
			if(DEBUG) {
1361
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1362
				e.printStackTrace(System.out);
1363
			}
1364
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
1365
			if(DEBUG) {
1366
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1367
				e.printStackTrace(System.out);
1368
			}
1369
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618
1370
			if(DEBUG) {
1371
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1372
				e.printStackTrace(System.out);
1373
			}
1374
		} finally {
1375
			if(!contextAccepted) {
1376
				contextAccepted = true;
1377
				InternalCompletionContext context = new InternalCompletionContext();
1378
				context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
1379
				context.setOffset(completionPosition - this.offset);
1380
				if (this.requestor.isExtendedContextRequired()) context.setExtended();
1381
				this.requestor.acceptContext(context);
1382
			}
1383
			this.requestor.endReporting();
1384
			if (this.monitor != null) this.monitor.done();
1385
			reset();
1386
		}
1387
	}
1321
1388
1322
				findMembers(
1389
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
1323
						this.completionToken,
1390
		if(this.requestor != null){
1324
						receiverType,
1391
			this.requestor.beginReporting();
1325
						scope,
1392
		}
1326
						ref,
1393
		boolean contextAccepted = false;
1327
						isInsideAnnotationAttribute,
1394
		IType topLevelType = type;
1328
						null,
1395
		while(topLevelType.getDeclaringType() != null) {
1329
						null,
1396
			topLevelType = topLevelType.getDeclaringType();
1330
						null,
1397
		}
1331
						false);
1332
1398
1333
			} else if (qualifiedBinding instanceof PackageBinding) {
1399
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
1400
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
1334
1401
1335
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1402
		CompilationUnitDeclaration compilationUnit = null;
1336
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1337
1403
1338
				// replace to the end of the completion identifier
1404
		try {
1339
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1405
			// TypeConverter is used instead of SourceTypeConverter because the type
1406
			// to convert can be a binary type or a source type
1407
			TypeDeclaration typeDeclaration = null;
1408
			if (type instanceof SourceType) {
1409
				SourceType sourceType = (SourceType) type;
1410
				ISourceType info = (ISourceType) sourceType.getElementInfo();
1411
				compilationUnit = SourceTypeConverter.buildCompilationUnit(
1412
					new ISourceType[] {info},//sourceTypes[0] is always toplevel here
1413
					SourceTypeConverter.FIELD_AND_METHOD // need field and methods
1414
					| SourceTypeConverter.MEMBER_TYPE, // need member types
1415
					// no need for field initialization
1416
					this.problemReporter,
1417
					compilationResult);
1418
				if (compilationUnit.types != null)
1419
					typeDeclaration = compilationUnit.types[0];
1420
			} else {
1421
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
1422
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
1340
			}
1423
			}
1341
		} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
1342
1424
1343
			this.insideQualifiedReference = true;
1425
			if(typeDeclaration != null) {
1426
				// build AST from snippet
1427
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
1344
1428
1345
			CompletionOnQualifiedTypeReference ref =
1429
				// merge AST
1346
				(CompletionOnQualifiedTypeReference) astNode;
1430
				FieldDeclaration[] oldFields = typeDeclaration.fields;
1431
				FieldDeclaration[] newFields = null;
1432
				if (oldFields != null) {
1433
					newFields = new FieldDeclaration[oldFields.length + 1];
1434
					System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
1435
					newFields[oldFields.length] = fakeInitializer;
1436
				} else {
1437
					newFields = new FieldDeclaration[] {fakeInitializer};
1438
				}
1439
				typeDeclaration.fields = newFields;
1347
1440
1348
			this.assistNodeIsClass = ref.isClass();
1441
				if(DEBUG) {
1349
			this.assistNodeIsException = ref.isException();
1442
					System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
1350
			this.assistNodeIsInterface = ref.isInterface();
1443
					System.out.println(compilationUnit.toString());
1351
			this.assistNodeIsSuperType = ref.isSuperType();
1444
				}
1352
1445
1353
			this.completionToken = ref.completionIdentifier;
1446
				if (compilationUnit.types != null) {
1354
			long completionPosition = ref.sourcePositions[ref.tokens.length];
1447
					try {
1448
						this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
1355
1449
1356
			// get the source positions of the completion identifier
1450
						if ((this.unitScope = compilationUnit.scope) != null) {
1357
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1451
							this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
1358
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1452
							compilationUnit.scope.faultInTypes();
1359
				if (this.assistNodeInJavadoc == 0 &&
1453
							compilationUnit.resolve();
1360
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1454
						}
1361
					if(ref.tokens.length == 1) {
1455
					} catch (CompletionNodeFound e) {
1362
						findMemberTypesFromMissingType(
1456
						//					completionNodeFound = true;
1363
								ref.tokens[0],
1457
						if (e.astNode != null) {
1364
								ref.sourcePositions[0],
1458
							// if null then we found a problem in the completion node
1365
								scope);
1459
							contextAccepted =
1460
								complete(
1461
									e.astNode,
1462
									this.parser.assistNodeParent,
1463
									this.parser.enclosingNode,
1464
									compilationUnit,
1465
									e.qualifiedBinding,
1466
									e.scope,
1467
									e.insideTypeAnnotation);
1468
						}
1366
					}
1469
					}
1367
				}
1470
				}
1368
			} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1471
				if(this.noProposal && this.problem != null) {
1369
				if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1472
					if(!contextAccepted) {
1370
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1473
						contextAccepted = true;
1371
1474
						InternalCompletionContext context = new InternalCompletionContext();
1372
					ObjectVector typesFound = new ObjectVector();
1475
						if (this.requestor.isExtendedContextRequired()) context.setExtended();
1373
1476
						this.requestor.acceptContext(context);
1374
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1477
					}
1375
						findExceptionFromTryStatement(
1478
					this.requestor.completionFailure(this.problem);
1376
								this.completionToken,
1479
					if(DEBUG) {
1377
								(ReferenceBinding)qualifiedBinding,
1480
						this.printDebug(this.problem);
1378
								scope.enclosingSourceType(),
1379
								(BlockScope)scope,
1380
								typesFound);
1381
					}
1481
					}
1382
1383
					findMemberTypes(
1384
						this.completionToken,
1385
						(ReferenceBinding) qualifiedBinding,
1386
						scope,
1387
						scope.enclosingSourceType(),
1388
						false,
1389
						false,
1390
						typesFound,
1391
						null,
1392
						null,
1393
						null,
1394
						false);
1395
				}
1482
				}
1396
			} else if (qualifiedBinding instanceof PackageBinding) {
1397
1398
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1399
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1400
				// replace to the end of the completion identifier
1401
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1402
			}
1483
			}
1403
		} else if (astNode instanceof CompletionOnMemberAccess) {
1484
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
1404
			this.insideQualifiedReference = true;
1485
			if(DEBUG) {
1405
			CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1486
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1406
			long completionPosition = access.nameSourcePosition;
1487
				e.printStackTrace(System.out);
1407
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1408
1409
			this.completionToken = access.token;
1410
1411
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1412
				// complete method members with missing return type
1413
				// class X {
1414
				//   Missing f() {return null;}
1415
				//   void foo() {
1416
				//     f().|
1417
				//   }
1418
				// }
1419
				if (this.assistNodeInJavadoc == 0 &&
1420
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1421
								this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1422
					ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1423
					findFieldsAndMethodsFromMissingReturnType(
1424
							problemMethodBinding.selector,
1425
							problemMethodBinding.parameters,
1426
							scope,
1427
							access,
1428
							insideTypeAnnotation);
1429
				}
1430
			} else {
1431
				if (!access.isInsideAnnotation) {
1432
					if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1433
						findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
1434
					}
1435
1436
					ObjectVector fieldsFound = new ObjectVector();
1437
					ObjectVector methodsFound = new ObjectVector();
1438
1439
					boolean superCall = access.receiver instanceof SuperReference;
1440
1441
					findFieldsAndMethods(
1442
						this.completionToken,
1443
						((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
1444
						scope,
1445
						fieldsFound,
1446
						methodsFound,
1447
						access,
1448
						scope,
1449
						false,
1450
						superCall,
1451
						null,
1452
						null,
1453
						null,
1454
						false,
1455
						null,
1456
						-1,
1457
						-1);
1458
1459
					if (!superCall) {
1460
						findFieldsAndMethodsFromCastedReceiver(
1461
								enclosingNode,
1462
								qualifiedBinding,
1463
								scope,
1464
								fieldsFound,
1465
								methodsFound,
1466
								access,
1467
								scope,
1468
								access.receiver);
1469
					}
1470
				}
1471
			}
1488
			}
1472
1489
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
1473
		} else if (astNode instanceof CompletionOnMessageSend) {
1490
			if(DEBUG) {
1491
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1492
				e.printStackTrace(System.out);
1493
			}
1494
		} catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
1495
			if(DEBUG) {
1496
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1497
				e.printStackTrace(System.out);
1498
			}
1499
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
1500
			if(DEBUG) {
1501
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
1502
				e.printStackTrace(System.out);
1503
			}
1504
		} catch(JavaModelException e) {
1505
			// Do nothing
1506
		}
1507
		if(!contextAccepted) {
1508
			contextAccepted = true;
1509
			InternalCompletionContext context = new InternalCompletionContext();
1510
			if (this.requestor.isExtendedContextRequired()) context.setExtended();
1511
			this.requestor.acceptContext(context);
1512
		}
1513
		if(this.requestor != null){
1514
			this.requestor.endReporting();
1515
		}
1516
	}
1517
	
1518
	private void completionOnBranchStatementLabel(ASTNode astNode) {
1519
		if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
1520
			CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
1521
			this.completionToken = label.label;
1522
			findLabels(this.completionToken, label.possibleLabels);
1523
		}
1524
	}
1525
	
1526
	private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1527
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
1528
			CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
1529
			setSourceAndTokenRange(access.classStart, access.sourceEnd);
1530
			this.completionToken = access.completionIdentifier;
1531
			findClassField(
1532
					this.completionToken,
1533
					(TypeBinding) qualifiedBinding,
1534
					scope,
1535
					null,
1536
					null,
1537
					null,
1538
					false);
1539
		}
1540
	}
1541
	
1542
	private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1543
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1474
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1544
			setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1545
			CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
1546
			TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1547
			findConstructors(
1548
				(ReferenceBinding) qualifiedBinding,
1549
				argTypes,
1550
				scope,
1551
				constructorCall,
1552
				false);
1553
		}
1554
	}
1555
	
1556
	private void completionOnFieldName(ASTNode astNode, Scope scope) {
1557
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1558
			CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1475
1559
1476
			CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1560
			FieldBinding[] fields = scope.enclosingSourceType().fields();
1477
			TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1561
			char[][] excludeNames = new char[fields.length][];
1478
			this.completionToken = messageSend.selector;
1562
			for(int i = 0 ; i < fields.length ; i++){
1479
			if (qualifiedBinding == null) {
1563
				excludeNames[i] = fields[i].name;
1480
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1564
			}
1481
					ObjectVector methodsFound = new ObjectVector();
1482
1565
1483
					findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
1566
			this.completionToken = field.realName;
1484
1567
1485
					findLocalMethodsFromStaticImports(
1568
			findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1569
		}
1570
	}
1571
	
1572
	private void completionOnFieldType(ASTNode astNode, Scope scope) {
1573
		CompletionOnFieldType field = (CompletionOnFieldType) astNode;
1574
		CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
1575
		this.completionToken = type.token;
1576
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1577
1578
		findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
1579
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1580
			findKeywordsForMember(this.completionToken, field.modifiers);
1581
		}
1582
1583
		if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
1584
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
1585
			if (!enclosingType.isAnnotationType()) {
1586
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
1587
					findMethodDeclarations(
1486
							this.completionToken,
1588
							this.completionToken,
1589
							enclosingType,
1487
							scope,
1590
							scope,
1488
							messageSend,
1591
							new ObjectVector(),
1489
							scope,
1592
							null,
1490
							true,
1593
							null,
1491
							methodsFound,
1594
							null,
1492
							true);
1595
							false);
1596
				}
1597
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
1598
					proposeNewMethod(this.completionToken, enclosingType);
1599
				}
1600
			}
1601
		}
1602
	}
1603
	//TODO
1604
	private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1605
		// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
1606
		
1607
		CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
1608
		this.javadocTagPosition = allocExpression.tagSourceStart;
1609
		int rangeStart = astNode.sourceStart;
1610
		if (allocExpression.type.isThis()) {
1611
			if (allocExpression.completeInText()) {
1612
				rangeStart = allocExpression.separatorPosition;
1613
			}
1614
		} else if (allocExpression.completeInText()) {
1615
			rangeStart = allocExpression.type.sourceStart;
1616
		}
1617
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1618
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1619
1620
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1621
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
1622
			findConstructors(ref, argTypes, scope, allocExpression, false);
1623
		}
1624
	}
1625
	//TODO
1626
	private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
1627
		this.insideQualifiedReference = true;
1628
		CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
1629
		this.completionToken = fieldRef.token;
1630
		long completionPosition = fieldRef.nameSourcePosition;
1631
		this.javadocTagPosition = fieldRef.tagSourceStart;
1632
1633
		if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
1634
				ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
1635
			int rangeStart = (int) (completionPosition >>> 32);
1636
			if (fieldRef.receiver.isThis()) {
1637
				if (fieldRef.completeInText()) {
1638
					rangeStart = fieldRef.separatorPosition;
1493
				}
1639
				}
1494
			} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1640
			} else if (fieldRef.completeInText()) {
1641
				rangeStart = fieldRef.receiver.sourceStart;
1642
			}
1643
			setSourceAndTokenRange(rangeStart, (int) completionPosition);
1644
1645
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
1646
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
1647
				findFields(this.completionToken,
1648
					receiverType,
1649
					scope,
1650
					new ObjectVector(),
1651
					new ObjectVector(),
1652
					false, /*not only static */
1653
					fieldRef,
1654
					scope,
1655
					false,
1656
					true,
1657
					null,
1658
					null,
1659
					null,
1660
					false,
1661
					null,
1662
					-1,
1663
					-1);
1664
			}
1665
1666
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1667
					|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
1495
				findMethods(
1668
				findMethods(
1496
					this.completionToken,
1669
					this.completionToken,
1497
					null,
1670
					null,
1498
					argTypes,
1671
					null,
1499
					(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1672
					receiverType,
1500
					scope,
1673
					scope,
1501
					new ObjectVector(),
1674
					new ObjectVector(),
1675
					false, /*not only static */
1502
					false,
1676
					false,
1503
					true,
1677
					fieldRef,
1504
					false,
1505
					messageSend,
1506
					scope,
1678
					scope,
1507
					false,
1679
					false,
1508
					messageSend.receiver instanceof SuperReference,
1509
					false,
1680
					false,
1681
					true,
1510
					null,
1682
					null,
1511
					null,
1683
					null,
1512
					null,
1684
					null,
Lines 1514-1956 Link Here
1514
					null,
1686
					null,
1515
					-1,
1687
					-1,
1516
					-1);
1688
					-1);
1689
				if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
1690
					ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
1691
					if (this.completionToken == null
1692
							|| CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
1693
							|| (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
1694
						findConstructors(refBinding, null, scope, fieldRef, false);
1695
					}
1696
				}
1517
			}
1697
			}
1518
		} else if (astNode instanceof CompletionOnExplicitConstructorCall) {
1698
		}
1519
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1699
	}
1520
				setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1700
	//TODO
1521
1701
	private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1522
				CompletionOnExplicitConstructorCall constructorCall =
1702
		CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
1523
					(CompletionOnExplicitConstructorCall) astNode;
1703
		TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
1524
				TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
1704
		this.completionToken = messageSend.selector;
1525
				findConstructors(
1705
		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
1706
1535
			CompletionOnQualifiedAllocationExpression allocExpression =
1707
		// Set source range
1536
				(CompletionOnQualifiedAllocationExpression) astNode;
1708
		int rangeStart = astNode.sourceStart;
1537
			TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
1709
		if (messageSend.receiver.isThis()) {
1710
			if (messageSend.completeInText()) {
1711
				rangeStart = messageSend.separatorPosition;
1712
			}
1713
		} else if (messageSend.completeInText()) {
1714
			rangeStart = messageSend.receiver.sourceStart;
1715
		}
1716
		setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
1538
1717
1539
			ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
1718
		if (qualifiedBinding == null) {
1540
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
1719
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1541
					&& ref.isClass()
1720
				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
			}
1721
			}
1550
			if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
1722
		} else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
1551
					&& !ref.isFinal()
1723
			findMethods(
1552
					&& !ref.isEnum()){
1724
				this.completionToken,
1553
				findAnonymousType(
1725
				null,
1554
					ref,
1726
				argTypes,
1555
					argTypes,
1727
				(ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
1728
				scope,
1729
				new ObjectVector(),
1730
				false,
1731
				false/* prefix match */,
1732
				messageSend,
1733
				scope,
1734
				false,
1735
				messageSend.receiver instanceof SuperReference,
1736
				true,
1737
				null,
1738
				null,
1739
				null,
1740
				false,
1741
				null,
1742
				-1,
1743
				-1);
1744
		}
1745
	}
1746
	//TODO
1747
	private void completionOnJavadocParamNameReference(ASTNode astNode) {
1748
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1749
			CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
1750
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1751
			findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
1752
			findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
1753
		}
1754
	}
1755
	//TODO
1756
	private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1757
		this.insideQualifiedReference = true;
1758
1759
		CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
1760
		this.completionToken = typeRef.completionIdentifier;
1761
		long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
1762
		this.javadocTagPosition = typeRef.tagSourceStart;
1763
1764
		// get the source positions of the completion identifier
1765
		if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
1766
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
1767
					((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
1768
				int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1769
				setSourceAndTokenRange(rangeStart, (int) completionPosition);
1770
				findMemberTypes(
1771
					this.completionToken,
1772
					(ReferenceBinding) qualifiedBinding,
1556
					scope,
1773
					scope,
1557
					allocExpression);
1774
					scope.enclosingSourceType(),
1775
					false,
1776
					false,
1777
					new ObjectVector(),
1778
					null,
1779
					null,
1780
					null,
1781
					false);
1558
			}
1782
			}
1559
		} else if (astNode instanceof CompletionOnClassLiteralAccess) {
1783
		} 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
1784
1564
				this.completionToken = access.completionIdentifier;
1785
			setSourceRange(astNode.sourceStart, (int) completionPosition);
1565
1786
			int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
1566
				findClassField(
1787
			setTokenRange(rangeStart, (int) completionPosition);
1567
						this.completionToken,
1788
			// replace to the end of the completion identifier
1568
						(TypeBinding) qualifiedBinding,
1789
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1569
						scope,
1790
		}
1570
						null,
1791
	}
1571
						null,
1792
	//TODO
1572
						null,
1793
	private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
1573
						false);
1794
		CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
1795
		this.completionToken = typeRef.token;
1796
		this.javadocTagPosition = typeRef.tagSourceStart;
1797
		setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
1798
		findTypesAndPackages(
1799
				this.completionToken,
1800
				scope,
1801
				(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
1802
				false,
1803
				new ObjectVector());
1804
	}
1805
	//TODO
1806
	private void completionOnJavadocTag(ASTNode astNode) {
1807
		CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
1808
		setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
1809
		findJavadocBlockTags(javadocTag);
1810
		findJavadocInlineTags(javadocTag);
1811
	}
1812
	//TODO
1813
	private void completionOnJavadocTypeParamReference(ASTNode astNode) {
1814
		if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
1815
			CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
1816
			setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
1817
			findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
1818
		}
1819
	}
1820
	
1821
	private void completionOnKeyword(ASTNode astNode) {
1822
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1823
			CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1824
			findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1825
		}
1826
	}
1827
	
1828
	private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
1829
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1830
			LocalDeclaration variable = (LocalDeclaration) astNode;
1831
1832
			int kind;
1833
			if (variable instanceof CompletionOnLocalName){
1834
				this.completionToken = ((CompletionOnLocalName) variable).realName;
1835
				kind = LOCAL;
1836
			} else {
1837
				CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1838
				this.completionToken = arg.realName;
1839
				kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1574
			}
1840
			}
1575
		} else if (astNode instanceof CompletionOnMethodName) {
1576
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1577
				CompletionOnMethodName method = (CompletionOnMethodName) astNode;
1578
1841
1579
				setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
1842
			char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1580
1843
1581
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1844
			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
1589
				findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
1590
			}
1591
		} else if (astNode instanceof CompletionOnFieldName) {
1592
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1593
				CompletionOnFieldName field = (CompletionOnFieldName) astNode;
1594
1845
1595
				FieldBinding[] fields = scope.enclosingSourceType().fields();
1846
			LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1596
				char[][] excludeNames = new char[fields.length][];
1847
			char[][] discouragedNames = new char[locals.length][];
1597
				for(int i = 0 ; i < fields.length ; i++){
1848
			int localCount = 0;
1598
					excludeNames[i] = fields[i].name;
1849
			for(int i = 0 ; i < locals.length ; i++){
1850
				if (locals[i] != null) {
1851
					discouragedNames[localCount++] = locals[i].name;
1599
				}
1852
				}
1600
1601
				this.completionToken = field.realName;
1602
1603
				findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
1604
			}
1853
			}
1605
		} else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) {
1606
			if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
1607
				LocalDeclaration variable = (LocalDeclaration) astNode;
1608
1609
				int kind;
1610
				if (variable instanceof CompletionOnLocalName){
1611
					this.completionToken = ((CompletionOnLocalName) variable).realName;
1612
					kind = LOCAL;
1613
				} else {
1614
					CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
1615
					this.completionToken = arg.realName;
1616
					kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
1617
				}
1618
1619
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
1620
1621
				char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
1622
1854
1623
				LocalVariableBinding[] locals = ((BlockScope)scope).locals;
1855
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1624
				char[][] discouragedNames = new char[locals.length][];
1625
				int localCount = 0;
1626
				for(int i = 0 ; i < locals.length ; i++){
1627
					if (locals[i] != null) {
1628
						discouragedNames[localCount++] = locals[i].name;
1629
					}
1630
				}
1631
1856
1632
				System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
1857
			findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1858
		}
1859
	}
1860
	
1861
	private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
1862
		CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1633
1863
1634
				findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
1864
		CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1635
			}
1865
		if (fakeType.annotations[0] == annot) {
1636
		} else if (astNode instanceof CompletionOnKeyword) {
1866
			// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1637
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1867
			// So 'targetedElement' is not computed in this case.
1638
				CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
1868
			if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1639
				findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
1869
				this.targetedElement = computeTargetedElement(fakeType);
1640
			}
1870
			}
1641
		} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
1642
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
1643
				CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
1644
1871
1645
				this.insideQualifiedReference = true;
1872
		}
1646
1873
1647
				this.assistNodeIsClass = ref.isClass();
1874
		this.assistNodeIsAnnotation = true;
1648
				this.assistNodeIsException = ref.isException();
1875
		if (annot.type instanceof CompletionOnSingleTypeReference) {
1649
				this.assistNodeIsInterface = ref.isInterface();
1876
			CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1650
				this.assistNodeIsSuperType = ref.isSuperType();
1877
			this.completionToken = type.token;
1878
			setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1651
1879
1652
				this.completionToken = ref.completionIdentifier;
1880
			if (scope.parent.parent != null &&
1653
				long completionPosition = ref.sourcePositions[ref.tokens.length];
1881
					!(scope.parent.parent instanceof MethodScope) &&
1654
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1882
					!fakeType.isParameter) {
1655
1883
1656
				if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
1884
				if (this.completionToken.length <= Keywords.INTERFACE.length
1657
						(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
1885
					&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
1658
					if (this.assistNodeInJavadoc == 0 &&
1886
				)){
1659
							(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
1887
					int relevance = computeBaseRelevance();
1660
						if(ref.tokens.length == 1) {
1888
					relevance += computeRelevanceForResolution();
1661
							findMemberTypesFromMissingType(
1889
					relevance += computeRelevanceForInterestingProposal();
1662
									ref,
1890
					relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
1663
									ref.sourcePositions[0],
1891
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1664
									scope);
1892
					relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
1893
1894
					this.noProposal = false;
1895
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1896
						CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1897
						proposal.setName(Keywords.INTERFACE);
1898
						proposal.setCompletion(Keywords.INTERFACE);
1899
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1900
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
1901
						proposal.setRelevance(relevance);
1902
						this.requestor.accept(proposal);
1903
						if(DEBUG) {
1904
							this.printDebug(proposal);
1665
						}
1905
						}
1666
					}
1906
					}
1667
				} else {
1668
					ObjectVector typesFound = new ObjectVector();
1669
					if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
1670
						findExceptionFromTryStatement(
1671
								this.completionToken,
1672
								(ReferenceBinding)qualifiedBinding,
1673
								scope.enclosingSourceType(),
1674
								(BlockScope)scope,
1675
								typesFound);
1676
					}
1677
1678
					findMemberTypes(
1679
						this.completionToken,
1680
						(ReferenceBinding) qualifiedBinding,
1681
						scope,
1682
						scope.enclosingSourceType(),
1683
						false,
1684
						false,
1685
						typesFound,
1686
						null,
1687
						null,
1688
						null,
1689
						false);
1690
				}
1907
				}
1691
			}
1908
			}
1692
		} else if (astNode instanceof CompletionOnMarkerAnnotationName) {
1693
			CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
1694
1909
1695
			CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
1910
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1696
			if (fakeType.annotations[0] == annot) {
1911
		} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1697
				// When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
1912
			this.insideQualifiedReference = true;
1698
				// So 'targetedElement' is not computed in this case.
1699
				if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
1700
					this.targetedElement = computeTargetedElement(fakeType);
1701
				}
1702
1913
1703
			}
1914
			CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1915
			this.completionToken = type.completionIdentifier;
1916
			long completionPosition = type.sourcePositions[type.tokens.length];
1917
			if (qualifiedBinding instanceof PackageBinding) {
1704
1918
1705
			this.assistNodeIsAnnotation = true;
1919
				setSourceRange(astNode.sourceStart, (int) completionPosition);
1706
			if (annot.type instanceof CompletionOnSingleTypeReference) {
1920
				setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1707
				CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
1921
				// replace to the end of the completion identifier
1708
				this.completionToken = type.token;
1922
				findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1709
				setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
1923
			} else {
1710
1924
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1711
				if (scope.parent.parent != null &&
1712
						!(scope.parent.parent instanceof MethodScope) &&
1713
						!fakeType.isParameter) {
1714
1715
					if (this.completionToken.length <= Keywords.INTERFACE.length
1716
						&& CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
1717
					)){
1718
						int relevance = computeBaseRelevance();
1719
						relevance += computeRelevanceForResolution();
1720
						relevance += computeRelevanceForInterestingProposal();
1721
						relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
1722
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
1723
						relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
1724
1725
						this.noProposal = false;
1726
						if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1727
							CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
1728
							proposal.setName(Keywords.INTERFACE);
1729
							proposal.setCompletion(Keywords.INTERFACE);
1730
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
1731
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
1732
							proposal.setRelevance(relevance);
1733
							this.requestor.accept(proposal);
1734
							if(DEBUG) {
1735
								this.printDebug(proposal);
1736
							}
1737
						}
1738
					}
1739
				}
1740
1741
				findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1742
			} else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
1743
				this.insideQualifiedReference = true;
1744
1745
				CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
1746
				this.completionToken = type.completionIdentifier;
1747
				long completionPosition = type.sourcePositions[type.tokens.length];
1748
				if (qualifiedBinding instanceof PackageBinding) {
1749
1750
					setSourceRange(astNode.sourceStart, (int) completionPosition);
1751
					setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1752
					// replace to the end of the completion identifier
1753
					findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
1754
				} else {
1755
					setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1756
1925
1757
					findMemberTypes(
1926
				findMemberTypes(
1758
						this.completionToken,
1927
					this.completionToken,
1759
						(ReferenceBinding) qualifiedBinding,
1928
					(ReferenceBinding) qualifiedBinding,
1929
					scope,
1930
					scope.enclosingSourceType(),
1931
					false,
1932
					false,
1933
					new ObjectVector(),
1934
					null,
1935
					null,
1936
					null,
1937
					false);
1938
			}
1939
		}
1940
	}
1941
	
1942
	private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
1943
			Scope scope, boolean insideTypeAnnotation) {
1944
		this.insideQualifiedReference = true;
1945
		CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
1946
		long completionPosition = access.nameSourcePosition;
1947
		setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
1948
1949
		this.completionToken = access.token;
1950
1951
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
1952
			// complete method members with missing return type
1953
			// class X {
1954
			//   Missing f() {return null;}
1955
			//   void foo() {
1956
			//     f().|
1957
			//   }
1958
			// }
1959
			if (this.assistNodeInJavadoc == 0 &&
1960
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
1961
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
1962
				ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
1963
				findFieldsAndMethodsFromMissingReturnType(
1964
						problemMethodBinding.selector,
1965
						problemMethodBinding.parameters,
1760
						scope,
1966
						scope,
1761
						scope.enclosingSourceType(),
1967
						access,
1762
						false,
1968
						insideTypeAnnotation);
1763
						false,
1764
						new ObjectVector(),
1765
						null,
1766
						null,
1767
						null,
1768
						false);
1769
				}
1770
			}
1969
			}
1771
		} else if (astNode instanceof CompletionOnMemberValueName) {
1970
		} else {
1772
			CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
1971
			if (!access.isInsideAnnotation) {
1773
			Annotation annotation = (Annotation) astNodeParent;
1972
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
1774
1973
					findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
1775
			this.completionToken = memberValuePair.name;
1974
				}
1776
1975
1777
			ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
1976
				ObjectVector fieldsFound = new ObjectVector();
1977
				ObjectVector methodsFound = new ObjectVector();
1778
1978
1779
			if (annotationType != null && annotationType.isAnnotationType()) {
1979
				boolean superCall = access.receiver instanceof SuperReference;
1780
				if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
1781
					findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
1782
				}
1783
				if (this.assistNodeCanBeSingleMemberAnnotation) {
1784
					if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1785
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1786
					} else {
1787
						if (this.expectedTypesPtr > -1) {
1788
							this.assistNodeIsEnum = true;
1789
							done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
1790
								if (!this.expectedTypes[i].isEnum()) {
1791
									this.assistNodeIsEnum = false;
1792
									break done;
1793
								}
1794
							}
1795
1980
1796
						}
1981
				findFieldsAndMethods(
1797
						if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
1982
					this.completionToken,
1798
							char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
1983
					((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
1984
					scope,
1985
					fieldsFound,
1986
					methodsFound,
1987
					access,
1988
					scope,
1989
					false,
1990
					superCall,
1991
					null,
1992
					null,
1993
					null,
1994
					false,
1995
					null,
1996
					-1,
1997
					-1);
1799
1998
1800
							findUnresolvedReference(
1999
				if (!superCall) {
1801
									memberValuePair.sourceStart,
2000
					
1802
									memberValuePair.sourceEnd,
2001
					checkCancel();
1803
									(BlockScope)scope,
2002
					
1804
									alreadyDefinedName);
2003
					findFieldsAndMethodsFromCastedReceiver(
1805
						}
2004
							enclosingNode,
1806
						findVariablesAndMethods(
2005
							qualifiedBinding,
1807
							this.completionToken,
1808
							scope,
2006
							scope,
1809
							FakeInvocationSite,
2007
							fieldsFound,
2008
							methodsFound,
2009
							access,
1810
							scope,
2010
							scope,
1811
							insideTypeAnnotation,
2011
							access.receiver);
1812
							true);
1813
						// can be the start of a qualified type name
1814
						findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1815
					}
1816
				}
2012
				}
1817
			}
2013
			}
1818
		} else if(astNode instanceof CompletionOnBrankStatementLabel) {
2014
		}
1819
			if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
2015
	}
1820
				CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode;
2016
	
2017
	private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
2018
			boolean insideTypeAnnotation) {
2019
		CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
2020
		Annotation annotation = (Annotation) astNodeParent;
1821
2021
1822
				this.completionToken = label.label;
2022
		this.completionToken = memberValuePair.name;
1823
2023
1824
				findLabels(this.completionToken, label.possibleLabels);
2024
		ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
2025
2026
		if (annotationType != null && annotationType.isAnnotationType()) {
2027
			if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2028
				findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
1825
			}
2029
			}
1826
		} else if(astNode instanceof CompletionOnMessageSendName) {
2030
			if (this.assistNodeCanBeSingleMemberAnnotation) {
1827
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2031
				if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
1828
				CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
2032
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2033
				} else {
2034
					if (this.expectedTypesPtr > -1) {
2035
						this.assistNodeIsEnum = true;
2036
						done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2037
							if (!this.expectedTypes[i].isEnum()) {
2038
								this.assistNodeIsEnum = false;
2039
								break done;
2040
							}
2041
						}
1829
2042
1830
				this.insideQualifiedReference = true;
1831
				this.completionToken = messageSend.selector;
1832
				boolean onlyStatic = false;
1833
				if (messageSend.receiver instanceof NameReference) {
1834
					onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
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
					}
2043
					}
2044
					if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
2045
						char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
2046
2047
						findUnresolvedReference(
2048
								memberValuePair.sourceStart,
2049
								memberValuePair.sourceEnd,
2050
								(BlockScope)scope,
2051
								alreadyDefinedName);
2052
					}
2053
					findVariablesAndMethods(
2054
						this.completionToken,
2055
						scope,
2056
						FakeInvocationSite,
2057
						scope,
2058
						insideTypeAnnotation,
2059
						true);
2060
					// can be the start of a qualified type name
2061
					findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
1869
				}
2062
				}
1870
			}
2063
			}
1871
		// Completion on Javadoc nodes
2064
		}
1872
		} else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
2065
	}
1873
			if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
2066
	
2067
	private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2068
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
1874
2069
1875
				CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
2070
		CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
1876
				this.completionToken = typeRef.token;
2071
		TypeBinding[] argTypes = computeTypes(messageSend.arguments);
1877
				this.javadocTagPosition = typeRef.tagSourceStart;
2072
		this.completionToken = messageSend.selector;
1878
				setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
2073
		if (qualifiedBinding == null) {
1879
				findTypesAndPackages(
2074
			if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2075
				ObjectVector methodsFound = new ObjectVector();
2076
2077
				findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
2078
				
2079
				checkCancel();
2080
				
2081
				findLocalMethodsFromStaticImports(
1880
						this.completionToken,
2082
						this.completionToken,
1881
						scope,
2083
						scope,
1882
						(this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
2084
						messageSend,
1883
						false,
2085
						scope,
1884
						new ObjectVector());
2086
						true,
1885
2087
						methodsFound,
1886
			} else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
2088
						true);
2089
			}
2090
		} else  if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2091
			findMethods(
2092
				this.completionToken,
2093
				null,
2094
				argTypes,
2095
				(ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
2096
				scope,
2097
				new ObjectVector(),
2098
				false,
2099
				true,
2100
				messageSend,
2101
				scope,
2102
				false,
2103
				messageSend.receiver instanceof SuperReference,
2104
				false,
2105
				null,
2106
				null,
2107
				null,
2108
				false,
2109
				null,
2110
				-1,
2111
				-1);
2112
		}
2113
	}
2114
	
2115
	private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2116
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
2117
			CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
1887
2118
1888
				this.insideQualifiedReference = true;
2119
			this.insideQualifiedReference = true;
2120
			this.completionToken = messageSend.selector;
2121
			boolean onlyStatic = false;
2122
			if (messageSend.receiver instanceof NameReference) {
2123
				onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
2124
			} else if (!(messageSend.receiver instanceof MessageSend) &&
2125
					!(messageSend.receiver instanceof FieldReference) &&
2126
					!(messageSend.receiver.isThis())) {
2127
				onlyStatic = true;
2128
			}
1889
2129
1890
				CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
2130
			TypeBinding receiverType = (TypeBinding)qualifiedBinding;
1891
				this.completionToken = typeRef.completionIdentifier;
2131
1892
				long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
2132
			if(receiverType != null && receiverType instanceof ReferenceBinding) {
1893
				this.javadocTagPosition = typeRef.tagSourceStart;
2133
				TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
1894
2134
				if(typeArgTypes != null) {
1895
				// get the source positions of the completion identifier
2135
					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,
2136
							this.completionToken,
1903
							(ReferenceBinding) qualifiedBinding,
2137
							typeArgTypes,
1904
							scope,
1905
							scope.enclosingSourceType(),
1906
							false,
1907
							false,
1908
							new ObjectVector(),
1909
							null,
1910
							null,
1911
							null,
2138
							null,
1912
							false);
2139
							(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,
2140
							scope,
1947
							new ObjectVector(),
2141
							new ObjectVector(),
1948
							new ObjectVector(),
2142
							onlyStatic,
1949
							false, /*not only static */
2143
							false,
1950
							fieldRef,
2144
							messageSend,
1951
							scope,
2145
							scope,
1952
							false,
2146
							false,
1953
							true,
2147
							false,
2148
							false,
1954
							null,
2149
							null,
1955
							null,
2150
							null,
1956
							null,
2151
							null,
Lines 1958-5072 Link Here
1958
							null,
2153
							null,
1959
							-1,
2154
							-1,
1960
							-1);
2155
							-1);
1961
					}
2156
				}
2157
			}
2158
		}
2159
	}
2160
	
2161
	private void completionOnMethodName(ASTNode astNode, Scope scope) {
2162
		if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
2163
			CompletionOnMethodName method = (CompletionOnMethodName) astNode;
2164
2165
			setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
2166
2167
			FieldBinding[] fields = scope.enclosingSourceType().fields();
2168
			char[][] excludeNames = new char[fields.length][];
2169
			for(int i = 0 ; i < fields.length ; i++){
2170
				excludeNames[i] = fields[i].name;
2171
			}
2172
2173
			this.completionToken = method.selector;
2174
2175
			findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
2176
		}
2177
	}
2178
	
2179
	private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
2180
		CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
2181
		SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
2182
		this.completionToken = type.token;
2183
		setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
2184
		findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
2185
		if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2186
			findKeywordsForMember(this.completionToken, method.modifiers);
2187
		}
1962
2188
1963
					if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2189
		if (method.modifiers == ClassFileConstants.AccDefault) {
1964
							|| !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
2190
			SourceTypeBinding enclosingType = scope.enclosingSourceType();
1965
						findMethods(
2191
			if (!enclosingType.isAnnotationType()) {
2192
				if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
2193
					findMethodDeclarations(
1966
							this.completionToken,
2194
							this.completionToken,
1967
							null,
2195
							scope.enclosingSourceType(),
1968
							null,
1969
							receiverType,
1970
							scope,
2196
							scope,
1971
							new ObjectVector(),
2197
							new ObjectVector(),
1972
							false, /*not only static */
1973
							false,
1974
							false,
1975
							fieldRef,
1976
							scope,
1977
							false,
1978
							false,
1979
							true,
1980
							null,
2198
							null,
1981
							null,
2199
							null,
1982
							null,
2200
							null,
1983
							false,
2201
							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
				}
2202
				}
2070
			} else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
2203
				if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
2071
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
2204
					proposeNewMethod(this.completionToken, scope.enclosingSourceType());
2072
					CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
2073
					setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
2074
					findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
2075
				}
2205
				}
2076
			} else if (astNode instanceof CompletionOnJavadocTag) {
2077
				CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
2078
				setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
2079
				findJavadocBlockTags(javadocTag);
2080
				findJavadocInlineTags(javadocTag);
2081
			}
2206
			}
2082
		}
2207
		}
2083
		return true;
2084
	}
2208
	}
2209
	
2210
	private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2211
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2212
			CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
2085
2213
2086
	private void findFieldsAndMethodsFromCastedReceiver(
2214
			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
2100
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
2101
2102
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
2103
2104
		TypeReference instanceOfType = instanceOfExpression.type;
2105
2106
		if (instanceOfType.resolvedType == null) return;
2107
2215
2108
		boolean findFromAnotherReceiver = false;
2216
			this.assistNodeIsClass = ref.isClass();
2217
			this.assistNodeIsException = ref.isException();
2218
			this.assistNodeIsInterface = ref.isInterface();
2219
			this.assistNodeIsSuperType = ref.isSuperType();
2109
2220
2110
		char[][] receiverName = null;
2221
			this.completionToken = ref.completionIdentifier;
2111
		int receiverStart = -1;
2222
			long completionPosition = ref.sourcePositions[ref.tokens.length];
2112
		int receiverEnd = -1;
2223
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2113
2224
2114
		if (receiver instanceof QualifiedNameReference) {
2225
			if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
2115
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
2226
					(((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
2227
				if (this.assistNodeInJavadoc == 0 &&
2228
						(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2229
					if(ref.tokens.length == 1) {
2230
						findMemberTypesFromMissingType(
2231
								ref,
2232
								ref.sourcePositions[0],
2233
								scope);
2234
					}
2235
				}
2236
			} else {
2237
				ObjectVector typesFound = new ObjectVector();
2238
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2239
					findExceptionFromTryStatement(
2240
							this.completionToken,
2241
							(ReferenceBinding)qualifiedBinding,
2242
							scope.enclosingSourceType(),
2243
							(BlockScope)scope,
2244
							typesFound);
2245
				}
2246
				
2247
				checkCancel();
2248
				
2249
				findMemberTypes(
2250
					this.completionToken,
2251
					(ReferenceBinding) qualifiedBinding,
2252
					scope,
2253
					scope.enclosingSourceType(),
2254
					false,
2255
					false,
2256
					typesFound,
2257
					null,
2258
					null,
2259
					null,
2260
					false);
2261
			}
2262
		}
2263
	}
2264
	
2265
	private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
2266
		setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
2116
2267
2117
			receiverName = qualifiedNameReference.tokens;
2268
		CompletionOnQualifiedAllocationExpression allocExpression =
2269
			(CompletionOnQualifiedAllocationExpression) astNode;
2270
		TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
2271
2272
		ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
2273
		if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
2274
				&& ref.isClass()
2275
				&& !ref.isAbstract()) {
2276
				findConstructors(
2277
					ref,
2278
					argTypes,
2279
					scope,
2280
					allocExpression,
2281
					false);
2282
		}
2283
		
2284
		checkCancel();
2285
		
2286
		if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
2287
				&& !ref.isFinal()
2288
				&& !ref.isEnum()){
2289
			findAnonymousType(
2290
				ref,
2291
				argTypes,
2292
				scope,
2293
				allocExpression);
2294
		}
2295
	}
2296
	
2297
	private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
2298
			Scope scope, boolean insideTypeAnnotation) {
2299
		this.insideQualifiedReference = true;
2300
		CompletionOnQualifiedNameReference ref =
2301
			(CompletionOnQualifiedNameReference) astNode;
2302
		this.completionToken = ref.completionIdentifier;
2303
		long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
2118
2304
2119
			if (receiverName.length != 1) return;
2305
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2306
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2307
			// complete field members with missing fields type
2308
			// class X {
2309
			//   Missing f;
2310
			//   void foo() {
2311
			//     f.|
2312
			//   }
2313
			// }
2314
			if (this.assistNodeInJavadoc == 0 &&
2315
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2316
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
2317
							this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2318
				if(ref.tokens.length == 1) {
2319
					boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2320
2321
					if (!foundSomeFields) {
2322
						
2323
						checkCancel();
2324
						
2325
						findMembersFromMissingType(
2326
								ref.tokens[0],
2327
								ref.sourcePositions[0],
2328
								null,
2329
								scope,
2330
								ref,
2331
								ref.isInsideAnnotationAttribute);
2332
					}
2333
				}
2334
			}
2335
		} else if (qualifiedBinding instanceof VariableBinding) {
2336
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2337
			TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
2338
			if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
2339
				ObjectVector fieldsFound = new ObjectVector();
2340
				ObjectVector methodsFound = new ObjectVector();
2120
2341
2121
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
2342
				findFieldsAndMethods(
2122
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
2343
						this.completionToken,
2344
						receiverType.capture(scope, ref.sourceEnd),
2345
						scope,
2346
						fieldsFound,
2347
						methodsFound,
2348
						ref,
2349
						scope,
2350
						false,
2351
						false,
2352
						null,
2353
						null,
2354
						null,
2355
						false,
2356
						null,
2357
						-1,
2358
						-1);
2359
				
2360
				checkCancel();
2123
2361
2124
			// if (local instanceof X) local.|
2362
				findFieldsAndMethodsFromCastedReceiver(
2125
			// if (field instanceof X) field.|
2363
						enclosingNode,
2126
			if (instanceOfExpression.expression instanceof SingleNameReference &&
2364
						qualifiedBinding,
2127
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
2365
						scope,
2128
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
2366
						fieldsFound,
2129
				findFromAnotherReceiver = true;
2367
						methodsFound,
2130
			}
2368
						ref,
2369
						scope,
2370
						ref);
2131
2371
2132
			// if (this.field instanceof X) field.|
2372
			} else if (this.assistNodeInJavadoc == 0 &&
2133
			if (instanceOfExpression.expression instanceof FieldReference) {
2373
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
2134
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
2374
							this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
2375
				boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
2376
				boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
2377
				if (proposeField || proposeMethod) {
2378
					if(ref.tokens.length == 1) {
2379
						if (qualifiedBinding instanceof LocalVariableBinding) {
2380
							// complete local variable members with missing variables type
2381
							// class X {
2382
							//   void foo() {
2383
							//     Missing f;
2384
							//     f.|
2385
							//   }
2386
							// }
2387
							LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
2388
							findFieldsAndMethodsFromMissingType(
2389
									localVariableBinding.declaration.type,
2390
									localVariableBinding.declaringScope,
2391
									ref,
2392
									scope);
2393
						} else {
2394
							// complete field members with missing fields type
2395
							// class X {
2396
							//   Missing f;
2397
							//   void foo() {
2398
							//     f.|
2399
							//   }
2400
							// }
2401
							findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
2402
						}
2135
2403
2136
				if (fieldReference.receiver instanceof ThisReference &&
2404
					}
2137
						qualifiedBinding instanceof FieldBinding &&
2138
						fieldReference.binding == qualifiedBinding) {
2139
							findFromAnotherReceiver = true;
2140
				}
2405
				}
2141
			}
2406
			}
2142
		} else if (receiver instanceof FieldReference) {
2143
			FieldReference fieldReference1 = (FieldReference) receiver;
2144
2145
			receiverStart = fieldReference1.sourceStart;
2146
			receiverEnd = fieldReference1.sourceEnd + 1;
2147
2407
2148
			if (fieldReference1.receiver instanceof ThisReference) {
2408
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2409
			boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
2410
			ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
2411
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2149
2412
2150
				receiverName = new char[][] {THIS, fieldReference1.token};
2413
			findMembers(
2414
					this.completionToken,
2415
					receiverType,
2416
					scope,
2417
					ref,
2418
					isInsideAnnotationAttribute,
2419
					null,
2420
					null,
2421
					null,
2422
					false);
2151
2423
2152
				// if (field instanceof X) this.field.|
2424
		} else if (qualifiedBinding instanceof PackageBinding) {
2153
				if (instanceOfExpression.expression instanceof SingleNameReference &&
2154
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
2155
					findFromAnotherReceiver = true;
2156
				}
2157
2425
2158
				// if (this.field instanceof X) this.field.|
2426
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2159
				if (instanceOfExpression.expression instanceof FieldReference) {
2427
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2160
					FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
2161
2428
2162
					if (fieldReference2.receiver instanceof ThisReference &&
2429
			// replace to the end of the completion identifier
2163
							fieldReference2.binding == fieldReference1.binding) {
2430
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2164
								findFromAnotherReceiver = true;
2165
					}
2166
				}
2167
			}
2168
		}
2431
		}
2432
	}
2433
	
2434
	private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
2435
			Scope scope) {
2436
		this.insideQualifiedReference = true;
2169
2437
2170
		if (findFromAnotherReceiver) {
2438
		CompletionOnQualifiedTypeReference ref =
2171
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
2439
			(CompletionOnQualifiedTypeReference) astNode;
2172
			char[] castedReceiver = null;
2173
2440
2174
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
2441
		this.assistNodeIsClass = ref.isClass();
2175
			if(this.source != null) {
2442
		this.assistNodeIsException = ref.isException();
2176
				int memberRefStart = this.startPosition;
2443
		this.assistNodeIsInterface = ref.isInterface();
2444
		this.assistNodeIsSuperType = ref.isSuperType();
2177
2445
2178
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
2446
		this.completionToken = ref.completionIdentifier;
2179
				char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
2447
		long completionPosition = ref.sourcePositions[ref.tokens.length];
2180
2448
2181
				castedReceiver =
2449
		// get the source positions of the completion identifier
2182
					CharOperation.concat(
2450
		if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
2183
						CharOperation.concat(
2451
			setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2184
							'(',
2452
			if (this.assistNodeInJavadoc == 0 &&
2185
							CharOperation.concat(
2453
					(this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
2186
								CharOperation.concat('(', castedTypeChars, ')'),
2454
				if(ref.tokens.length == 1) {
2187
								receiverChars),
2455
					findMemberTypesFromMissingType(
2188
							')'),
2456
							ref.tokens[0],
2189
						dotChars);
2457
							ref.sourcePositions[0],
2190
			} else {
2458
							scope);
2191
				castedReceiver =
2459
				}
2192
					CharOperation.concat(
2193
						CharOperation.concat(
2194
							'(',
2195
							CharOperation.concat(
2196
								CharOperation.concat('(', castedTypeChars, ')'),
2197
								CharOperation.concatWith(receiverName, '.')),
2198
							')'),
2199
						DOT);
2200
			}
2460
			}
2461
		} else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
2462
			if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2463
				setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2201
2464
2202
			if (castedReceiver == null) return;
2465
				ObjectVector typesFound = new ObjectVector();
2203
2466
2204
			int oldStartPosition = this.startPosition;
2467
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2205
			this.startPosition = receiverStart;
2468
					findExceptionFromTryStatement(
2469
							this.completionToken,
2470
							(ReferenceBinding)qualifiedBinding,
2471
							scope.enclosingSourceType(),
2472
							(BlockScope)scope,
2473
							typesFound);
2474
				}
2475
				
2476
				checkCancel();
2206
2477
2207
			findFieldsAndMethods(
2478
				findMemberTypes(
2208
					this.completionToken,
2479
					this.completionToken,
2209
					receiverTypeBinding,
2480
					(ReferenceBinding) qualifiedBinding,
2210
					scope,
2481
					scope,
2211
					fieldsFound,
2482
					scope.enclosingSourceType(),
2212
					methodsFound,
2213
					invocationSite,
2214
					invocationScope,
2215
					false,
2483
					false,
2216
					false,
2484
					false,
2485
					typesFound,
2217
					null,
2486
					null,
2218
					null,
2487
					null,
2219
					null,
2488
					null,
2220
					false,
2489
					false);
2221
					castedReceiver,
2490
			}
2222
					receiverStart,
2491
		} else if (qualifiedBinding instanceof PackageBinding) {
2223
					receiverEnd);
2224
2492
2225
			this.startPosition = oldStartPosition;
2493
			setSourceRange(astNode.sourceStart, (int) completionPosition);
2494
			setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
2495
			// replace to the end of the completion identifier
2496
			findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
2226
		}
2497
		}
2227
	}
2498
	}
2499
	
2500
	private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
2501
			boolean insideTypeAnnotation) {
2502
		CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
2503
		this.completionToken = singleNameReference.token;
2504
		SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
2505
		if (switchStatement != null
2506
				&& switchStatement.expression.resolvedType != null
2507
				&& switchStatement.expression.resolvedType.isEnum()) {
2508
			if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2509
				this.assistNodeIsEnum = true;
2510
				findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
2511
			}
2512
		} else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
2513
			findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
2514
		} else {
2515
			if (this.expectedTypesPtr > -1) {
2516
				this.assistNodeIsEnum = true;
2517
				done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
2518
					if (!this.expectedTypes[i].isEnum()) {
2519
						this.assistNodeIsEnum = false;
2520
						break done;
2521
					}
2522
				}
2228
2523
2229
	public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2524
			}
2230
		if(this.requestor != null){
2525
			if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
2231
			this.requestor.beginReporting();
2526
				char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
2232
		}
2527
2233
		boolean contextAccepted = false;
2528
				findUnresolvedReference(
2234
		IType topLevelType = type;
2529
						singleNameReference.sourceStart,
2235
		while(topLevelType.getDeclaringType() != null) {
2530
						singleNameReference.sourceEnd,
2236
			topLevelType = topLevelType.getDeclaringType();
2531
						(BlockScope)scope,
2532
						alreadyDefinedName);
2533
			}
2534
			
2535
			checkCancel();
2536
			
2537
			findVariablesAndMethods(
2538
				this.completionToken,
2539
				scope,
2540
				singleNameReference,
2541
				scope,
2542
				insideTypeAnnotation,
2543
				singleNameReference.isInsideAnnotationAttribute);
2544
			
2545
			checkCancel();
2546
			
2547
			// can be the start of a qualified type name
2548
			findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
2549
			if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
2550
				if (this.completionToken != null && this.completionToken.length != 0) {
2551
					findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
2552
				} else {
2553
					findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
2554
				}
2555
			}
2556
			if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
2557
				if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
2558
					ReferenceBinding ref = scope.enclosingSourceType();
2559
					findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
2560
				} else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
2561
					ReferenceBinding ref = scope.enclosingSourceType();
2562
					findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
2563
				}
2564
			}
2237
		}
2565
		}
2566
	}
2567
	
2568
	private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
2569
		CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
2238
2570
2239
		this.fileName = topLevelType.getParent().getElementName().toCharArray();
2571
		this.completionToken = singleRef.token;
2240
		CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2241
2572
2242
		CompilationUnitDeclaration compilationUnit = null;
2573
		this.assistNodeIsClass = singleRef.isClass();
2574
		this.assistNodeIsException = singleRef.isException();
2575
		this.assistNodeIsInterface = singleRef.isInterface();
2576
		this.assistNodeIsConstructor = singleRef.isConstructorType;
2577
		this.assistNodeIsSuperType = singleRef.isSuperType();
2578
2579
		// can be the start of a qualified type name
2580
		if (qualifiedBinding == null) {
2581
			if (this.completionToken.length == 0 &&
2582
					(astNodeParent instanceof ParameterizedSingleTypeReference ||
2583
							astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
2584
				this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
2243
2585
2244
		try {
2586
				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 {
2587
			} else {
2261
				compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
2588
				ObjectVector typesFound = new ObjectVector();
2262
				typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
2589
				if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
2263
			}
2590
					findExceptionFromTryStatement(
2264
2591
							this.completionToken,
2265
			if(typeDeclaration != null) {
2592
							null,
2266
				// build AST from snippet
2593
							scope.enclosingSourceType(),
2267
				Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
2594
							(BlockScope)scope,
2268
2595
							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
				}
2596
				}
2597
				
2598
				checkCancel();
2599
				
2600
				findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
2323
			}
2601
			}
2324
		}  catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
2602
		} else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2325
			if(DEBUG) {
2603
			findMemberTypes(
2326
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2604
				this.completionToken,
2327
				e.printStackTrace(System.out);
2605
				(ReferenceBinding) qualifiedBinding,
2328
			}
2606
				scope,
2329
		} catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
2607
				scope.enclosingSourceType(),
2330
			if(DEBUG) {
2608
				false,
2331
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2609
				false,
2332
				e.printStackTrace(System.out);
2610
				false,
2333
			}
2611
				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)
2612
				!this.assistNodeIsConstructor,
2335
			if(DEBUG) {
2613
				null,
2336
				System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
2614
				new ObjectVector(),
2337
				e.printStackTrace(System.out);
2615
				null,
2338
			}
2616
				null,
2339
		} catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
2617
				null,
2340
			if(DEBUG) {
2618
				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
		}
2619
		}
2356
	}
2620
	}
2357
2621
2358
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
2622
	private char[][] computeAlreadyDefinedName(
2359
		StringBuffer prefix = new StringBuffer();
2623
			BlockScope scope,
2360
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
2624
			InvocationSite invocationSite) {
2361
		if(isStatic) {
2625
		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
2626
2374
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
2627
		boolean staticsOnly = false;
2375
		this.offset = prefix.length();
2376
2628
2377
		String encoding = this.compilerOptions.defaultEncoding;
2629
		Scope currentScope = scope;
2378
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
2379
			fakeSource,
2380
			null,
2381
			"FakeType.java", //$NON-NLS-1$
2382
			encoding);
2383
2630
2384
		this.actualCompletionPosition = prefix.length() + position - 1;
2631
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
2385
2632
2386
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
2633
			switch (currentScope.kind) {
2387
		CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
2388
2634
2389
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
2635
				case Scope.METHOD_SCOPE :
2636
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
2637
					MethodScope methodScope = (MethodScope) currentScope;
2638
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
2390
2639
2391
		return (Initializer)fakeAST.types[0].fields[0];
2640
				//$FALL-THROUGH$
2392
	}
2641
				case Scope.BLOCK_SCOPE :
2642
					BlockScope blockScope = (BlockScope) currentScope;
2393
2643
2394
	/**
2644
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
2395
	 * Ask the engine to compute a completion at the specified position
2645
						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
2646
2410
		if(DEBUG) {
2647
						if (local == null)
2411
			System.out.print("COMPLETION IN "); //$NON-NLS-1$
2648
							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
2649
2429
			//		boolean completionNodeFound = false;
2650
						if (local.isSecret())
2430
			if (parsedUnit != null) {
2651
							continue next;
2431
				if(DEBUG) {
2432
					System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
2433
					System.out.println(parsedUnit.toString());
2434
				}
2435
2652
2436
				// scan the package & import statements first
2653
						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
					}
2654
					}
2449
					return;
2655
					break;
2450
				}
2451
2656
2452
				ImportReference[] imports = parsedUnit.imports;
2657
				case Scope.CLASS_SCOPE :
2453
				if (imports != null) {
2658
					ClassScope classScope = (ClassScope) currentScope;
2454
					for (int i = 0, length = imports.length; i < length; i++) {
2659
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
2455
						ImportReference importReference = imports[i];
2660
					computeAlreadyDefinedName(
2456
						if (importReference instanceof CompletionOnImportReference) {
2661
							enclosingType,
2457
							this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2662
							classScope,
2458
							if ((this.unitScope = parsedUnit.scope) != null) {
2663
							staticsOnly,
2459
								contextAccepted = true;
2664
							invocationSite,
2460
								buildContext(importReference, null, parsedUnit, null, null);
2665
							result);
2666
					staticsOnly |= enclosingType.isStatic();
2667
					break;
2461
2668
2462
								long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
2669
				case Scope.COMPILATION_UNIT_SCOPE :
2463
								setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
2670
					break done1;
2671
			}
2672
			currentScope = currentScope.parent;
2673
		}
2464
2674
2465
								char[][] oldTokens = importReference.tokens;
2675
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
2466
								int tokenCount = oldTokens.length;
2467
								if (tokenCount == 1) {
2468
									findImports((CompletionOnImportReference)importReference, true);
2469
								} else if(tokenCount > 1){
2470
									this.insideQualifiedReference = true;
2471
2676
2472
									char[] lastToken = oldTokens[tokenCount - 1];
2677
		return (char[][])result.toArray(new char[result.size()][]);
2473
									char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
2678
	}
2474
2679
2475
									Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
2680
	private void computeAlreadyDefinedName(
2476
									if(binding != null) {
2681
			FieldBinding[] fields,
2477
										if(binding instanceof PackageBinding) {
2682
			Scope scope,
2478
											findImports((CompletionOnImportReference)importReference, false);
2683
			boolean onlyStaticFields,
2479
										} else {
2684
			ReferenceBinding receiverType,
2480
											ReferenceBinding ref = (ReferenceBinding) binding;
2685
			InvocationSite invocationSite,
2686
			ArrayList result) {
2481
2687
2482
											if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
2688
		next : for (int f = fields.length; --f >= 0;) {
2483
												findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
2689
			FieldBinding field = fields[f];
2484
											}
2485
											if(importReference.isStatic()) {
2486
2690
2487
												if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
2691
			if (field.isSynthetic()) continue next;
2488
													findImportsOfStaticFields(lastToken, ref);
2489
												}
2490
												if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
2491
													findImportsOfStaticMethods(lastToken, ref);
2492
												}
2493
											}
2494
										}
2495
									}
2496
								}
2497
2692
2498
								if(this.noProposal && this.problem != null) {
2693
			if (onlyStaticFields && !field.isStatic()) 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
2694
2525
				if (parsedUnit.types != null) {
2695
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
2526
					try {
2527
						this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
2528
2696
2529
						if ((this.unitScope = parsedUnit.scope) != null) {
2697
			result.add(field.name);
2530
							this.source = sourceUnit.getContents();
2698
		}
2531
							this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
2699
	}
2532
							parsedUnit.scope.faultInTypes();
2700
2533
							parseBlockStatements(parsedUnit, this.actualCompletionPosition);
2701
	private void computeAlreadyDefinedName(
2534
							if(DEBUG) {
2702
			SourceTypeBinding receiverType,
2535
								System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
2703
			ClassScope scope,
2536
								System.out.println(parsedUnit.toString());
2704
			boolean onlyStaticFields,
2537
							}
2705
			InvocationSite invocationSite,
2538
							parsedUnit.resolve();
2706
			ArrayList result) {
2539
						}
2707
2540
					} catch (CompletionNodeFound e) {
2708
		ReferenceBinding currentType = receiverType;
2541
						//					completionNodeFound = true;
2709
		ReferenceBinding[] interfacesToVisit = null;
2542
						if (e.astNode != null) {
2710
		int nextPosition = 0;
2543
							// if null then we found a problem in the completion node
2711
		do {
2544
							if(DEBUG) {
2712
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
2545
								System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
2713
			if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2546
								System.out.println(e.astNode.toString());
2714
				if (interfacesToVisit == null) {
2547
								if(this.parser.assistNodeParent != null) {
2715
					interfacesToVisit = itsInterfaces;
2548
									System.out.print("COMPLETION - Parent Node : ");  //$NON-NLS-1$
2716
					nextPosition = interfacesToVisit.length;
2549
									System.out.println(this.parser.assistNodeParent);
2717
				} else {
2550
								}
2718
					int itsLength = itsInterfaces.length;
2551
							}
2719
					if (nextPosition + itsLength >= interfacesToVisit.length)
2552
							this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
2720
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2553
							contextAccepted =
2721
					nextInterface : for (int a = 0; a < itsLength; a++) {
2554
								complete(
2722
						ReferenceBinding next = itsInterfaces[a];
2555
									e.astNode,
2723
						for (int b = 0; b < nextPosition; b++)
2556
									this.parser.assistNodeParent,
2724
							if (next == interfacesToVisit[b]) continue nextInterface;
2557
									this.parser.enclosingNode,
2725
						interfacesToVisit[nextPosition++] = next;
2558
									parsedUnit,
2559
									e.qualifiedBinding,
2560
									e.scope,
2561
									e.insideTypeAnnotation);
2562
						}
2563
					}
2726
					}
2564
				}
2727
				}
2565
			}
2728
			}
2566
2729
2567
			if(this.noProposal && this.problem != null) {
2730
			FieldBinding[] fields = currentType.availableFields();
2568
				if(!contextAccepted) {
2731
			if(fields != null && fields.length > 0) {
2569
					contextAccepted = true;
2732
				computeAlreadyDefinedName(
2570
					InternalCompletionContext context = new InternalCompletionContext();
2733
					fields,
2571
					context.setOffset(completionPosition - this.offset);
2734
					scope,
2572
					context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
2735
					onlyStaticFields,
2573
					if (this.requestor.isExtendedContextRequired()) context.setExtended();
2736
					receiverType,
2574
					this.requestor.acceptContext(context);
2737
					invocationSite,
2575
				}
2738
					result);
2576
				this.requestor.completionFailure(this.problem);
2577
				if(DEBUG) {
2578
					this.printDebug(this.problem);
2579
				}
2580
			}
2739
			}
2581
			/* Ignore package, import, class & interface keywords for now...
2740
			currentType = currentType.superclass();
2582
					if (!completionNodeFound) {
2741
		} while ( currentType != null);
2583
						if (parsedUnit == null || parsedUnit.types == null) {
2742
2584
							// this is not good enough... can still be trying to define a second type
2743
		if (interfacesToVisit != null) {
2585
							CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
2744
			for (int i = 0; i < nextPosition; i++) {
2586
							setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
2745
				ReferenceBinding anInterface = interfacesToVisit[i];
2587
							findKeywords(scanner.completionIdentifier, mainDeclarations, null);
2746
				FieldBinding[] fields = anInterface.availableFields();
2588
						}
2747
				if(fields !=  null) {
2589
						// currently have no way to know if extends/implements are possible keywords
2748
					computeAlreadyDefinedName(
2749
						fields,
2750
						scope,
2751
						onlyStaticFields,
2752
						receiverType,
2753
						invocationSite,
2754
						result);
2755
				}
2756
2757
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
2758
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
2759
					int itsLength = itsInterfaces.length;
2760
					if (nextPosition + itsLength >= interfacesToVisit.length)
2761
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
2762
					nextInterface : for (int a = 0; a < itsLength; a++) {
2763
						ReferenceBinding next = itsInterfaces[a];
2764
						for (int b = 0; b < nextPosition; b++)
2765
							if (next == interfacesToVisit[b]) continue nextInterface;
2766
						interfacesToVisit[nextPosition++] = next;
2590
					}
2767
					}
2591
			*/
2768
				}
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
			}
2769
			}
2622
			this.requestor.endReporting();
2623
		}
2770
		}
2624
	}
2771
	}
2625
2772
2626
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
2773
	int computeBaseRelevance(){
2627
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
2774
		return R_DEFAULT;
2775
	}
2628
2776
2629
		if (annotatedElement instanceof TypeDeclaration) {
2777
	private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
2630
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
2778
2631
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
2779
		// default filter
2632
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
2780
		this.expectedTypesFilter = SUBTYPE;
2781
		this.hasJavaLangObjectAsExpectedType = false;
2782
2783
		// find types from parent
2784
		if(parent instanceof AbstractVariableDeclaration) {
2785
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
2786
			TypeBinding binding = variable.type.resolvedType;
2787
			if(binding != null) {
2788
				if(!(variable.initialization instanceof ArrayInitializer)) {
2789
					addExpectedType(binding, scope);
2790
				}
2633
			}
2791
			}
2634
			return TagBits.AnnotationForType;
2792
		} else if(parent instanceof Assignment) {
2635
		} else if (annotatedElement instanceof FieldDeclaration) {
2793
			TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
2636
			if (fakeNode.isParameter) {
2794
			if(binding != null) {
2637
				return TagBits.AnnotationForParameter;
2795
				addExpectedType(binding, scope);
2638
			}
2796
			}
2639
			return TagBits.AnnotationForField;
2797
		} else if(parent instanceof ReturnStatement) {
2640
		} else if (annotatedElement instanceof MethodDeclaration) {
2798
			if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
2641
			return TagBits.AnnotationForMethod;
2799
				MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
2642
		} else if (annotatedElement instanceof Argument) {
2800
				TypeBinding binding = methodBinding  == null ? null : methodBinding.returnType;
2643
			return TagBits.AnnotationForParameter;
2801
				if(binding != null) {
2644
		} else if (annotatedElement instanceof ConstructorDeclaration) {
2802
					addExpectedType(binding, scope);
2645
			return TagBits.AnnotationForConstructor;
2646
		} else if (annotatedElement instanceof LocalDeclaration) {
2647
			return TagBits.AnnotationForLocalVariable;
2648
		} else if (annotatedElement instanceof ImportReference) {
2649
			return TagBits.AnnotationForPackage;
2650
		}
2651
		return 0;
2652
	}
2653
2654
	private TypeBinding[] computeTypes(Expression[] arguments) {
2655
		if (arguments == null) return null;
2656
		int argsLength = arguments.length;
2657
		TypeBinding[] argTypes = new TypeBinding[argsLength];
2658
		for (int a = argsLength; --a >= 0;) {
2659
			argTypes[a] = arguments[a].resolvedType;
2660
		}
2661
		return argTypes;
2662
	}
2663
2664
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
2665
		if (arguments == null) return null;
2666
		int argsLength = arguments.length;
2667
		TypeBinding[] argTypes = new TypeBinding[argsLength];
2668
		for (int a = argsLength; --a >= 0;) {
2669
			TypeBinding typeBinding = arguments[a].resolvedType;
2670
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
2671
			argTypes[a] = typeBinding;
2672
		}
2673
		return argTypes;
2674
	}
2675
2676
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
2677
		MethodBinding[] methods = annotation.availableMethods();
2678
		nextAttribute: for (int i = 0; i < methods.length; i++) {
2679
			MethodBinding method = methods[i];
2680
2681
			if(!CharOperation.prefixEquals(token, method.selector, false)
2682
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
2683
2684
			int length = attributesFound == null ? 0 : attributesFound.length;
2685
			for (int j = 0; j < length; j++) {
2686
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
2687
			}
2688
2689
			int relevance = computeBaseRelevance();
2690
			relevance += computeRelevanceForResolution();
2691
			relevance += computeRelevanceForInterestingProposal(method);
2692
			relevance += computeRelevanceForCaseMatching(token, method.selector);
2693
			relevance += computeRelevanceForQualification(false);
2694
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2695
2696
			this.noProposal = false;
2697
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
2698
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
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
				}
2803
				}
2711
			}
2804
			}
2712
		}
2805
		} else if(parent instanceof CastExpression) {
2713
	}
2806
			Expression e = ((CastExpression)parent).type;
2714
	private void findAnonymousType(
2807
			TypeBinding binding = e.resolvedType;
2715
		ReferenceBinding currentType,
2808
			if(binding != null){
2716
		TypeBinding[] argTypes,
2809
				addExpectedType(binding, scope);
2717
		Scope scope,
2810
				this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2718
		InvocationSite invocationSite) {
2811
			}
2812
		} else if(parent instanceof MessageSend) {
2813
			MessageSend messageSend = (MessageSend) parent;
2719
2814
2720
		if (currentType.isInterface()) {
2815
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
2721
			char[] completion = CharOperation.NO_CHAR;
2816
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
2722
			int relevance = computeBaseRelevance();
2817
				boolean isStatic = messageSend.receiver.isTypeReference();
2723
			relevance += computeRelevanceForResolution();
2724
			relevance += computeRelevanceForInterestingProposal();
2725
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
2726
2818
2727
			this.noProposal = false;
2819
				while(binding != null) {
2728
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
2820
					computeExpectedTypesForMessageSend(
2729
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
2821
						binding,
2730
				proposal.setDeclarationSignature(getSignature(currentType));
2822
						messageSend.selector,
2731
				proposal.setDeclarationKey(currentType.computeUniqueKey());
2823
						messageSend.arguments,
2732
				proposal.setSignature(
2824
						(ReferenceBinding)messageSend.actualReceiverType,
2733
						createMethodSignature(
2825
						scope,
2734
								CharOperation.NO_CHAR_CHAR,
2826
						messageSend,
2735
								CharOperation.NO_CHAR_CHAR,
2827
						isStatic);
2736
								CharOperation.NO_CHAR,
2828
					computeExpectedTypesForMessageSendForInterface(
2737
								CharOperation.NO_CHAR));
2829
						binding,
2738
				//proposal.setOriginalSignature(null);
2830
						messageSend.selector,
2739
				//proposal.setUniqueKey(null);
2831
						messageSend.arguments,
2740
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
2832
						(ReferenceBinding)messageSend.actualReceiverType,
2741
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
2833
						scope,
2742
				//proposal.setParameterPackageNames(null);
2834
						messageSend,
2743
				//proposal.setParameterTypeNames(null);
2835
						isStatic);
2744
				//proposal.setPackageName(null);
2836
					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
				}
2837
				}
2755
			}
2838
			}
2756
		} else {
2839
		} else if(parent instanceof AllocationExpression) {
2757
			findConstructors(
2840
			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
2841
2777
		if (token.length <= classField.length
2842
			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
2843
2788
			if (missingElements != null) {
2844
			if(binding != null) {
2789
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
2845
				computeExpectedTypesForAllocationExpression(
2846
					binding,
2847
					allocationExpression.arguments,
2848
					scope,
2849
					allocationExpression);
2790
			}
2850
			}
2791
2851
		} else if(parent instanceof OperatorExpression) {
2792
			this.noProposal = false;
2852
			int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
2793
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
2853
			if(parent instanceof ConditionalExpression) {
2794
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
2854
				// for future use
2795
				//proposal.setDeclarationSignature(null);
2855
			} else if(parent instanceof InstanceOfExpression) {
2796
				char[] signature =
2856
				InstanceOfExpression e = (InstanceOfExpression) parent;
2797
					createNonGenericTypeSignature(
2857
				TypeBinding binding = e.expression.resolvedType;
2798
						CharOperation.concatWith(JAVA_LANG, '.'),
2858
				if(binding != null){
2799
						CLASS);
2859
					addExpectedType(binding, scope);
2800
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
2860
					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
				}
2812
				proposal.setSignature(signature);
2813
				//proposal.setDeclarationPackageName(null);
2814
				//proposal.setDeclarationTypeName(null);
2815
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
2816
				proposal.setTypeName(CLASS);
2817
				proposal.setName(classField);
2818
				if (missingElements != null) {
2819
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
2820
					for (int i = 0; i < missingElements.length; i++) {
2821
						subProposals[i] =
2822
							createRequiredTypeProposal(
2823
									missingElements[i],
2824
									missingElementsStarts[i],
2825
									missingElementsEnds[i],
2826
									relevance);
2827
					}
2828
					proposal.setRequiredProposals(subProposals);
2829
				}
2830
				proposal.setCompletion(classField);
2831
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
2832
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
2833
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
2834
				proposal.setRelevance(relevance);
2835
				this.requestor.accept(proposal);
2836
				if(DEBUG) {
2837
					this.printDebug(proposal);
2838
				}
2861
				}
2839
			}
2862
			} else if(parent instanceof BinaryExpression) {
2840
		}
2863
				BinaryExpression binaryExpression = (BinaryExpression) parent;
2841
	}
2864
				switch(operator) {
2842
2865
					case OperatorIds.EQUAL_EQUAL :
2843
	private void findEnumConstants(
2866
						// expected type is not relevant in this case
2844
			char[] enumConstantName,
2867
						TypeBinding binding = binaryExpression.left.resolvedType;
2845
			ReferenceBinding enumType,
2868
						if (binding != null) {
2846
			Scope invocationScope,
2869
							addExpectedType(binding, scope);
2847
			ObjectVector fieldsFound,
2870
							this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
2848
			char[][] alreadyUsedConstants,
2871
						}
2849
			int alreadyUsedConstantCount,
2872
						break;
2850
			boolean needQualification) {
2873
					case OperatorIds.PLUS :
2851
2874
						addExpectedType(TypeBinding.SHORT, scope);
2852
		FieldBinding[] fields = enumType.fields();
2875
						addExpectedType(TypeBinding.INT, scope);
2876
						addExpectedType(TypeBinding.LONG, scope);
2877
						addExpectedType(TypeBinding.FLOAT, scope);
2878
						addExpectedType(TypeBinding.DOUBLE, scope);
2879
						addExpectedType(TypeBinding.CHAR, scope);
2880
						addExpectedType(TypeBinding.BYTE, scope);
2881
						addExpectedType(scope.getJavaLangString(), scope);
2882
						break;
2883
					case OperatorIds.AND_AND :
2884
					case OperatorIds.OR_OR :
2885
					case OperatorIds.XOR :
2886
						addExpectedType(TypeBinding.BOOLEAN, scope);
2887
						break;
2888
					default :
2889
						addExpectedType(TypeBinding.SHORT, scope);
2890
						addExpectedType(TypeBinding.INT, scope);
2891
						addExpectedType(TypeBinding.LONG, scope);
2892
						addExpectedType(TypeBinding.FLOAT, scope);
2893
						addExpectedType(TypeBinding.DOUBLE, scope);
2894
						addExpectedType(TypeBinding.CHAR, scope);
2895
						addExpectedType(TypeBinding.BYTE, scope);
2896
						break;
2897
				}
2898
				if(operator == OperatorIds.LESS) {
2899
					if(binaryExpression.left instanceof SingleNameReference){
2900
						SingleNameReference name = (SingleNameReference) binaryExpression.left;
2901
						Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
2902
						if(b instanceof ReferenceBinding) {
2903
							TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
2904
							if(typeVariableBindings != null && typeVariableBindings.length > 0) {
2905
								addExpectedType(typeVariableBindings[0].firstBound, scope);
2906
							}
2853
2907
2854
		int enumConstantLength = enumConstantName.length;
2908
						}
2855
		next : for (int f = fields.length; --f >= 0;) {
2909
					}
2856
			FieldBinding field = fields[f];
2910
				}
2911
			} else if(parent instanceof UnaryExpression) {
2912
				switch(operator) {
2913
					case OperatorIds.NOT :
2914
						addExpectedType(TypeBinding.BOOLEAN, scope);
2915
						break;
2916
					case OperatorIds.TWIDDLE :
2917
						addExpectedType(TypeBinding.SHORT, scope);
2918
						addExpectedType(TypeBinding.INT, scope);
2919
						addExpectedType(TypeBinding.LONG, scope);
2920
						addExpectedType(TypeBinding.CHAR, scope);
2921
						addExpectedType(TypeBinding.BYTE, scope);
2922
						break;
2923
					case OperatorIds.PLUS :
2924
					case OperatorIds.MINUS :
2925
					case OperatorIds.PLUS_PLUS :
2926
					case OperatorIds.MINUS_MINUS :
2927
						addExpectedType(TypeBinding.SHORT, scope);
2928
						addExpectedType(TypeBinding.INT, scope);
2929
						addExpectedType(TypeBinding.LONG, scope);
2930
						addExpectedType(TypeBinding.FLOAT, scope);
2931
						addExpectedType(TypeBinding.DOUBLE, scope);
2932
						addExpectedType(TypeBinding.CHAR, scope);
2933
						addExpectedType(TypeBinding.BYTE, scope);
2934
						break;
2935
				}
2936
			}
2937
		} else if(parent instanceof ArrayReference) {
2938
			addExpectedType(TypeBinding.SHORT, scope);
2939
			addExpectedType(TypeBinding.INT, scope);
2940
			addExpectedType(TypeBinding.LONG, scope);
2941
		} else if(parent instanceof ParameterizedSingleTypeReference) {
2942
			ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
2943
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2944
			int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
2945
			if(typeVariables != null && typeVariables.length >= length) {
2946
				int index = length - 1;
2947
				while(index > -1 && ref.typeArguments[index] != node) index--;
2857
2948
2858
			if (field.isSynthetic()) continue next;
2949
				TypeBinding bound = typeVariables[index].firstBound;
2950
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2951
			}
2952
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
2953
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
2954
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
2955
			TypeReference[][] arguments = ref.typeArguments;
2956
			if(typeVariables != null) {
2957
				int iLength = arguments == null ? 0 : arguments.length;
2958
				done: for (int i = 0; i < iLength; i++) {
2959
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
2960
					for (int j = 0; j < jLength; j++) {
2961
						if(arguments[i][j] == node && typeVariables.length > j) {
2962
							TypeBinding bound = typeVariables[j].firstBound;
2963
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
2964
							break done;
2965
						}
2966
					}
2967
				}
2968
			}
2969
		} else if(parent instanceof MemberValuePair) {
2970
			MemberValuePair memberValuePair = (MemberValuePair) parent;
2971
			if(memberValuePair.binding != null) {
2972
				addExpectedType(memberValuePair.binding.returnType, scope);
2973
			}
2974
		} else if (parent instanceof NormalAnnotation) {
2975
			NormalAnnotation annotation = (NormalAnnotation) parent;
2976
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
2977
			if(memberValuePairs == null || memberValuePairs.length == 0) {
2978
				if(annotation.resolvedType instanceof ReferenceBinding) {
2979
					MethodBinding[] methodBindings =
2980
						((ReferenceBinding)annotation.resolvedType).availableMethods();
2981
					if (methodBindings != null &&
2982
							methodBindings.length > 0 &&
2983
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
2984
						boolean canBeSingleMemberAnnotation = true;
2985
						done : for (int i = 1; i < methodBindings.length; i++) {
2986
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
2987
								canBeSingleMemberAnnotation = false;
2988
								break done;
2989
							}
2990
						}
2991
						if (canBeSingleMemberAnnotation) {
2992
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
2993
							addExpectedType(methodBindings[0].returnType, scope);
2994
						}
2995
					}
2996
				}
2997
			}
2998
		} else if (parent instanceof TryStatement) {
2999
			boolean isException = false;
3000
			if (node instanceof CompletionOnSingleTypeReference) {
3001
				isException = ((CompletionOnSingleTypeReference)node).isException();
3002
			} else if (node instanceof CompletionOnQualifiedTypeReference) {
3003
				isException = ((CompletionOnQualifiedTypeReference)node).isException();
3004
			} else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
3005
				isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
3006
			}
3007
			if (isException) {
3008
				ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
3009
				ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
3010
				if (bindings != null && bindings.length > 0) {
3011
					for (int i = 0; i < bindings.length; i++) {
3012
						addExpectedType(bindings[i], scope);
3013
					}
3014
					this.expectedTypesFilter = SUPERTYPE;
3015
				}
3016
			}
3017
		} else if (parent instanceof SwitchStatement) {
3018
			SwitchStatement switchStatement = (SwitchStatement) parent;
3019
			if (switchStatement.expression != null &&
3020
					switchStatement.expression.resolvedType != null) {
3021
				addExpectedType(switchStatement.expression.resolvedType, scope);
3022
			}
2859
3023
2860
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
3024
		// Expected types for javadoc
3025
		} else if (parent instanceof Javadoc) {
3026
			if (scope.kind == Scope.METHOD_SCOPE) {
3027
				MethodScope methodScope = (MethodScope) scope;
3028
				AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
3029
				if (methodDecl != null && methodDecl.binding != null) {
3030
					ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
3031
					if (exceptions != null) {
3032
						for (int i = 0; i < exceptions.length; i++) {
3033
							addExpectedType(exceptions[i], scope);
3034
						}
3035
					}
3036
				}
3037
			}
3038
		}
2861
3039
2862
			if (enumConstantLength > field.name.length) continue next;
3040
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
3041
			System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
3042
		}
3043
	}
2863
3044
2864
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
3045
	private void computeExpectedTypesForAllocationExpression(
2865
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
3046
		ReferenceBinding binding,
3047
		Expression[] arguments,
3048
		Scope scope,
3049
		InvocationSite invocationSite) {
2866
3050
2867
			char[] fieldName = field.name;
3051
		MethodBinding[] methods = binding.availableMethods();
3052
		nextMethod : for (int i = 0; i < methods.length; i++) {
3053
			MethodBinding method = methods[i];
2868
3054
2869
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
3055
			if (!method.isConstructor()) continue nextMethod;
2870
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
2871
			}
2872
3056
2873
			int relevance = computeBaseRelevance();
3057
			if (method.isSynthetic()) continue nextMethod;
2874
			relevance += computeRelevanceForResolution();
2875
			relevance += computeRelevanceForInterestingProposal(field);
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
3058
2882
			this.noProposal = false;
3059
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
2883
			if (!needQualification) {
2884
				char[] completion = fieldName;
2885
3060
2886
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3061
			TypeBinding[] parameters = method.parameters;
2887
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3062
			if(parameters.length < arguments.length)
2888
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3063
				continue nextMethod;
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
3064
2906
			} else {
3065
			int length = arguments.length - 1;
2907
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
2908
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
2909
3066
2910
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
3067
			for (int j = 0; j < length; j++) {
3068
				Expression argument = arguments[j];
3069
				TypeBinding argType = argument.resolvedType;
3070
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
3071
					continue nextMethod;
3072
			}
2911
3073
2912
				if (!needImport) {
3074
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2913
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
3075
			if(expectedType != null) {
2914
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3076
				addExpectedType(expectedType, scope);
2915
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
3077
			}
2916
						proposal.setSignature(getSignature(field.type));
3078
		}
2917
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3079
	}
2918
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3080
	private void computeExpectedTypesForMessageSend(
2919
						proposal.setPackageName(field.type.qualifiedPackageName());
3081
		ReferenceBinding binding,
2920
						proposal.setTypeName(field.type.qualifiedSourceName());
3082
		char[] selector,
2921
						proposal.setName(field.name);
3083
		Expression[] arguments,
2922
						proposal.setCompletion(completion);
3084
		ReferenceBinding receiverType,
2923
						proposal.setFlags(field.modifiers);
3085
		Scope scope,
2924
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3086
		InvocationSite invocationSite,
2925
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3087
		boolean isStatic) {
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
3088
2938
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
3089
		MethodBinding[] methods = binding.availableMethods();
3090
		nextMethod : for (int i = 0; i < methods.length; i++) {
3091
			MethodBinding method = methods[i];
2939
3092
2940
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3093
			if (method.isSynthetic()) continue nextMethod;
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 (method.isDefaultAbstract())	continue nextMethod;
2955
3096
2956
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
3097
			if (method.isConstructor()) continue nextMethod;
2957
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
2958
						typeImportProposal.completionEngine = this;
2959
						char[] packageName = fieldType.qualifiedPackageName();
2960
						typeImportProposal.setDeclarationSignature(packageName);
2961
						typeImportProposal.setSignature(getSignature(fieldType));
2962
						typeImportProposal.setPackageName(packageName);
2963
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
2964
						typeImportProposal.setCompletion(typeImportCompletion);
2965
						typeImportProposal.setFlags(fieldType.modifiers);
2966
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
2967
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
2968
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
2969
						typeImportProposal.setRelevance(relevance);
2970
3098
2971
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
3099
			if (isStatic && !method.isStatic()) continue nextMethod;
2972
3100
2973
						this.requestor.accept(proposal);
3101
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
2974
						if(DEBUG) {
3102
2975
							this.printDebug(proposal);
3103
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
2976
						}
3104
2977
					}
3105
			TypeBinding[] parameters = method.parameters;
2978
				}
3106
			if(parameters.length < arguments.length)
3107
				continue nextMethod;
3108
3109
			int length = arguments.length - 1;
3110
3111
			for (int j = 0; j < length; j++) {
3112
				Expression argument = arguments[j];
3113
				TypeBinding argType = argument.resolvedType;
3114
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
3115
					continue nextMethod;
2979
			}
3116
			}
2980
		}
2981
	}
2982
3117
2983
	private void findEnumConstantsFromExpectedTypes(
3118
			TypeBinding expectedType = method.parameters[arguments.length - 1];
2984
			char[] token,
3119
			if(expectedType != null) {
2985
			Scope invocationScope,
3120
				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
			}
3121
			}
2999
		}
3122
		}
3000
3001
	}
3123
	}
3124
	private void computeExpectedTypesForMessageSendForInterface(
3125
		ReferenceBinding binding,
3126
		char[] selector,
3127
		Expression[] arguments,
3128
		ReferenceBinding receiverType,
3129
		Scope scope,
3130
		InvocationSite invocationSite,
3131
		boolean isStatic) {
3002
3132
3003
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
3133
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
3004
		TypeBinding expressionType = switchStatement.expression.resolvedType;
3134
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3005
		if(expressionType != null && expressionType.isEnum()) {
3135
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
3006
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
3136
			int nextPosition = interfacesToVisit.length;
3007
3137
3008
			CaseStatement[] cases = switchStatement.cases;
3138
			for (int i = 0; i < nextPosition; i++) {
3139
				ReferenceBinding currentType = interfacesToVisit[i];
3140
				computeExpectedTypesForMessageSend(
3141
					currentType,
3142
					selector,
3143
					arguments,
3144
					receiverType,
3145
					scope,
3146
					invocationSite,
3147
					isStatic);
3009
3148
3010
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
3149
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
3011
			int alreadyUsedConstantCount = 0;
3150
					int itsLength = itsInterfaces.length;
3012
			for (int i = 0; i < switchStatement.caseCount; i++) {
3151
					if (nextPosition + itsLength >= interfacesToVisit.length)
3013
				Expression caseExpression = cases[i].constantExpression;
3152
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3014
				if((caseExpression instanceof SingleNameReference)
3153
					nextInterface : for (int a = 0; a < itsLength; a++) {
3015
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
3154
						ReferenceBinding next = itsInterfaces[a];
3016
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
3155
						for (int b = 0; b < nextPosition; b++)
3156
							if (next == interfacesToVisit[b]) continue nextInterface;
3157
						interfacesToVisit[nextPosition++] = next;
3158
					}
3017
				}
3159
				}
3018
			}
3160
			}
3019
3020
			findEnumConstants(
3021
					enumConstantName,
3022
					enumType,
3023
					null /* doesn't need invocation scope */,
3024
					new ObjectVector(),
3025
					alreadyUsedConstants,
3026
					alreadyUsedConstantCount,
3027
					false);
3028
		}
3161
		}
3029
	}
3162
	}
3030
3163
3031
	private void findExceptionFromTryStatement(
3164
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
3032
			char[] typeName,
3165
		this.forbbidenBindingsFilter = NONE;
3033
			ReferenceBinding exceptionType,
3166
		if(scope instanceof ClassScope) {
3034
			ReferenceBinding receiverType,
3167
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
3035
			SourceTypeBinding invocationType,
3168
			if(typeDeclaration.superclass == astNode) {
3036
			BlockScope scope,
3169
				addForbiddenBindings(typeDeclaration.binding);
3037
			ObjectVector typesFound,
3170
				return scope.parent;
3038
			boolean searchSuperClasses) {
3171
			}
3039
3172
			TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
3040
		if (searchSuperClasses) {
3173
			int length = superInterfaces == null ? 0 : superInterfaces.length;
3041
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
3174
			for (int i = 0; i < length; i++) {
3042
			if (exceptionType != javaLangThrowable) {
3175
				if(superInterfaces[i] == astNode) {
3043
				ReferenceBinding superClass = exceptionType.superclass();
3176
					addForbiddenBindings(typeDeclaration.binding);
3044
				while(superClass != null && superClass != javaLangThrowable) {
3177
					return scope.parent;
3045
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
3046
					superClass = superClass.superclass();
3047
				}
3178
				}
3048
			}
3179
			}
3049
		}
3180
		} else {
3050
3181
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
3051
		if (typeName.length > exceptionType.sourceName.length)
3182
				boolean isException = false;
3052
			return;
3183
				if (astNode instanceof CompletionOnSingleTypeReference) {
3053
3184
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
3054
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
3185
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
3055
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
3186
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
3056
			return;
3187
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
3057
3188
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
3058
		if (this.options.checkDeprecation &&
3189
				}
3059
				exceptionType.isViewedAsDeprecated() &&
3190
				if (isException) {
3060
				!scope.isDefinedInSameUnit(exceptionType))
3191
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
3061
			return;
3192
					int length = catchArguments == null ? 0 : catchArguments.length;
3062
3193
					for (int i = 0; i < length; i++) {
3063
		if (this.options.checkVisibility) {
3194
						TypeBinding caughtException = catchArguments[i].type.resolvedType;
3064
			if (invocationType != null) {
3195
						if (caughtException != null) {
3065
				if (receiverType != null) {
3196
							addForbiddenBindings(caughtException);
3066
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
3197
							this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
3067
				} else {
3198
						}
3068
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
3199
					}
3200
					this.forbbidenBindingsFilter = SUBTYPE;
3069
				}
3201
				}
3070
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
3071
				return;
3072
			}
3202
			}
3073
		}
3203
		}
3204
//		else if(scope instanceof MethodScope) {
3205
//			MethodScope methodScope = (MethodScope) scope;
3206
//			if(methodScope.insideTypeAnnotation) {
3207
//				return methodScope.parent.parent;
3208
//			}
3209
//		}
3210
		return scope;
3211
	}
3074
3212
3075
		for (int j = typesFound.size; --j >= 0;) {
3213
	private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
3076
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
3077
3214
3078
			if (exceptionType == otherType)
3215
		StringBuffer completion = new StringBuffer(10);
3079
				return;
3080
3216
3081
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
3217
		if (isStatic) {
3218
			completion.append(declarationType.sourceName());
3082
3219
3083
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
3220
		} else if (declarationType == invocationType) {
3084
					return;
3221
			completion.append(THIS);
3085
3222
3086
				if (otherType.enclosingType().isInterface())
3223
		} else {
3087
					if (exceptionType.enclosingType()
3088
						.implementsInterface(otherType.enclosingType(), true))
3089
						return;
3090
3091
				if (exceptionType.enclosingType().isInterface())
3092
					if (otherType.enclosingType()
3093
						.implementsInterface(exceptionType.enclosingType(), true))
3094
						return;
3095
			}
3096
		}
3097
3098
		typesFound.add(exceptionType);
3099
3224
3100
		char[] completionName = exceptionType.sourceName();
3225
			if (!declarationType.isNestedType()) {
3101
3226
3102
		boolean isQualified = false;
3227
				completion.append(declarationType.sourceName());
3228
				completion.append('.');
3229
				completion.append(THIS);
3103
3230
3104
		if(!this.insideQualifiedReference) {
3231
			} else if (!declarationType.isAnonymousType()) {
3105
			isQualified = true;
3106
3232
3107
			char[] memberPackageName = exceptionType.qualifiedPackageName();
3233
				completion.append(declarationType.sourceName());
3108
			char[] memberTypeName = exceptionType.sourceName();
3234
				completion.append('.');
3109
			char[] memberEnclosingTypeNames = null;
3235
				completion.append(THIS);
3110
3236
3111
			ReferenceBinding enclosingType = exceptionType.enclosingType();
3112
			if (enclosingType != null) {
3113
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
3114
			}
3237
			}
3238
		}
3115
3239
3116
			Scope currentScope = scope;
3240
		return completion.toString().toCharArray();
3117
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
3241
	}
3118
3119
				switch (currentScope.kind) {
3120
3121
					case Scope.METHOD_SCOPE :
3122
					case Scope.BLOCK_SCOPE :
3123
						BlockScope blockScope = (BlockScope) currentScope;
3124
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
3242
3152
						break;
3243
	private int computeRelevanceForAnnotation(){
3244
		if(this.assistNodeIsAnnotation) {
3245
			return R_ANNOTATION;
3246
		}
3247
		return 0;
3248
	}
3153
3249
3154
					case Scope.COMPILATION_UNIT_SCOPE :
3250
	private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
3155
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
3251
		if (this.assistNodeIsAnnotation &&
3156
						if (types != null) {
3252
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
3157
							for (int j = 0; j < types.length; j++) {
3253
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
3158
								if (types[j] == exceptionType) {
3254
			if(target == 0 || (target & this.targetedElement) != 0) {
3159
									isQualified = false;
3255
				return R_TARGET;
3160
									break done;
3161
								}
3162
							}
3163
						}
3164
						break done;
3165
				}
3166
				currentScope = currentScope.parent;
3167
			}
3256
			}
3168
3257
		}
3169
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
3258
		return 0;
3170
				if (memberPackageName == null || memberPackageName.length == 0)
3259
	}
3171
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
3260
	int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
3172
						return; // ignore types from the default package from outside it
3261
		if (this.options.camelCaseMatch) {
3173
			} else {
3262
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3174
				isQualified = false;
3263
				return R_CASE + R_EXACT_NAME;
3264
			} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3265
				return R_CASE;
3266
			} else if (CharOperation.camelCaseMatch(token, proposalName)){
3267
				return R_CAMEL_CASE;
3268
			} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3269
				return R_EXACT_NAME;
3175
			}
3270
			}
3176
3271
		} else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
3177
			if (isQualified) {
3272
			if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
3178
				completionName =
3273
				return R_CASE + R_EXACT_NAME;
3179
					CharOperation.concat(
3274
			} else {
3180
							memberPackageName,
3275
				return R_CASE;
3181
							CharOperation.concat(
3182
									memberEnclosingTypeNames,
3183
									memberTypeName,
3184
									'.'),
3185
							'.');
3186
			}
3276
			}
3277
		} else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
3278
			return R_EXACT_NAME;
3187
		}
3279
		}
3280
		return 0;
3281
	}
3188
3282
3189
		int relevance = computeBaseRelevance();
3283
	private int computeRelevanceForClass(){
3190
		relevance += computeRelevanceForResolution();
3284
		if(this.assistNodeIsClass) {
3191
		relevance += computeRelevanceForInterestingProposal();
3285
			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
		}
3286
		}
3198
		relevance += computeRelevanceForClass();
3287
		return 0;
3199
		relevance += computeRelevanceForException();
3288
	}
3200
3289
3201
		this.noProposal = false;
3290
	private int computeRelevanceForEnum(){
3202
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3291
		if(this.assistNodeIsEnum) {
3203
			createTypeProposal(
3292
			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
		}
3293
		}
3294
		return 0;
3214
	}
3295
	}
3215
3296
3216
	private void findExceptionFromTryStatement(
3297
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
3217
			char[] typeName,
3298
		if(this.assistNodeIsEnum &&
3218
			ReferenceBinding receiverType,
3299
				proposalType != null &&
3219
			SourceTypeBinding invocationType,
3300
				this.expectedTypes != null) {
3220
			BlockScope scope,
3301
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3221
			ObjectVector typesFound) {
3302
				if (proposalType.isEnum() &&
3222
3303
						proposalType == this.expectedTypes[i]) {
3223
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
3304
					return R_ENUM + R_ENUM_CONSTANT;
3224
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
3305
				}
3225
3306
3226
			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
3307
			}
3227
		}
3308
		}
3309
		return 0;
3228
	}
3310
	}
3229
	private void findExplicitConstructors(
3230
		char[] name,
3231
		ReferenceBinding currentType,
3232
		MethodScope scope,
3233
		InvocationSite invocationSite) {
3234
3311
3235
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
3312
	private int computeRelevanceForException(){
3236
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
3313
		if (this.assistNodeIsException) {
3237
3314
			return R_EXCEPTION;
3238
		// No visibility checks can be performed without the scope & invocationSite
3315
		}
3239
		MethodBinding[] methods = currentType.availableMethods();
3316
		return 0;
3240
		if(methods != null) {
3317
	}
3241
			next : for (int f = methods.length; --f >= 0;) {
3242
				MethodBinding constructor = methods[f];
3243
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
3244
3318
3245
					if (constructor.isSynthetic()) continue next;
3319
	private int computeRelevanceForException(char[] proposalName){
3246
3320
3247
					if (this.options.checkDeprecation &&
3321
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
3248
							constructor.isViewedAsDeprecated() &&
3322
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
3249
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3323
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
3250
						continue next;
3324
			return R_EXCEPTION;
3325
		}
3326
		return 0;
3327
	}
3251
3328
3252
					if (this.options.checkVisibility
3329
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
3253
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
3330
		if(this.expectedTypes != null) {
3331
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3332
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
3333
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
3334
					return R_EXACT_EXPECTED_TYPE;
3335
				}
3336
			}
3337
			if(this.hasJavaLangObjectAsExpectedType) {
3338
				return R_EXPECTED_TYPE;
3339
			}
3340
		}
3341
		return 0;
3342
	}
3254
3343
3255
					TypeBinding[] parameters = constructor.parameters;
3344
	private int computeRelevanceForExpectingType(TypeBinding proposalType){
3256
					int paramLength = parameters.length;
3345
		if(this.expectedTypes != null && proposalType != null) {
3346
			int relevance = 0;
3347
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
3348
				if((this.expectedTypesFilter & SUBTYPE) != 0
3349
						&& proposalType.isCompatibleWith(this.expectedTypes[i])) {
3257
3350
3258
					char[][] parameterPackageNames = new char[paramLength][];
3351
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3259
					char[][] parameterTypeNames = new char[paramLength][];
3352
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3260
					for (int i = 0; i < paramLength; i++) {
3353
						return R_EXACT_EXPECTED_TYPE;
3261
						TypeBinding type = parameters[i];
3262
						parameterPackageNames[i] = type.qualifiedPackageName();
3263
						parameterTypeNames[i] = type.qualifiedSourceName();
3264
					}
3354
					}
3265
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3266
3355
3267
					char[] completion = CharOperation.NO_CHAR;
3356
					relevance = R_EXPECTED_TYPE;
3268
					if (this.source != null
3357
				}
3269
						&& this.source.length > this.endPosition
3358
				if((this.expectedTypesFilter & SUPERTYPE) != 0
3270
						&& this.source[this.endPosition] == '(')
3359
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
3271
						completion = name;
3272
					else
3273
						completion = CharOperation.concat(name, new char[] { '(', ')' });
3274
3275
					int relevance = computeBaseRelevance();
3276
					relevance += computeRelevanceForResolution();
3277
					relevance += computeRelevanceForInterestingProposal();
3278
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
3279
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3280
3360
3281
					this.noProposal = false;
3361
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
3282
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
3362
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
3283
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3363
						return R_EXACT_EXPECTED_TYPE;
3284
						proposal.setDeclarationSignature(getSignature(currentType));
3285
						proposal.setSignature(getSignature(constructor));
3286
						MethodBinding original = constructor.original();
3287
						if(original != constructor) {
3288
							proposal.setOriginalSignature(getSignature(original));
3289
						}
3290
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3291
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3292
						proposal.setParameterPackageNames(parameterPackageNames);
3293
						proposal.setParameterTypeNames(parameterTypeNames);
3294
						//proposal.setPackageName(null);
3295
						//proposal.setTypeName(null);
3296
						proposal.setName(name);
3297
						proposal.setIsContructor(true);
3298
						proposal.setCompletion(completion);
3299
						proposal.setFlags(constructor.modifiers);
3300
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3301
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3302
						proposal.setRelevance(relevance);
3303
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
3304
						this.requestor.accept(proposal);
3305
						if(DEBUG) {
3306
							this.printDebug(proposal);
3307
						}
3308
					}
3364
					}
3365
3366
					relevance = R_EXPECTED_TYPE;
3309
				}
3367
				}
3310
			}
3368
			}
3369
			return relevance;
3311
		}
3370
		}
3371
		return 0;
3312
	}
3372
	}
3313
	private void findConstructors(
3314
		ReferenceBinding currentType,
3315
		TypeBinding[] argTypes,
3316
		Scope scope,
3317
		InvocationSite invocationSite,
3318
		boolean forAnonymousType) {
3319
3373
3320
		// No visibility checks can be performed without the scope & invocationSite
3374
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
3321
		MethodBinding[] methods = currentType.availableMethods();
3375
		if (receiverType == declaringClass) return R_NON_INHERITED;
3322
		if(methods != null) {
3376
		return 0;
3323
			int minArgLength = argTypes == null ? 0 : argTypes.length;
3377
	}
3324
			next : for (int f = methods.length; --f >= 0;) {
3325
				MethodBinding constructor = methods[f];
3326
				if (constructor.isConstructor()) {
3327
3378
3328
					if (constructor.isSynthetic()) continue next;
3379
	int computeRelevanceForInterestingProposal(){
3380
		return computeRelevanceForInterestingProposal(null);
3381
	}
3329
3382
3330
					if (this.options.checkDeprecation &&
3383
	private int computeRelevanceForInterestingProposal(Binding binding){
3331
							constructor.isViewedAsDeprecated() &&
3384
		if(this.uninterestingBindings != null) {
3332
							!scope.isDefinedInSameUnit(constructor.declaringClass))
3385
			for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
3333
						continue next;
3386
				if(this.uninterestingBindings[i] == binding) {
3387
					return 0;
3388
				}
3389
			}
3390
		}
3391
		return R_INTERESTING;
3392
	}
3334
3393
3335
					if (this.options.checkVisibility
3394
	private int computeRelevanceForInterface(){
3336
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
3395
		if(this.assistNodeIsInterface) {
3337
						if(!forAnonymousType || !constructor.isProtected())
3396
			return R_INTERFACE;
3338
							continue next;
3397
		}
3339
					}
3398
		return 0;
3399
	}
3340
3400
3341
					TypeBinding[] parameters = constructor.parameters;
3401
	private int computeRelevanceForMissingElements(boolean hasProblems) {
3342
					int paramLength = parameters.length;
3402
		if (!hasProblems) {
3343
					if (minArgLength > paramLength)
3403
			return R_NO_PROBLEMS;
3344
						continue next;
3404
		}
3345
					for (int a = minArgLength; --a >= 0;)
3405
		return 0;
3346
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
3406
	}
3347
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
3407
	int computeRelevanceForQualification(boolean prefixRequired) {
3348
								continue next;
3408
		if(!prefixRequired && !this.insideQualifiedReference) {
3349
						}
3409
			return R_UNQUALIFIED;
3410
		}
3350
3411
3351
					char[][] parameterPackageNames = new char[paramLength][];
3412
		if(prefixRequired && this.insideQualifiedReference) {
3352
					char[][] parameterTypeNames = new char[paramLength][];
3413
			return R_QUALIFIED;
3353
					for (int i = 0; i < paramLength; i++) {
3414
		}
3354
						TypeBinding type = parameters[i];
3415
		return 0;
3355
						parameterPackageNames[i] = type.qualifiedPackageName();
3416
	}
3356
						parameterTypeNames[i] = type.qualifiedSourceName();
3357
					}
3358
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
3359
3417
3360
					char[] completion = CharOperation.NO_CHAR;
3418
	int computeRelevanceForResolution(){
3361
					if(forAnonymousType){
3419
		return computeRelevanceForResolution(true);
3362
						int relevance = computeBaseRelevance();
3420
	}
3363
						relevance += computeRelevanceForResolution();
3364
						relevance += computeRelevanceForInterestingProposal();
3365
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3366
3421
3367
						this.noProposal = false;
3422
	int computeRelevanceForResolution(boolean isResolved){
3368
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
3423
		if (isResolved) {
3369
							InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
3424
			return R_RESOLVED;
3370
							proposal.setDeclarationSignature(getSignature(currentType));
3425
		}
3371
							proposal.setDeclarationKey(currentType.computeUniqueKey());
3426
		return 0;
3372
							proposal.setSignature(getSignature(constructor));
3427
	}
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
3428
3401
						// Special case for completion in javadoc
3429
	int computeRelevanceForRestrictions(int accessRuleKind) {
3402
						if (this.assistNodeInJavadoc > 0) {
3430
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
3403
							Expression receiver = null;
3431
			return R_NON_RESTRICTED;
3404
							char[] selector = null;
3432
		}
3405
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
3433
		return 0;
3406
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
3434
	}
3407
								receiver = alloc.type;
3408
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3409
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3410
								receiver = fieldRef.receiver;
3411
							}
3412
							if (receiver != null) {
3413
								StringBuffer javadocCompletion = new StringBuffer();
3414
								if (receiver.isThis()) {
3415
									selector = (((JavadocImplicitTypeReference)receiver).token);
3416
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3417
										javadocCompletion.append('#');
3418
									}
3419
								} else if (receiver instanceof JavadocSingleTypeReference) {
3420
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
3421
									selector = typeRef.token;
3422
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3423
										javadocCompletion.append(typeRef.token);
3424
										javadocCompletion.append('#');
3425
									}
3426
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
3427
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
3428
									selector = typeRef.tokens[typeRef.tokens.length-1];
3429
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
3430
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
3431
										javadocCompletion.append('#');
3432
									}
3433
								}
3434
								// Append parameters types
3435
								javadocCompletion.append(selector);
3436
								javadocCompletion.append('(');
3437
								if (constructor.parameters != null) {
3438
									boolean isVarargs = constructor.isVarargs();
3439
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
3440
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
3441
										TypeBinding argTypeBinding = constructor.parameters[p];
3442
										if (isVarargs && p == ln - 1)  {
3443
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
3444
										} else {
3445
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
3446
										}
3447
									}
3448
								}
3449
								javadocCompletion.append(')');
3450
								completion = javadocCompletion.toString().toCharArray();
3451
							}
3452
						}
3453
3435
3454
						// Create standard proposal
3436
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
3455
						this.noProposal = false;
3437
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
3456
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3438
			return R_NON_STATIC;
3457
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
3458
							proposal.setDeclarationSignature(getSignature(currentType));
3459
							proposal.setSignature(getSignature(constructor));
3460
							MethodBinding original = constructor.original();
3461
							if(original != constructor) {
3462
								proposal.setOriginalSignature(getSignature(original));
3463
							}
3464
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3465
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3466
							proposal.setParameterPackageNames(parameterPackageNames);
3467
							proposal.setParameterTypeNames(parameterTypeNames);
3468
							//proposal.setPackageName(null);
3469
							//proposal.setTypeName(null);
3470
							proposal.setName(currentType.sourceName());
3471
							proposal.setIsContructor(true);
3472
							proposal.setCompletion(completion);
3473
							proposal.setFlags(constructor.modifiers);
3474
							int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
3475
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3476
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3477
							proposal.setRelevance(relevance);
3478
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
3479
							this.requestor.accept(proposal);
3480
							if(DEBUG) {
3481
								this.printDebug(proposal);
3482
							}
3483
						}
3484
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
3485
							char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3486
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
3487
							proposal.setDeclarationSignature(getSignature(currentType));
3488
							proposal.setSignature(getSignature(constructor));
3489
							MethodBinding original = constructor.original();
3490
							if(original != constructor) {
3491
								proposal.setOriginalSignature(getSignature(original));
3492
							}
3493
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3494
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3495
							proposal.setParameterPackageNames(parameterPackageNames);
3496
							proposal.setParameterTypeNames(parameterTypeNames);
3497
							//proposal.setPackageName(null);
3498
							//proposal.setTypeName(null);
3499
							proposal.setName(currentType.sourceName());
3500
							proposal.setIsContructor(true);
3501
							proposal.setCompletion(javadocCompletion);
3502
							proposal.setFlags(constructor.modifiers);
3503
							int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3504
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3505
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3506
							proposal.setRelevance(relevance+R_INLINE_TAG);
3507
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
3508
							this.requestor.accept(proposal);
3509
							if(DEBUG) {
3510
								this.printDebug(proposal);
3511
							}
3512
						}
3513
					}
3514
				}
3515
			}
3516
		}
3439
		}
3440
		return 0;
3517
	}
3441
	}
3518
3442
3519
	private char[][] findEnclosingTypeNames(Scope scope){
3443
	private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
3520
		char[][] excludedNames = new char[10][];
3444
		ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
3521
		int excludedNameCount = 0;
3522
3523
		Scope currentScope = scope;
3524
		while(currentScope != null) {
3525
			switch (currentScope.kind) {
3526
				case Scope.CLASS_SCOPE :
3527
					ClassScope classScope = (ClassScope) currentScope;
3528
3529
					TypeDeclaration typeDeclaration = classScope.referenceContext;
3530
3531
					if(excludedNameCount == excludedNames.length) {
3532
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
3533
					}
3534
					excludedNames[excludedNameCount++] = typeDeclaration.name;
3535
3445
3536
					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
3446
		if (annotatedElement instanceof TypeDeclaration) {
3537
					if(classTypeParameters != null) {
3447
			TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
3538
						for (int i = 0; i < classTypeParameters.length; i++) {
3448
			if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
3539
							TypeParameter typeParameter = classTypeParameters[i];
3449
				return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
3540
							if(excludedNameCount == excludedNames.length) {
3450
			}
3541
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
3451
			return TagBits.AnnotationForType;
3542
							}
3452
		} else if (annotatedElement instanceof FieldDeclaration) {
3543
							excludedNames[excludedNameCount++] = typeParameter.name;
3453
			if (fakeNode.isParameter) {
3544
						}
3454
				return TagBits.AnnotationForParameter;
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
			}
3455
			}
3456
			return TagBits.AnnotationForField;
3457
		} else if (annotatedElement instanceof MethodDeclaration) {
3458
			return TagBits.AnnotationForMethod;
3459
		} else if (annotatedElement instanceof Argument) {
3460
			return TagBits.AnnotationForParameter;
3461
		} else if (annotatedElement instanceof ConstructorDeclaration) {
3462
			return TagBits.AnnotationForConstructor;
3463
		} else if (annotatedElement instanceof LocalDeclaration) {
3464
			return TagBits.AnnotationForLocalVariable;
3465
		} else if (annotatedElement instanceof ImportReference) {
3466
			return TagBits.AnnotationForPackage;
3467
		}
3468
		return 0;
3469
	}
3470
	private TypeBinding[] computeTypes(Expression[] arguments) {
3471
		if (arguments == null) return null;
3472
		int argsLength = arguments.length;
3473
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3474
		for (int a = argsLength; --a >= 0;) {
3475
			argTypes[a] = arguments[a].resolvedType;
3476
		}
3477
		return argTypes;
3478
	}
3563
3479
3564
			currentScope = currentScope.parent;
3480
	private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
3481
		if (arguments == null) return null;
3482
		int argsLength = arguments.length;
3483
		TypeBinding[] argTypes = new TypeBinding[argsLength];
3484
		for (int a = argsLength; --a >= 0;) {
3485
			TypeBinding typeBinding = arguments[a].resolvedType;
3486
			if(typeBinding == null || !typeBinding.isValidBinding()) return null;
3487
			argTypes[a] = typeBinding;
3565
		}
3488
		}
3489
		return argTypes;
3490
	}
3566
3491
3567
		if(excludedNameCount == 0) {
3492
	private void computeUninterestingBindings(ASTNode parent, Scope scope){
3568
			return CharOperation.NO_CHAR_CHAR;
3493
		if(parent instanceof LocalDeclaration) {
3494
			addUninterestingBindings(((LocalDeclaration)parent).binding);
3495
		} else if (parent instanceof FieldDeclaration) {
3496
			addUninterestingBindings(((FieldDeclaration)parent).binding);
3569
		}
3497
		}
3570
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
3571
		return excludedNames;
3572
	}
3498
	}
3573
3499
3574
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
3500
	private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
3575
	private void findFields(
3501
		char[] result = IMPORT;
3576
		char[] fieldName,
3502
		if (isStatic) {
3577
		FieldBinding[] fields,
3503
			result = CharOperation.concat(result, STATIC, ' ');
3578
		Scope scope,
3504
		}
3579
		ObjectVector fieldsFound,
3505
		result = CharOperation.concat(result, importedElement, ' ');
3580
		ObjectVector localsFound,
3506
		if (onDemand) {
3581
		boolean onlyStaticFields,
3507
			result = CharOperation.concat(result, ON_DEMAND);
3582
		ReferenceBinding receiverType,
3508
		}
3583
		InvocationSite invocationSite,
3509
		return CharOperation.concat(result, IMPORT_END);
3584
		Scope invocationScope,
3510
	}
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
3511
3595
		ObjectVector newFieldsFound = new ObjectVector();
3512
	private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
3596
		// Inherited fields which are hidden by subclasses are filtered out
3513
		//// Modifiers
3597
		// No visibility checks can be performed without the scope & invocationSite
3514
		// flush uninteresting modifiers
3515
		int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
3516
		if(insertedModifiers != ClassFileConstants.AccDefault){
3517
			ASTNode.printModifiers(insertedModifiers, completion);
3518
		}
3598
3519
3599
		int fieldLength = fieldName.length;
3520
		//// Type parameters
3600
		next : for (int f = fields.length; --f >= 0;) {
3601
			FieldBinding field = fields[f];
3602
3521
3603
			if (field.isSynthetic())	continue next;
3522
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
3523
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
3524
			completion.append('<');
3525
			for (int i = 0; i < typeVariableBindings.length; i++) {
3526
				if(i != 0) {
3527
					completion.append(',');
3528
					completion.append(' ');
3529
				}
3530
				createTypeVariable(typeVariableBindings[i], scope, completion);
3531
			}
3532
			completion.append('>');
3533
			completion.append(' ');
3534
		}
3604
3535
3605
			if (onlyStaticFields && !field.isStatic()) continue next;
3536
		//// Return type
3537
		createType(method.returnType, scope, completion);
3538
		completion.append(' ');
3606
3539
3607
			if (fieldLength > field.name.length) continue next;
3540
		//// Selector
3541
		completion.append(method.selector);
3608
3542
3609
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
3543
		completion.append('(');
3610
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
3611
3544
3612
			if (this.options.checkDeprecation &&
3545
		////Parameters
3613
					field.isViewedAsDeprecated() &&
3546
		TypeBinding[] parameterTypes = method.parameters;
3614
					!scope.isDefinedInSameUnit(field.declaringClass))
3547
		int length = parameterTypes.length;
3615
				continue next;
3548
		for (int i = 0; i < length; i++) {
3549
			if(i != 0) {
3550
				completion.append(',');
3551
				completion.append(' ');
3552
			}
3553
			createType(parameterTypes[i], scope, completion);
3554
			completion.append(' ');
3555
			if(parameterNames != null){
3556
				completion.append(parameterNames[i]);
3557
			} else {
3558
				completion.append('%');
3559
			}
3560
		}
3616
3561
3617
			if (this.options.checkVisibility
3562
		completion.append(')');
3618
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
3619
3563
3620
			boolean prefixRequired = false;
3564
		//// Exceptions
3565
		ReferenceBinding[] exceptions = method.thrownExceptions;
3621
3566
3622
			for (int i = fieldsFound.size; --i >= 0;) {
3567
		if (exceptions != null && exceptions.length > 0){
3623
				Object[] other = (Object[])fieldsFound.elementAt(i);
3568
			completion.append(' ');
3624
				FieldBinding otherField = (FieldBinding) other[0];
3569
			completion.append(THROWS);
3625
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
3570
			completion.append(' ');
3626
				if (field == otherField && receiverType == otherReceiverType)
3571
			for(int i = 0; i < exceptions.length ; i++){
3627
					continue next;
3572
				if(i != 0) {
3628
				if (CharOperation.equals(field.name, otherField.name, true)) {
3573
					completion.append(' ');
3629
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
3574
					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
				}
3575
				}
3576
				createType(exceptions[i], scope, completion);
3646
			}
3577
			}
3578
		}
3579
	}
3647
3580
3648
			for (int l = localsFound.size; --l >= 0;) {
3581
	protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
3649
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
3582
		InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
3583
		proposal.nameLookup = this.nameEnvironment.nameLookup;
3584
		proposal.completionEngine = this;
3585
		return proposal;
3586
	}
3650
3587
3651
				if (CharOperation.equals(field.name, local.name, true)) {
3588
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
3652
					SourceTypeBinding declarationType = scope.enclosingSourceType();
3589
		InternalCompletionProposal proposal = null;
3653
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
3590
		if (binding instanceof ReferenceBinding) {
3654
						continue next;
3591
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
3655
					}
3656
					if(canBePrefixed) {
3657
						prefixRequired = true;
3658
					} else {
3659
						continue next;
3660
					}
3661
					break;
3662
				}
3663
			}
3664
3592
3665
			newFieldsFound.add(new Object[]{field, receiverType});
3593
			char[] packageName = typeBinding.qualifiedPackageName();
3594
			char[] typeName = typeBinding.qualifiedSourceName();
3595
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
3666
3596
3667
			char[] completion = field.name;
3597
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
3598
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3599
			proposal.completionEngine = this;
3600
			proposal.setDeclarationSignature(packageName);
3601
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
3602
			proposal.setPackageName(packageName);
3603
			proposal.setTypeName(typeName);
3604
			proposal.setCompletion(fullyQualifiedName);
3605
			proposal.setFlags(typeBinding.modifiers);
3606
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3607
			proposal.setTokenRange(start - this.offset, end - this.offset);
3608
			proposal.setRelevance(relevance);
3609
		} else if (binding instanceof PackageBinding) {
3610
			PackageBinding packageBinding = (PackageBinding) binding;
3668
3611
3669
			if(prefixRequired || this.options.forceImplicitQualification){
3612
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
3670
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
3671
				completion = CharOperation.concat(prefix,completion,'.');
3672
			}
3673
3613
3614
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
3615
			proposal.setDeclarationSignature(packageName);
3616
			proposal.setPackageName(packageName);
3617
			proposal.setCompletion(packageName);
3618
			proposal.setReplaceRange(start - this.offset, end - this.offset);
3619
			proposal.setTokenRange(start - this.offset, end - this.offset);
3620
			proposal.setRelevance(relevance);
3621
		}
3622
		return proposal;
3623
	}
3674
3624
3675
			if (castedReceiver != null) {
3625
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
3676
				completion = CharOperation.concat(castedReceiver, completion);
3626
		switch (type.kind()) {
3677
			}
3627
			case Binding.BASE_TYPE :
3628
				completion.append(type.sourceName());
3629
				break;
3630
			case Binding.WILDCARD_TYPE :
3631
			case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
3632
				WildcardBinding wildcardBinding = (WildcardBinding) type;
3633
				completion.append('?');
3634
				switch (wildcardBinding.boundKind) {
3635
					case Wildcard.EXTENDS:
3636
						completion.append(' ');
3637
						completion.append(EXTENDS);
3638
						completion.append(' ');
3639
						createType(wildcardBinding.bound, scope, completion);
3640
						if(wildcardBinding.otherBounds != null) {
3678
3641
3679
			// Special case for javadoc completion
3642
							int length = wildcardBinding.otherBounds.length;
3680
			if (this.assistNodeInJavadoc > 0) {
3643
							for (int i = 0; i < length; i++) {
3681
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
3644
								completion.append(' ');
3682
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
3645
								completion.append('&');
3683
					if (fieldRef.receiver.isThis()) {
3646
								completion.append(' ');
3684
						if (fieldRef.completeInText()) {
3647
								createType(wildcardBinding.otherBounds[i], scope, completion);
3685
							completion = CharOperation.concat(new char[] { '#' }, field.name);
3648
							}
3686
						}
3687
					} else if (fieldRef.completeInText()) {
3688
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
3689
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
3690
							completion = CharOperation.concat(typeRef.token, field.name, '#');
3691
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
3692
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
3693
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
3694
						}
3649
						}
3695
					}
3650
						break;
3651
					case Wildcard.SUPER:
3652
						completion.append(' ');
3653
						completion.append(SUPER);
3654
						completion.append(' ');
3655
						createType(wildcardBinding.bound, scope, completion);
3656
						break;
3657
				}
3658
				break;
3659
			case Binding.ARRAY_TYPE :
3660
				createType(type.leafComponentType(), scope, completion);
3661
				int dim = type.dimensions();
3662
				for (int i = 0; i < dim; i++) {
3663
					completion.append('[');
3664
					completion.append(']');
3696
				}
3665
				}
3666
				break;
3667
			case Binding.PARAMETERIZED_TYPE :
3668
				ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
3669
				if (type.isMemberType()) {
3670
					createType(parameterizedType.enclosingType(), scope, completion);
3671
					completion.append('.');
3672
					completion.append(parameterizedType.sourceName);
3673
				} else {
3674
					completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
3675
				}
3676
				if (parameterizedType.arguments != null) {
3677
					completion.append('<');
3678
				    for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
3679
				        if (i != 0) completion.append(',');
3680
				        createType(parameterizedType.arguments[i], scope, completion);
3681
				    }
3682
				    completion.append('>');
3683
				}
3684
				break;
3685
			default :
3686
				char[] packageName = type.qualifiedPackageName();
3687
			char[] typeName = type.qualifiedSourceName();
3688
			if(mustQualifyType(
3689
					(ReferenceBinding)type,
3690
					packageName,
3691
					scope)) {
3692
				completion.append(CharOperation.concat(packageName, typeName,'.'));
3693
			} else {
3694
				completion.append(type.sourceName());
3697
			}
3695
			}
3696
			break;
3697
		}
3698
	}
3698
3699
3699
			int relevance = computeBaseRelevance();
3700
	/*
3700
			relevance += computeRelevanceForResolution();
3701
	 * Create a completion proposal for a member type.
3701
			relevance += computeRelevanceForInterestingProposal(field);
3702
	 */
3702
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
3703
	private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
3703
			relevance += computeRelevanceForExpectingType(field.type);
3704
		char[] completionName = typeParameter.name;
3704
			relevance += computeRelevanceForEnumConstant(field.type);
3705
3705
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
3706
		// Create standard type proposal
3706
			relevance += computeRelevanceForQualification(prefixRequired);
3707
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
3707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
3708
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3708
			if (onlyStaticFields && this.insideQualifiedReference) {
3709
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3709
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
3710
			proposal.completionEngine = this;
3711
			proposal.setSignature(getSignature(typeParameter.binding));
3712
			proposal.setTypeName(completionName);
3713
			proposal.setCompletion(completionName);
3714
			proposal.setFlags(typeParameter.modifiers);
3715
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3716
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3717
			proposal.setRelevance(relevance);
3718
			this.requestor.accept(proposal);
3719
			if(DEBUG) {
3720
				this.printDebug(proposal);
3710
			}
3721
			}
3711
			if (missingElements != null) {
3722
		}
3712
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
3723
3724
		// Create javadoc text proposal if necessary
3725
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3726
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3727
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3728
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3729
			proposal.completionEngine = this;
3730
			proposal.setSignature(getSignature(typeParameter.binding));
3731
			proposal.setTypeName(javadocCompletion);
3732
			proposal.setCompletion(javadocCompletion);
3733
			proposal.setFlags(typeParameter.modifiers);
3734
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3735
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3736
			proposal.setRelevance(relevance+R_INLINE_TAG);
3737
			this.requestor.accept(proposal);
3738
			if(DEBUG) {
3739
				this.printDebug(proposal);
3713
			}
3740
			}
3741
		}
3742
	}
3714
3743
3715
			this.noProposal = false;
3744
	/*
3716
			if (castedReceiver == null) {
3745
	 * Create a completion proposal for a type.
3717
				// Standard proposal
3746
	 */
3718
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3747
	private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
3719
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
3720
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3721
					proposal.setSignature(getSignature(field.type));
3722
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3723
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3724
					proposal.setPackageName(field.type.qualifiedPackageName());
3725
					proposal.setTypeName(field.type.qualifiedSourceName());
3726
					proposal.setName(field.name);
3727
					if (missingElements != null) {
3728
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3729
						for (int i = 0; i < missingElements.length; i++) {
3730
							subProposals[i] =
3731
								createRequiredTypeProposal(
3732
										missingElements[i],
3733
										missingElementsStarts[i],
3734
										missingElementsEnds[i],
3735
										relevance);
3736
						}
3737
						proposal.setRequiredProposals(subProposals);
3738
					}
3739
					proposal.setCompletion(completion);
3740
					proposal.setFlags(field.modifiers);
3741
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3742
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3743
					proposal.setRelevance(relevance);
3744
					this.requestor.accept(proposal);
3745
					if(DEBUG) {
3746
						this.printDebug(proposal);
3747
					}
3748
				}
3749
3748
3750
				// Javadoc completions
3749
		// Create standard type proposal
3751
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
3750
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3752
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
3751
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3753
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
3752
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3754
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3753
			proposal.completionEngine = this;
3755
					proposal.setSignature(getSignature(field.type));
3754
			proposal.setDeclarationSignature(packageName);
3756
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3755
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
3757
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3756
			proposal.setPackageName(packageName);
3758
					proposal.setPackageName(field.type.qualifiedPackageName());
3757
			proposal.setTypeName(typeName);
3759
					proposal.setTypeName(field.type.qualifiedSourceName());
3758
			proposal.setCompletion(completionName);
3760
					proposal.setName(field.name);
3759
			proposal.setFlags(modifiers);
3761
					proposal.setCompletion(javadocCompletion);
3760
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3762
					proposal.setFlags(field.modifiers);
3761
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3763
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3762
			proposal.setRelevance(relevance);
3764
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3763
			proposal.setAccessibility(accessibility);
3765
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3764
			this.requestor.accept(proposal);
3766
					proposal.setRelevance(relevance+R_INLINE_TAG);
3765
			if(DEBUG) {
3767
					this.requestor.accept(proposal);
3766
				this.printDebug(proposal);
3768
					if(DEBUG) {
3769
						this.printDebug(proposal);
3770
					}
3771
					// Javadoc value completion for static fields
3772
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
3773
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
3774
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
3775
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
3776
						valueProposal.setSignature(getSignature(field.type));
3777
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3778
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3779
						valueProposal.setPackageName(field.type.qualifiedPackageName());
3780
						valueProposal.setTypeName(field.type.qualifiedSourceName());
3781
						valueProposal.setName(field.name);
3782
						valueProposal.setCompletion(javadocCompletion);
3783
						valueProposal.setFlags(field.modifiers);
3784
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3785
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3786
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
3787
						this.requestor.accept(valueProposal);
3788
						if(DEBUG) {
3789
							this.printDebug(valueProposal);
3790
						}
3791
					}
3792
				}
3793
			} else {
3794
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
3795
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
3796
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
3797
					proposal.setSignature(getSignature(field.type));
3798
					proposal.setReceiverSignature(getSignature(receiverType));
3799
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
3800
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
3801
					proposal.setPackageName(field.type.qualifiedPackageName());
3802
					proposal.setTypeName(field.type.qualifiedSourceName());
3803
					proposal.setName(field.name);
3804
					if (missingElements != null) {
3805
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3806
						for (int i = 0; i < missingElements.length; i++) {
3807
							subProposals[i] =
3808
								createRequiredTypeProposal(
3809
										missingElements[i],
3810
										missingElementsStarts[i],
3811
										missingElementsEnds[i],
3812
										relevance);
3813
						}
3814
						proposal.setRequiredProposals(subProposals);
3815
					}
3816
					proposal.setCompletion(completion);
3817
					proposal.setFlags(field.modifiers);
3818
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3819
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
3820
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3821
					proposal.setRelevance(relevance);
3822
					this.requestor.accept(proposal);
3823
					if(DEBUG) {
3824
						this.printDebug(proposal);
3825
					}
3826
				}
3827
			}
3767
			}
3828
		}
3768
		}
3829
3769
3830
		fieldsFound.addAll(newFieldsFound);
3770
		// Create javadoc text proposal if necessary
3831
	}
3771
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3832
3772
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3833
	private void findFields(
3773
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3834
		char[] fieldName,
3774
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3835
		ReferenceBinding receiverType,
3775
			proposal.completionEngine = this;
3836
		Scope scope,
3776
			proposal.setDeclarationSignature(packageName);
3837
		ObjectVector fieldsFound,
3777
			proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
3838
		ObjectVector localsFound,
3778
			proposal.setPackageName(packageName);
3839
		boolean onlyStaticFields,
3779
			proposal.setTypeName(typeName);
3840
		InvocationSite invocationSite,
3780
			proposal.setCompletion(javadocCompletion);
3841
		Scope invocationScope,
3781
			proposal.setFlags(modifiers);
3842
		boolean implicitCall,
3782
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3843
		boolean canBePrefixed,
3783
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3844
		Binding[] missingElements,
3784
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3845
		int[] missingElementsStarts,
3785
			proposal.setRelevance(relevance+R_INLINE_TAG);
3846
		int[] missingElementsEnds,
3786
			proposal.setAccessibility(accessibility);
3847
		boolean missingElementsHaveProblems,
3787
			this.requestor.accept(proposal);
3848
		char[] castedReceiver,
3788
			if(DEBUG) {
3849
		int receiverStart,
3789
				this.printDebug(proposal);
3850
		int receiverEnd) {
3851
3852
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
3853
		if (fieldName == null && notInJavadoc)
3854
			return;
3855
3856
		ReferenceBinding currentType = receiverType;
3857
		ReferenceBinding[] interfacesToVisit = null;
3858
		int nextPosition = 0;
3859
		do {
3860
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
3861
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
3862
				if (interfacesToVisit == null) {
3863
					interfacesToVisit = itsInterfaces;
3864
					nextPosition = interfacesToVisit.length;
3865
				} else {
3866
					int itsLength = itsInterfaces.length;
3867
					if (nextPosition + itsLength >= interfacesToVisit.length)
3868
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3869
					nextInterface : for (int a = 0; a < itsLength; a++) {
3870
						ReferenceBinding next = itsInterfaces[a];
3871
						for (int b = 0; b < nextPosition; b++)
3872
							if (next == interfacesToVisit[b]) continue nextInterface;
3873
						interfacesToVisit[nextPosition++] = next;
3874
					}
3875
				}
3876
			}
3877
3878
			FieldBinding[] fields = currentType.availableFields();
3879
			if(fields != null && fields.length > 0) {
3880
				findFields(
3881
					fieldName,
3882
					fields,
3883
					scope,
3884
					fieldsFound,
3885
					localsFound,
3886
					onlyStaticFields,
3887
					receiverType,
3888
					invocationSite,
3889
					invocationScope,
3890
					implicitCall,
3891
					canBePrefixed,
3892
					missingElements,
3893
					missingElementsStarts,
3894
					missingElementsEnds,
3895
					missingElementsHaveProblems,
3896
					castedReceiver,
3897
					receiverStart,
3898
					receiverEnd);
3899
			}
3900
			currentType = currentType.superclass();
3901
		} while (notInJavadoc && currentType != null);
3902
3903
		if (notInJavadoc && interfacesToVisit != null) {
3904
			for (int i = 0; i < nextPosition; i++) {
3905
				ReferenceBinding anInterface = interfacesToVisit[i];
3906
				FieldBinding[] fields = anInterface.availableFields();
3907
				if(fields !=  null) {
3908
					findFields(
3909
						fieldName,
3910
						fields,
3911
						scope,
3912
						fieldsFound,
3913
						localsFound,
3914
						onlyStaticFields,
3915
						receiverType,
3916
						invocationSite,
3917
						invocationScope,
3918
						implicitCall,
3919
						canBePrefixed,
3920
						missingElements,
3921
						missingElementsStarts,
3922
						missingElementsEnds,
3923
						missingElementsHaveProblems,
3924
						castedReceiver,
3925
						receiverStart,
3926
						receiverEnd);
3927
				}
3928
3929
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
3930
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
3931
					int itsLength = itsInterfaces.length;
3932
					if (nextPosition + itsLength >= interfacesToVisit.length)
3933
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
3934
					nextInterface : for (int a = 0; a < itsLength; a++) {
3935
						ReferenceBinding next = itsInterfaces[a];
3936
						for (int b = 0; b < nextPosition; b++)
3937
							if (next == interfacesToVisit[b]) continue nextInterface;
3938
						interfacesToVisit[nextPosition++] = next;
3939
					}
3940
				}
3941
			}
3790
			}
3942
		}
3791
		}
3943
	}
3792
	}
3944
3793
3945
	protected void findFieldsAndMethodsFromAnotherReceiver(
3794
	/*
3946
			char[] token,
3795
	 * Create a completion proposal for a member type.
3947
			TypeReference receiverType,
3796
	 */
3948
			Scope scope,
3797
	private void createTypeProposal(
3949
			ObjectVector fieldsFound,
3798
			ReferenceBinding refBinding,
3950
			ObjectVector methodsFound,
3799
			char[] typeName,
3951
			InvocationSite invocationSite,
3800
			int accessibility,
3952
			Scope invocationScope,
3801
			char[] completionName,
3953
			boolean implicitCall,
3802
			int relevance,
3954
			boolean superCall,
3955
			Binding[] missingElements,
3803
			Binding[] missingElements,
3956
			int[] missingElementsStarts,
3804
			int[] missingElementsStarts,
3957
			int[] missingElementsEnds,
3805
			int[] missingElementsEnds,
3958
			boolean missingElementsHaveProblems,
3806
			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
3807
3972
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
3808
		// Create standard type proposal
3973
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
3809
		if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
3810
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
3811
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3812
			proposal.completionEngine = this;
3813
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
3814
			proposal.setSignature(getCompletedTypeSignature(refBinding));
3815
			proposal.setPackageName(refBinding.qualifiedPackageName());
3816
			proposal.setTypeName(typeName);
3817
			if (missingElements != null) {
3818
				CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
3819
				for (int i = 0; i < missingElements.length; i++) {
3820
					subProposals[i] =
3821
						createRequiredTypeProposal(
3822
								missingElements[i],
3823
								missingElementsStarts[i],
3824
								missingElementsEnds[i],
3825
								relevance);
3826
				}
3827
				proposal.setRequiredProposals(subProposals);
3828
			}
3829
			proposal.setCompletion(completionName);
3830
			proposal.setFlags(refBinding.modifiers);
3831
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3832
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3833
			proposal.setRelevance(relevance);
3834
			this.requestor.accept(proposal);
3835
			if(DEBUG) {
3836
				this.printDebug(proposal);
3837
			}
3838
		}
3974
3839
3975
			castedReceiver =
3840
		// Create javadoc text proposal if necessary
3976
				CharOperation.concat(
3841
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
3977
					CharOperation.concat(
3842
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
3978
						'(',
3843
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
3979
						CharOperation.concat(
3844
			proposal.nameLookup = this.nameEnvironment.nameLookup;
3980
							CharOperation.concat('(', castedTypeChars, ')'),
3845
			proposal.completionEngine = this;
3981
							receiverChars),
3846
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
3982
						')'),
3847
			proposal.setSignature(getCompletedTypeSignature(refBinding));
3983
					dotChars);
3848
			proposal.setPackageName(refBinding.qualifiedPackageName());
3849
			proposal.setTypeName(typeName);
3850
			proposal.setCompletion(javadocCompletion);
3851
			proposal.setFlags(refBinding.modifiers);
3852
			int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
3853
			proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
3854
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3855
			proposal.setRelevance(relevance+R_INLINE_TAG);
3856
			this.requestor.accept(proposal);
3857
			if(DEBUG) {
3858
				this.printDebug(proposal);
3859
			}
3860
		}
3861
	}
3862
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
3863
		completion.append(typeVariable.sourceName);
3864
3865
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
3866
		    completion.append(' ');
3867
		    completion.append(EXTENDS);
3868
		    completion.append(' ');
3869
		    createType(typeVariable.superclass, scope, completion);
3870
		}
3871
		if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
3872
		   if (typeVariable.firstBound != typeVariable.superclass) {
3873
			   completion.append(' ');
3874
			   completion.append(EXTENDS);
3875
			   completion.append(' ');
3876
		   }
3877
		   for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
3878
			   if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
3879
				   completion.append(' ');
3880
				   completion.append(EXTENDS);
3881
				   completion.append(' ');
3882
			   }
3883
			   createType(typeVariable.superInterfaces[i], scope, completion);
3884
		   }
3885
		}
3886
	}
3887
	private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
3888
		if (type.isArrayType()) {
3889
			createType(type.leafComponentType(), scope, completion);
3890
			int dim = type.dimensions() - 1;
3891
			for (int i = 0; i < dim; i++) {
3892
				completion.append('[');
3893
				completion.append(']');
3894
			}
3895
			completion.append(VARARGS);
3984
		} else {
3896
		} else {
3985
			castedReceiver =
3897
			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
		}
3898
		}
3899
	}
3900
	private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
3901
		MethodBinding[] methods = annotation.availableMethods();
3902
		nextAttribute: for (int i = 0; i < methods.length; i++) {
3903
			MethodBinding method = methods[i];
3995
3904
3996
		if (castedReceiver == null) return;
3905
			if(!CharOperation.prefixEquals(token, method.selector, false)
3906
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
3997
3907
3998
		int oldStartPosition = this.startPosition;
3908
			int length = attributesFound == null ? 0 : attributesFound.length;
3999
		this.startPosition = receiverStart;
3909
			for (int j = 0; j < length; j++) {
3910
				if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
3911
			}
4000
3912
4001
		findFieldsAndMethods(
3913
			int relevance = computeBaseRelevance();
4002
				token,
3914
			relevance += computeRelevanceForResolution();
4003
				receiverTypeBinding,
3915
			relevance += computeRelevanceForInterestingProposal(method);
4004
				scope,
3916
			relevance += computeRelevanceForCaseMatching(token, method.selector);
4005
				fieldsFound,
3917
			relevance += computeRelevanceForQualification(false);
4006
				methodsFound,
3918
			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
3919
4019
		this.startPosition = oldStartPosition;
3920
			this.noProposal = false;
3921
			if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
3922
				CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
3923
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
3924
				proposal.setSignature(getSignature(method.returnType));
3925
				proposal.setName(method.selector);
3926
				proposal.setCompletion(method.selector);
3927
				proposal.setFlags(method.modifiers);
3928
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
3929
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
3930
				proposal.setRelevance(relevance);
3931
				this.requestor.accept(proposal);
3932
				if(DEBUG) {
3933
					this.printDebug(proposal);
3934
				}
3935
			}
3936
		}
4020
	}
3937
	}
4021
	protected void findFieldsAndMethods(
3938
	private void findAnonymousType(
4022
		char[] token,
3939
		ReferenceBinding currentType,
4023
		TypeBinding receiverType,
3940
		TypeBinding[] argTypes,
4024
		Scope scope,
3941
		Scope scope,
4025
		ObjectVector fieldsFound,
3942
		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
4039
		if (token == null)
4040
			return;
4041
3943
4042
		if (receiverType.isBaseType())
3944
		if (currentType.isInterface()) {
4043
			return; // nothing else is possible with base types
3945
			char[] completion = CharOperation.NO_CHAR;
3946
			int relevance = computeBaseRelevance();
3947
			relevance += computeRelevanceForResolution();
3948
			relevance += computeRelevanceForInterestingProposal();
3949
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4044
3950
4045
		boolean proposeField =
3951
			this.noProposal = false;
4046
			castedReceiver == null ?
3952
			if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
4047
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
3953
				InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
4048
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
3954
				proposal.setDeclarationSignature(getSignature(currentType));
4049
		boolean proposeMethod =
3955
				proposal.setDeclarationKey(currentType.computeUniqueKey());
4050
			castedReceiver == null ?
3956
				proposal.setSignature(
4051
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
3957
						createMethodSignature(
4052
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
3958
								CharOperation.NO_CHAR_CHAR,
3959
								CharOperation.NO_CHAR_CHAR,
3960
								CharOperation.NO_CHAR,
3961
								CharOperation.NO_CHAR));
3962
				//proposal.setOriginalSignature(null);
3963
				//proposal.setUniqueKey(null);
3964
				proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
3965
				proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
3966
				//proposal.setParameterPackageNames(null);
3967
				//proposal.setParameterTypeNames(null);
3968
				//proposal.setPackageName(null);
3969
				//proposal.setTypeName(null);
3970
				proposal.setCompletion(completion);
3971
				proposal.setFlags(Flags.AccPublic);
3972
				proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
3973
				proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
3974
				proposal.setRelevance(relevance);
3975
				this.requestor.accept(proposal);
3976
				if(DEBUG) {
3977
					this.printDebug(proposal);
3978
				}
3979
			}
3980
		} else {
3981
			findConstructors(
3982
				currentType,
3983
				argTypes,
3984
				scope,
3985
				invocationSite,
3986
				true);
3987
		}
3988
	}
3989
	private void findClassField(
3990
			char[] token,
3991
			TypeBinding receiverType,
3992
			Scope scope,
3993
			Binding[] missingElements,
3994
			int[] missingElementsStarts,
3995
			int[] missingElementsEnds,
3996
			boolean missingElementsHaveProblems) {
4053
3997
4054
		if (receiverType.isArrayType()) {
3998
		if (token == null) return;
4055
			if (proposeField
4056
				&& token.length <= lengthField.length
4057
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
4058
			)) {
4059
3999
4060
				int relevance = computeBaseRelevance();
4000
		if (token.length <= classField.length
4061
				relevance += computeRelevanceForResolution();
4001
			&& CharOperation.prefixEquals(token, classField, false /* ignore case */
4062
				relevance += computeRelevanceForInterestingProposal();
4002
		)) {
4063
				relevance += computeRelevanceForCaseMatching(token,lengthField);
4003
			int relevance = computeBaseRelevance();
4064
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
4004
			relevance += computeRelevanceForResolution();
4065
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
4005
			relevance += computeRelevanceForInterestingProposal();
4066
				if (missingElements != null) {
4006
			relevance += computeRelevanceForCaseMatching(token, classField);
4067
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4007
			relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
4068
				}
4008
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
4069
				this.noProposal = false;
4009
			relevance += R_NON_INHERITED;
4070
				if (castedReceiver == null) {
4071
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
4072
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4073
						proposal.setDeclarationSignature(getSignature(receiverType));
4074
						proposal.setSignature(INT_SIGNATURE);
4075
						proposal.setTypeName(INT);
4076
						proposal.setName(lengthField);
4077
						if (missingElements != null) {
4078
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4079
							for (int i = 0; i < missingElements.length; i++) {
4080
								subProposals[i] =
4081
									createRequiredTypeProposal(
4082
											missingElements[i],
4083
											missingElementsStarts[i],
4084
											missingElementsEnds[i],
4085
											relevance);
4086
							}
4087
							proposal.setRequiredProposals(subProposals);
4088
						}
4089
						proposal.setCompletion(lengthField);
4090
						proposal.setFlags(Flags.AccPublic);
4091
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4092
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4093
						proposal.setRelevance(relevance);
4094
						this.requestor.accept(proposal);
4095
						if(DEBUG) {
4096
							this.printDebug(proposal);
4097
						}
4098
					}
4099
				} else {
4100
					char[] completion = CharOperation.concat(castedReceiver, lengthField);
4101
4010
4102
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
4011
			if (missingElements != null) {
4103
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
4012
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
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
					}
4132
				}
4133
			}
4013
			}
4134
			if (proposeMethod
4135
				&& token.length <= cloneMethod.length
4136
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
4137
			) {
4138
				ReferenceBinding objectRef = scope.getJavaLangObject();
4139
4014
4140
				int relevance = computeBaseRelevance();
4015
			this.noProposal = false;
4141
				relevance += computeRelevanceForResolution();
4016
			if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
4142
				relevance += computeRelevanceForInterestingProposal();
4017
				InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4143
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
4018
				//proposal.setDeclarationSignature(null);
4144
				relevance += computeRelevanceForExpectingType(objectRef);
4019
				char[] signature =
4145
				relevance += computeRelevanceForStatic(false, false);
4020
					createNonGenericTypeSignature(
4146
				relevance += computeRelevanceForQualification(false);
4021
						CharOperation.concatWith(JAVA_LANG, '.'),
4147
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
4022
						CLASS);
4023
				if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
4024
					// add type argument
4025
					char[] typeArgument = getTypeSignature(receiverType);
4026
					int oldLength = signature.length;
4027
					int argumentLength = typeArgument.length;
4028
					int newLength = oldLength + argumentLength + 2;
4029
					System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
4030
					signature[oldLength - 1] = '<';
4031
					System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
4032
					signature[newLength - 2] = '>';
4033
					signature[newLength - 1] = ';';
4034
				}
4035
				proposal.setSignature(signature);
4036
				//proposal.setDeclarationPackageName(null);
4037
				//proposal.setDeclarationTypeName(null);
4038
				proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4039
				proposal.setTypeName(CLASS);
4040
				proposal.setName(classField);
4148
				if (missingElements != null) {
4041
				if (missingElements != null) {
4149
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4042
					CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4043
					for (int i = 0; i < missingElements.length; i++) {
4044
						subProposals[i] =
4045
							createRequiredTypeProposal(
4046
									missingElements[i],
4047
									missingElementsStarts[i],
4048
									missingElementsEnds[i],
4049
									relevance);
4050
					}
4051
					proposal.setRequiredProposals(subProposals);
4150
				}
4052
				}
4151
				char[] completion;
4053
				proposal.setCompletion(classField);
4152
				if (this.source != null
4054
				proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
4153
					&& this.source.length > this.endPosition
4055
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4154
					&& this.source[this.endPosition] == '(') {
4056
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4155
					completion = cloneMethod;
4057
				proposal.setRelevance(relevance);
4156
					} else {
4058
				this.requestor.accept(proposal);
4157
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
4059
				if(DEBUG) {
4060
					this.printDebug(proposal);
4158
				}
4061
				}
4062
			}
4063
		}
4064
	}
4065
	private void findConstructors(
4066
		ReferenceBinding currentType,
4067
		TypeBinding[] argTypes,
4068
		Scope scope,
4069
		InvocationSite invocationSite,
4070
		boolean forAnonymousType) {
4159
4071
4160
				if (castedReceiver != null) {
4072
		// No visibility checks can be performed without the scope & invocationSite
4161
					completion = CharOperation.concat(castedReceiver, completion);
4073
		MethodBinding[] methods = currentType.availableMethods();
4162
				}
4074
		if(methods != null) {
4075
			int minArgLength = argTypes == null ? 0 : argTypes.length;
4076
			next : for (int f = methods.length; --f >= 0;) {
4077
				MethodBinding constructor = methods[f];
4078
				if (constructor.isConstructor()) {
4163
4079
4164
				this.noProposal = false;
4080
					if (constructor.isSynthetic()) continue next;
4165
				if (castedReceiver == null) {
4081
4166
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
4082
					if (this.options.checkDeprecation &&
4167
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4083
							constructor.isViewedAsDeprecated() &&
4168
						proposal.setDeclarationSignature(getSignature(receiverType));
4084
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4169
						proposal.setSignature(
4085
						continue next;
4170
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
4086
4171
										createMethodSignature(
4087
					if (this.options.checkVisibility
4172
												CharOperation.NO_CHAR_CHAR,
4088
						&& !constructor.canBeSeenBy(invocationSite, scope)) {
4173
												CharOperation.NO_CHAR_CHAR,
4089
						if(!forAnonymousType || !constructor.isProtected())
4174
												getSignature(receiverType)) :
4090
							continue next;
4175
										createMethodSignature(
4091
					}
4176
												CharOperation.NO_CHAR_CHAR,
4092
4177
												CharOperation.NO_CHAR_CHAR,
4093
					TypeBinding[] parameters = constructor.parameters;
4178
												CharOperation.concatWith(JAVA_LANG, '.'),
4094
					int paramLength = parameters.length;
4179
												OBJECT));
4095
					if (minArgLength > paramLength)
4180
						//proposal.setOriginalSignature(null);
4096
						continue next;
4181
						//proposal.setDeclarationPackageName(null);
4097
					for (int a = minArgLength; --a >= 0;)
4182
						//proposal.setDeclarationTypeName(null);
4098
						if (argTypes[a] != null) { // can be null if it could not be resolved properly
4183
						//proposal.setParameterPackageNames(null);
4099
							if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
4184
						//proposal.setParameterTypeNames(null);
4100
								continue next;
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
						}
4101
						}
4102
4103
					char[][] parameterPackageNames = new char[paramLength][];
4104
					char[][] parameterTypeNames = new char[paramLength][];
4105
					for (int i = 0; i < paramLength; i++) {
4106
						TypeBinding type = parameters[i];
4107
						parameterPackageNames[i] = type.qualifiedPackageName();
4108
						parameterTypeNames[i] = type.qualifiedSourceName();
4209
					}
4109
					}
4210
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
4110
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4211
				} else {
4111
4212
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
4112
					char[] completion = CharOperation.NO_CHAR;
4213
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
4113
					if(forAnonymousType){
4214
						proposal.setDeclarationSignature(getSignature(receiverType));
4114
						int relevance = computeBaseRelevance();
4215
						proposal.setSignature(
4115
						relevance += computeRelevanceForResolution();
4216
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
4116
						relevance += computeRelevanceForInterestingProposal();
4217
										createMethodSignature(
4117
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4218
												CharOperation.NO_CHAR_CHAR,
4118
4219
												CharOperation.NO_CHAR_CHAR,
4119
						this.noProposal = false;
4220
												getSignature(receiverType)) :
4120
						if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
4221
										createMethodSignature(
4121
							InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
4222
												CharOperation.NO_CHAR_CHAR,
4122
							proposal.setDeclarationSignature(getSignature(currentType));
4223
												CharOperation.NO_CHAR_CHAR,
4123
							proposal.setDeclarationKey(currentType.computeUniqueKey());
4224
												CharOperation.concatWith(JAVA_LANG, '.'),
4124
							proposal.setSignature(getSignature(constructor));
4225
												OBJECT));
4125
							MethodBinding original = constructor.original();
4226
						proposal.setReceiverSignature(getSignature(receiverType));
4126
							if(original != constructor) {
4227
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
4127
								proposal.setOriginalSignature(getSignature(original));
4228
						proposal.setTypeName(OBJECT);
4128
							}
4229
						proposal.setName(cloneMethod);
4129
							proposal.setKey(constructor.computeUniqueKey());
4230
						if (missingElements != null) {
4130
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4231
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4131
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4232
							for (int i = 0; i < missingElements.length; i++) {
4132
							proposal.setParameterPackageNames(parameterPackageNames);
4233
								subProposals[i] =
4133
							proposal.setParameterTypeNames(parameterTypeNames);
4234
									createRequiredTypeProposal(
4134
							//proposal.setPackageName(null);
4235
											missingElements[i],
4135
							//proposal.setTypeName(null);
4236
											missingElementsStarts[i],
4136
							proposal.setCompletion(completion);
4237
											missingElementsEnds[i],
4137
							proposal.setFlags(constructor.modifiers);
4238
											relevance);
4138
							proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
4139
							proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
4140
							proposal.setRelevance(relevance);
4141
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4142
							this.requestor.accept(proposal);
4143
							if(DEBUG) {
4144
								this.printDebug(proposal);
4239
							}
4145
							}
4240
							proposal.setRequiredProposals(subProposals);
4241
						}
4146
						}
4242
						proposal.setCompletion(completion);
4147
					} else {
4243
						proposal.setFlags(Flags.AccPublic);
4148
						int relevance = computeBaseRelevance();
4244
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4149
						relevance += computeRelevanceForResolution();
4245
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
4150
						relevance += computeRelevanceForInterestingProposal();
4246
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4151
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4247
						proposal.setRelevance(relevance);
4152
4248
						this.requestor.accept(proposal);
4153
						// Special case for completion in javadoc
4249
						if(DEBUG) {
4154
						if (this.assistNodeInJavadoc > 0) {
4250
							this.printDebug(proposal);
4155
							Expression receiver = null;
4156
							char[] selector = null;
4157
							if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
4158
								CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
4159
								receiver = alloc.type;
4160
							} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4161
								CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4162
								receiver = fieldRef.receiver;
4163
							}
4164
							if (receiver != null) {
4165
								StringBuffer javadocCompletion = new StringBuffer();
4166
								if (receiver.isThis()) {
4167
									selector = (((JavadocImplicitTypeReference)receiver).token);
4168
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4169
										javadocCompletion.append('#');
4170
									}
4171
								} else if (receiver instanceof JavadocSingleTypeReference) {
4172
									JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
4173
									selector = typeRef.token;
4174
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4175
										javadocCompletion.append(typeRef.token);
4176
										javadocCompletion.append('#');
4177
									}
4178
								} else if (receiver instanceof JavadocQualifiedTypeReference) {
4179
									JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
4180
									selector = typeRef.tokens[typeRef.tokens.length-1];
4181
									if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
4182
										javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
4183
										javadocCompletion.append('#');
4184
									}
4185
								}
4186
								// Append parameters types
4187
								javadocCompletion.append(selector);
4188
								javadocCompletion.append('(');
4189
								if (constructor.parameters != null) {
4190
									boolean isVarargs = constructor.isVarargs();
4191
									for (int p=0, ln=constructor.parameters.length; p<ln; p++) {
4192
										if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
4193
										TypeBinding argTypeBinding = constructor.parameters[p];
4194
										if (isVarargs && p == ln - 1)  {
4195
											createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
4196
										} else {
4197
											createType(argTypeBinding.erasure(), scope, javadocCompletion);
4198
										}
4199
									}
4200
								}
4201
								javadocCompletion.append(')');
4202
								completion = javadocCompletion.toString().toCharArray();
4203
							}
4204
						}
4205
4206
						// Create standard proposal
4207
						this.noProposal = false;
4208
						if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4209
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4210
							proposal.setDeclarationSignature(getSignature(currentType));
4211
							proposal.setSignature(getSignature(constructor));
4212
							MethodBinding original = constructor.original();
4213
							if(original != constructor) {
4214
								proposal.setOriginalSignature(getSignature(original));
4215
							}
4216
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4217
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4218
							proposal.setParameterPackageNames(parameterPackageNames);
4219
							proposal.setParameterTypeNames(parameterTypeNames);
4220
							//proposal.setPackageName(null);
4221
							//proposal.setTypeName(null);
4222
							proposal.setName(currentType.sourceName());
4223
							proposal.setIsContructor(true);
4224
							proposal.setCompletion(completion);
4225
							proposal.setFlags(constructor.modifiers);
4226
							int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
4227
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4228
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4229
							proposal.setRelevance(relevance);
4230
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4231
							this.requestor.accept(proposal);
4232
							if(DEBUG) {
4233
								this.printDebug(proposal);
4234
							}
4235
						}
4236
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
4237
							char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
4238
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
4239
							proposal.setDeclarationSignature(getSignature(currentType));
4240
							proposal.setSignature(getSignature(constructor));
4241
							MethodBinding original = constructor.original();
4242
							if(original != constructor) {
4243
								proposal.setOriginalSignature(getSignature(original));
4244
							}
4245
							proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4246
							proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4247
							proposal.setParameterPackageNames(parameterPackageNames);
4248
							proposal.setParameterTypeNames(parameterTypeNames);
4249
							//proposal.setPackageName(null);
4250
							//proposal.setTypeName(null);
4251
							proposal.setName(currentType.sourceName());
4252
							proposal.setIsContructor(true);
4253
							proposal.setCompletion(javadocCompletion);
4254
							proposal.setFlags(constructor.modifiers);
4255
							int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4256
							proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4257
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4258
							proposal.setRelevance(relevance+R_INLINE_TAG);
4259
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
4260
							this.requestor.accept(proposal);
4261
							if(DEBUG) {
4262
								this.printDebug(proposal);
4263
							}
4251
						}
4264
						}
4252
					}
4265
					}
4253
				}
4266
				}
4254
			}
4267
			}
4255
4256
			receiverType = scope.getJavaLangObject();
4257
		}
4258
4259
		if(proposeField) {
4260
			findFields(
4261
				token,
4262
				(ReferenceBinding) receiverType,
4263
				scope,
4264
				fieldsFound,
4265
				new ObjectVector(),
4266
				false,
4267
				invocationSite,
4268
				invocationScope,
4269
				implicitCall,
4270
				false,
4271
				missingElements,
4272
				missingElementsStarts,
4273
				missingElementsEnds,
4274
				missingElementsHaveProblems,
4275
				castedReceiver,
4276
				receiverStart,
4277
				receiverEnd);
4278
		}
4279
4280
		if(proposeMethod) {
4281
			findMethods(
4282
				token,
4283
				null,
4284
				null,
4285
				(ReferenceBinding) receiverType,
4286
				scope,
4287
				methodsFound,
4288
				false,
4289
				false,
4290
				false,
4291
				invocationSite,
4292
				invocationScope,
4293
				implicitCall,
4294
				superCall,
4295
				false,
4296
				missingElements,
4297
				missingElementsStarts,
4298
				missingElementsEnds,
4299
				missingElementsHaveProblems,
4300
				castedReceiver,
4301
				receiverStart,
4302
				receiverEnd);
4303
		}
4268
		}
4304
	}
4269
	}
4270
	private char[][] findEnclosingTypeNames(Scope scope){
4271
		char[][] excludedNames = new char[10][];
4272
		int excludedNameCount = 0;
4305
4273
4306
	private void findFieldsAndMethodsFromFavorites(
4274
		Scope currentScope = scope;
4307
			char[] token,
4275
		while(currentScope != null) {
4308
			Scope scope,
4276
			switch (currentScope.kind) {
4309
			InvocationSite invocationSite,
4277
				case Scope.CLASS_SCOPE :
4310
			Scope invocationScope,
4278
					ClassScope classScope = (ClassScope) currentScope;
4311
			ObjectVector localsFound,
4312
			ObjectVector fieldsFound,
4313
			ObjectVector methodsFound) {
4314
4279
4315
		ObjectVector methodsFoundFromFavorites = new ObjectVector();
4280
					TypeDeclaration typeDeclaration = classScope.referenceContext;
4316
4281
4317
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
4282
					if(excludedNameCount == excludedNames.length) {
4283
						System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4284
					}
4285
					excludedNames[excludedNameCount++] = typeDeclaration.name;
4318
4286
4319
		if (favoriteBindings != null && favoriteBindings.length > 0) {
4287
					TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
4320
			for (int i = 0; i < favoriteBindings.length; i++) {
4288
					if(classTypeParameters != null) {
4321
				ImportBinding favoriteBinding = favoriteBindings[i];
4289
						for (int i = 0; i < classTypeParameters.length; i++) {
4322
				switch (favoriteBinding.resolvedImport.kind()) {
4290
							TypeParameter typeParameter = classTypeParameters[i];
4323
					case Binding.FIELD:
4291
							if(excludedNameCount == excludedNames.length) {
4324
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
4292
								System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4325
						findFieldsFromFavorites(
4293
							}
4326
								token,
4294
							excludedNames[excludedNameCount++] = typeParameter.name;
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
4369
							findLocalMethodsFromFavorites(
4370
									token,
4371
									referenceBinding.availableMethods(),
4372
									scope,
4373
									methodsFound,
4374
									methodsFoundFromFavorites,
4375
									referenceBinding,
4376
									invocationSite,
4377
									invocationScope);
4378
						}
4295
						}
4379
						break;
4296
					}
4380
				}
4297
					break;
4381
			}
4382
		}
4383
4384
		methodsFound.addAll(methodsFoundFromFavorites);
4385
	}
4386
4387
	private boolean findFieldsAndMethodsFromMissingFieldType(
4388
		char[] token,
4389
		Scope scope,
4390
		InvocationSite invocationSite,
4391
		boolean insideTypeAnnotation) {
4392
4393
		boolean foundSomeFields = false;
4394
4395
		boolean staticsOnly = false;
4396
		Scope currentScope = scope;
4397
4398
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4399
4400
			switch (currentScope.kind) {
4401
4402
				case Scope.METHOD_SCOPE :
4298
				case Scope.METHOD_SCOPE :
4403
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4404
					MethodScope methodScope = (MethodScope) currentScope;
4299
					MethodScope methodScope = (MethodScope) currentScope;
4405
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4300
					if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
4406
					break;
4301
						TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
4407
				case Scope.CLASS_SCOPE :
4302
						if(methodTypeParameters != null) {
4408
					ClassScope classScope = (ClassScope) currentScope;
4303
							for (int i = 0; i < methodTypeParameters.length; i++) {
4409
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4304
								TypeParameter typeParameter = methodTypeParameters[i];
4410
					if(!insideTypeAnnotation) {
4305
								if(excludedNameCount == excludedNames.length) {
4411
4306
									System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
4412
						FieldDeclaration[] fields = classScope.referenceContext.fields;
4413
4414
						int fieldsCount = fields == null ? 0 : fields.length;
4415
						for (int i = 0; i < fieldsCount; i++) {
4416
							FieldDeclaration fieldDeclaration = fields[i];
4417
							if (CharOperation.equals(fieldDeclaration.name, token)) {
4418
								FieldBinding fieldBinding = fieldDeclaration.binding;
4419
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
4420
									foundSomeFields = true;
4421
									findFieldsAndMethodsFromMissingType(
4422
											fieldDeclaration.type,
4423
											currentScope,
4424
											invocationSite,
4425
											scope);
4426
								}
4307
								}
4427
								break done;
4308
								excludedNames[excludedNameCount++] = typeParameter.name;
4428
							}
4309
							}
4429
						}
4310
						}
4430
					}
4311
					}
4431
					staticsOnly |= enclosingType.isStatic();
4432
					insideTypeAnnotation = false;
4433
					break;
4312
					break;
4434
				case Scope.COMPILATION_UNIT_SCOPE :
4435
					break done;
4436
			}
4313
			}
4314
4437
			currentScope = currentScope.parent;
4315
			currentScope = currentScope.parent;
4438
		}
4316
		}
4439
		return foundSomeFields;
4317
4318
		if(excludedNameCount == 0) {
4319
			return CharOperation.NO_CHAR_CHAR;
4320
		}
4321
		System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
4322
		return excludedNames;
4440
	}
4323
	}
4324
	private void findEnumConstants(
4325
			char[] enumConstantName,
4326
			ReferenceBinding enumType,
4327
			Scope invocationScope,
4328
			ObjectVector fieldsFound,
4329
			char[][] alreadyUsedConstants,
4330
			int alreadyUsedConstantCount,
4331
			boolean needQualification) {
4441
4332
4442
	private void findFieldsAndMethodsFromMissingReturnType(
4333
		FieldBinding[] fields = enumType.fields();
4443
		char[] token,
4444
		TypeBinding[] arguments,
4445
		Scope scope,
4446
		InvocationSite invocationSite,
4447
		boolean insideTypeAnnotation) {
4448
4334
4449
		boolean staticsOnly = false;
4335
		int enumConstantLength = enumConstantName.length;
4450
		Scope currentScope = scope;
4336
		next : for (int f = fields.length; --f >= 0;) {
4337
			FieldBinding field = fields[f];
4451
4338
4452
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
4339
			if (field.isSynthetic()) continue next;
4453
4340
4454
			switch (currentScope.kind) {
4341
			if ((field.modifiers & Flags.AccEnum) == 0) continue next;
4455
4342
4456
				case Scope.METHOD_SCOPE :
4343
			if (enumConstantLength > field.name.length) continue next;
4457
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
4458
					MethodScope methodScope = (MethodScope) currentScope;
4459
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
4460
					break;
4461
				case Scope.CLASS_SCOPE :
4462
					ClassScope classScope = (ClassScope) currentScope;
4463
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
4464
					if(!insideTypeAnnotation) {
4465
4344
4466
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
4345
			if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
4346
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name)))	continue next;
4467
4347
4468
						int methodsCount = methods == null ? 0 : methods.length;
4348
			char[] fieldName = field.name;
4469
						for (int i = 0; i < methodsCount; i++) {
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
4349
4480
									if (parametersLength == 0) {
4350
			for (int i = 0; i < alreadyUsedConstantCount; i++) {
4481
										if (argumentsLength == 0) {
4351
				if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
4482
											findFieldsAndMethodsFromMissingType(
4352
			}
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
4353
4514
							}
4354
			int relevance = computeBaseRelevance();
4515
						}
4355
			relevance += computeRelevanceForResolution();
4356
			relevance += computeRelevanceForInterestingProposal(field);
4357
			relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
4358
			relevance += computeRelevanceForExpectingType(field.type);
4359
			relevance += computeRelevanceForEnumConstant(field.type);
4360
			relevance += computeRelevanceForQualification(needQualification);
4361
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4362
4363
			this.noProposal = false;
4364
			if (!needQualification) {
4365
				char[] completion = fieldName;
4366
4367
				if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4368
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4369
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4370
					proposal.setSignature(getSignature(field.type));
4371
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4372
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4373
					proposal.setPackageName(field.type.qualifiedPackageName());
4374
					proposal.setTypeName(field.type.qualifiedSourceName());
4375
					proposal.setName(field.name);
4376
					proposal.setCompletion(completion);
4377
					proposal.setFlags(field.modifiers);
4378
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4379
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4380
					proposal.setRelevance(relevance);
4381
					this.requestor.accept(proposal);
4382
					if(DEBUG) {
4383
						this.printDebug(proposal);
4516
					}
4384
					}
4517
					staticsOnly |= enclosingType.isStatic();
4385
				}
4518
					insideTypeAnnotation = false;
4519
					break;
4520
				case Scope.COMPILATION_UNIT_SCOPE :
4521
					break done;
4522
			}
4523
			currentScope = currentScope.parent;
4524
		}
4525
	}
4526
4386
4527
	private void findFieldsAndMethodsFromMissingType(
4387
			} else {
4528
			TypeReference typeRef,
4388
				TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
4529
			final Scope scope,
4389
				boolean needImport = visibleType == null || !visibleType.isValidBinding();
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
4559
				}
4560
			};
4561
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
4562
	}
4563
4390
4564
	private void findFieldsFromFavorites(
4391
				char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
4565
			char[] fieldName,
4566
			FieldBinding[] fields,
4567
			Scope scope,
4568
			ObjectVector fieldsFound,
4569
			ObjectVector localsFound,
4570
			ReferenceBinding receiverType,
4571
			InvocationSite invocationSite,
4572
			Scope invocationScope) {
4573
4392
4574
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
4393
				if (!needImport) {
4394
					if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4395
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4396
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4397
						proposal.setSignature(getSignature(field.type));
4398
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4399
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4400
						proposal.setPackageName(field.type.qualifiedPackageName());
4401
						proposal.setTypeName(field.type.qualifiedSourceName());
4402
						proposal.setName(field.name);
4403
						proposal.setCompletion(completion);
4404
						proposal.setFlags(field.modifiers);
4405
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4406
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4407
						proposal.setRelevance(relevance);
4408
						this.requestor.accept(proposal);
4409
						if(DEBUG) {
4410
							this.printDebug(proposal);
4411
						}
4412
					}
4413
				} else {
4414
					if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4415
						CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4416
						int importStart = cu.types[0].declarationSourceStart;
4417
						int importEnd = importStart;
4575
4418
4576
		int fieldLength = fieldName.length;
4419
						ReferenceBinding fieldType = (ReferenceBinding)field.type;
4577
		next : for (int f = fields.length; --f >= 0;) {
4578
			FieldBinding field = fields[f];
4579
4420
4580
			if (field.isSynthetic())	continue next;
4421
						InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4422
						proposal.setDeclarationSignature(getSignature(field.declaringClass));
4423
						proposal.setSignature(getSignature(field.type));
4424
						proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4425
						proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4426
						proposal.setPackageName(field.type.qualifiedPackageName());
4427
						proposal.setTypeName(field.type.qualifiedSourceName());
4428
						proposal.setName(field.name);
4429
						proposal.setCompletion(completion);
4430
						proposal.setFlags(field.modifiers);
4431
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4432
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4433
						proposal.setRelevance(relevance);
4581
4434
4582
			// only static fields must be proposed
4435
						char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
4583
			if (!field.isStatic()) continue next;
4584
4436
4585
			if (fieldLength > field.name.length) continue next;
4437
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4438
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4439
						typeImportProposal.completionEngine = this;
4440
						char[] packageName = fieldType.qualifiedPackageName();
4441
						typeImportProposal.setDeclarationSignature(packageName);
4442
						typeImportProposal.setSignature(getSignature(fieldType));
4443
						typeImportProposal.setPackageName(packageName);
4444
						typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
4445
						typeImportProposal.setCompletion(typeImportCompletion);
4446
						typeImportProposal.setFlags(fieldType.modifiers);
4447
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4448
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4449
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4450
						typeImportProposal.setRelevance(relevance);
4586
4451
4587
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4452
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4588
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4589
4453
4590
			if (this.options.checkDeprecation &&
4454
						this.requestor.accept(proposal);
4591
					field.isViewedAsDeprecated() &&
4455
						if(DEBUG) {
4592
					!scope.isDefinedInSameUnit(field.declaringClass))
4456
							this.printDebug(proposal);
4593
				continue next;
4457
						}
4458
					}
4459
				}
4460
			}
4461
		}
4462
	}
4463
	private void findEnumConstantsFromExpectedTypes(
4464
			char[] token,
4465
			Scope invocationScope,
4466
			ObjectVector fieldsFound) {
4467
		int length = this.expectedTypesPtr + 1;
4468
		for (int i = 0; i < length; i++) {
4469
			if (this.expectedTypes[i].isEnum()) {
4470
				findEnumConstants(
4471
						token,
4472
						(ReferenceBinding)this.expectedTypes[i],
4473
						invocationScope,
4474
						fieldsFound,
4475
						CharOperation.NO_CHAR_CHAR,
4476
						0,
4477
						true);
4478
			}
4479
		}
4594
4480
4595
			if (this.options.checkVisibility
4481
	}
4596
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4482
	private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
4483
		TypeBinding expressionType = switchStatement.expression.resolvedType;
4484
		if(expressionType != null && expressionType.isEnum()) {
4485
			ReferenceBinding enumType = (ReferenceBinding) expressionType;
4597
4486
4598
			for (int i = fieldsFound.size; --i >= 0;) {
4487
			CaseStatement[] cases = switchStatement.cases;
4599
				Object[] other = (Object[])fieldsFound.elementAt(i);
4600
				FieldBinding otherField = (FieldBinding) other[0];
4601
4488
4602
				if (field == otherField) continue next;
4489
			char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
4490
			int alreadyUsedConstantCount = 0;
4491
			for (int i = 0; i < switchStatement.caseCount; i++) {
4492
				Expression caseExpression = cases[i].constantExpression;
4493
				if((caseExpression instanceof SingleNameReference)
4494
						&& (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
4495
					alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
4496
				}
4603
			}
4497
			}
4604
4498
4605
			fieldsFound.add(new Object[]{field, receiverType});
4499
			findEnumConstants(
4500
					enumConstantName,
4501
					enumType,
4502
					null /* doesn't need invocation scope */,
4503
					new ObjectVector(),
4504
					alreadyUsedConstants,
4505
					alreadyUsedConstantCount,
4506
					false);
4507
		}
4508
	}
4509
	private void findExceptionFromTryStatement(
4510
			char[] typeName,
4511
			ReferenceBinding exceptionType,
4512
			ReferenceBinding receiverType,
4513
			SourceTypeBinding invocationType,
4514
			BlockScope scope,
4515
			ObjectVector typesFound,
4516
			boolean searchSuperClasses) {
4606
4517
4607
			int relevance = computeBaseRelevance();
4518
		if (searchSuperClasses) {
4608
			relevance += computeRelevanceForResolution();
4519
			ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
4609
			relevance += computeRelevanceForInterestingProposal(field);
4520
			if (exceptionType != javaLangThrowable) {
4610
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4521
				ReferenceBinding superClass = exceptionType.superclass();
4611
			relevance += computeRelevanceForExpectingType(field.type);
4522
				while(superClass != null && superClass != javaLangThrowable) {
4612
			relevance += computeRelevanceForEnumConstant(field.type);
4523
					findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
4613
			relevance += computeRelevanceForStatic(true, true);
4524
					superClass = superClass.superclass();
4614
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4525
				}
4526
			}
4527
		}
4615
4528
4616
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
4529
		if (typeName.length > exceptionType.sourceName.length)
4617
			int importStart = cu.types[0].declarationSourceStart;
4530
			return;
4618
			int importEnd = importStart;
4619
4531
4620
			this.noProposal = false;
4532
		if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
4533
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
4534
			return;
4621
4535
4622
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
4536
		if (this.options.checkDeprecation &&
4623
					!this.options.suggestStaticImport) {
4537
				exceptionType.isViewedAsDeprecated() &&
4624
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
4538
				!scope.isDefinedInSameUnit(exceptionType))
4625
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
4539
			return;
4626
4540
4627
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4541
		if (this.options.checkVisibility) {
4628
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4542
			if (invocationType != null) {
4629
					proposal.setSignature(getSignature(field.type));
4543
				if (receiverType != null) {
4630
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4544
					if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
4631
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4545
				} else {
4632
					proposal.setPackageName(field.type.qualifiedPackageName());
4546
					if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
4633
					proposal.setTypeName(field.type.qualifiedSourceName());
4547
				}
4634
					proposal.setName(field.name);
4548
			} else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
4635
					proposal.setCompletion(completion);
4549
				return;
4636
					proposal.setFlags(field.modifiers);
4550
			}
4637
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4551
		}
4638
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4639
					proposal.setRelevance(relevance);
4640
4552
4641
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
4553
		for (int j = typesFound.size; --j >= 0;) {
4554
			ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
4642
4555
4643
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
4556
			if (exceptionType == otherType)
4644
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
4557
				return;
4645
					typeImportProposal.completionEngine = this;
4646
					char[] packageName = receiverType.qualifiedPackageName();
4647
					typeImportProposal.setDeclarationSignature(packageName);
4648
					typeImportProposal.setSignature(getSignature(receiverType));
4649
					typeImportProposal.setPackageName(packageName);
4650
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
4651
					typeImportProposal.setCompletion(typeImportCompletion);
4652
					typeImportProposal.setFlags(receiverType.modifiers);
4653
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
4654
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
4655
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
4656
					typeImportProposal.setRelevance(relevance);
4657
4558
4658
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
4559
			if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
4659
4560
4660
					this.requestor.accept(proposal);
4561
				if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
4661
					if(DEBUG) {
4562
					return;
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
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
4563
4700
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
4564
				if (otherType.enclosingType().isInterface())
4565
					if (exceptionType.enclosingType()
4566
						.implementsInterface(otherType.enclosingType(), true))
4567
						return;
4701
4568
4702
					this.requestor.accept(proposal);
4569
				if (exceptionType.enclosingType().isInterface())
4703
					if(DEBUG) {
4570
					if (otherType.enclosingType()
4704
						this.printDebug(proposal);
4571
						.implementsInterface(exceptionType.enclosingType(), true))
4705
					}
4572
						return;
4706
				}
4707
			}
4573
			}
4708
		}
4574
		}
4709
	}
4710
4575
4711
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
4576
		typesFound.add(exceptionType);
4712
		char[][] tokens = importReference.tokens;
4713
4577
4714
		char[] importName = CharOperation.concatWith(tokens, '.');
4578
		char[] completionName = exceptionType.sourceName();
4715
4579
4716
		if (importName.length == 0)
4580
		boolean isQualified = false;
4717
			return;
4718
4581
4719
		char[] lastToken = tokens[tokens.length - 1];
4582
		if(!this.insideQualifiedReference) {
4720
		if(lastToken != null && lastToken.length == 0)
4583
			isQualified = true;
4721
			importName = CharOperation.concat(importName, new char[]{'.'});
4722
4584
4723
		this.resolvingImports = true;
4585
			char[] memberPackageName = exceptionType.qualifiedPackageName();
4724
		this.resolvingStaticImports = importReference.isStatic();
4586
			char[] memberTypeName = exceptionType.sourceName();
4587
			char[] memberEnclosingTypeNames = null;
4725
4588
4726
		this.completionToken =  lastToken;
4589
			ReferenceBinding enclosingType = exceptionType.enclosingType();
4727
		this.qualifiedCompletionToken = importName;
4590
			if (enclosingType != null) {
4591
				memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
4592
			}
4728
4593
4729
		// want to replace the existing .*;
4594
			Scope currentScope = scope;
4730
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
4595
			done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
4731
			int oldStart = this.startPosition;
4732
			int oldEnd = this.endPosition;
4733
			setSourceRange(
4734
				importReference.sourceStart,
4735
				importReference.declarationSourceEnd);
4736
			this.nameEnvironment.findPackages(importName, this);
4737
			setSourceRange(
4738
				oldStart,
4739
				oldEnd - 1,
4740
				false);
4741
		}
4742
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4743
			this.nameEnvironment.findTypes(
4744
					importName,
4745
					findMembers,
4746
					this.options.camelCaseMatch,
4747
					IJavaSearchConstants.TYPE,
4748
					this);
4749
			acceptTypes(null);
4750
		}
4751
	}
4752
4596
4753
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
4597
				switch (currentScope.kind) {
4754
		ReferenceBinding[] memberTypes = ref.memberTypes();
4755
4598
4756
		int typeLength = typeName.length;
4599
					case Scope.METHOD_SCOPE :
4757
		next : for (int m = memberTypes.length; --m >= 0;) {
4600
					case Scope.BLOCK_SCOPE :
4758
			ReferenceBinding memberType = memberTypes[m];
4601
						BlockScope blockScope = (BlockScope) currentScope;
4759
			//		if (!wantClasses && memberType.isClass()) continue next;
4760
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
4761
4602
4762
			if (onlyStatic && !memberType.isStatic())
4603
						for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
4763
				continue next;
4764
4604
4765
			if (typeLength > memberType.sourceName.length)
4605
							if (blockScope.subscopes[j] instanceof ClassScope) {
4766
				continue next;
4606
								SourceTypeBinding localType =
4607
									((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
4767
4608
4768
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
4609
								if (localType == exceptionType) {
4769
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
4610
									isQualified = false;
4770
				continue next;
4611
									break done;
4612
								}
4613
							}
4614
						}
4615
						break;
4771
4616
4772
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
4617
					case Scope.CLASS_SCOPE :
4618
						SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
4619
						ReferenceBinding[] memberTypes = type.memberTypes();
4620
						if (memberTypes != null) {
4621
							for (int j = 0; j < memberTypes.length; j++) {
4622
								if (memberTypes[j] == exceptionType) {
4623
									isQualified = false;
4624
									break done;
4625
								}
4626
							}
4627
						}
4773
4628
4774
			if (this.options.checkVisibility
4775
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
4776
				continue next;
4777
4629
4778
			char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
4630
						break;
4779
4631
4780
			int relevance = computeBaseRelevance();
4632
					case Scope.COMPILATION_UNIT_SCOPE :
4781
			relevance += computeRelevanceForResolution();
4633
						SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
4782
			relevance += computeRelevanceForInterestingProposal();
4634
						if (types != null) {
4783
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
4635
							for (int j = 0; j < types.length; j++) {
4784
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4636
								if (types[j] == exceptionType) {
4637
									isQualified = false;
4638
									break done;
4639
								}
4640
							}
4641
						}
4642
						break done;
4643
				}
4644
				currentScope = currentScope.parent;
4645
			}
4785
4646
4786
			if (memberType.isClass()) {
4647
			if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
4787
				relevance += computeRelevanceForClass();
4648
				if (memberPackageName == null || memberPackageName.length == 0)
4788
			} else if(memberType.isEnum()) {
4649
					if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
4789
				relevance += computeRelevanceForEnum();
4650
						return; // ignore types from the default package from outside it
4790
			} else if (memberType.isInterface()) {
4651
			} else {
4791
				relevance += computeRelevanceForInterface();
4652
				isQualified = false;
4792
			}
4653
			}
4793
			this.noProposal = false;
4654
4794
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4655
			if (isQualified) {
4795
				createTypeProposal(
4656
				completionName =
4796
						memberType,
4657
					CharOperation.concat(
4797
						memberType.qualifiedSourceName(),
4658
							memberPackageName,
4798
						IAccessRule.K_ACCESSIBLE,
4659
							CharOperation.concat(
4799
						completionName,
4660
									memberEnclosingTypeNames,
4800
						relevance,
4661
									memberTypeName,
4801
						null,
4662
									'.'),
4802
						null,
4663
							'.');
4803
						null,
4804
						false);
4805
			}
4664
			}
4806
		}
4665
		}
4807
	}
4808
4666
4809
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
4667
		int relevance = computeBaseRelevance();
4810
		FieldBinding[] fields = ref.availableFields();
4668
		relevance += computeRelevanceForResolution();
4669
		relevance += computeRelevanceForInterestingProposal();
4670
		relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
4671
		relevance += computeRelevanceForExpectingType(exceptionType);
4672
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4673
		if(!this.insideQualifiedReference) {
4674
			relevance += computeRelevanceForQualification(isQualified);
4675
		}
4676
		relevance += computeRelevanceForClass();
4677
		relevance += computeRelevanceForException();
4811
4678
4812
		int fieldLength = fieldName.length;
4679
		this.noProposal = false;
4813
		next : for (int m = fields.length; --m >= 0;) {
4680
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
4814
			FieldBinding field = fields[m];
4681
			createTypeProposal(
4682
					exceptionType,
4683
					exceptionType.qualifiedSourceName(),
4684
					IAccessRule.K_ACCESSIBLE,
4685
					completionName,
4686
					relevance,
4687
					null,
4688
					null,
4689
					null,
4690
					false);
4691
		}
4692
	}
4693
	private void findExceptionFromTryStatement(
4694
			char[] typeName,
4695
			ReferenceBinding receiverType,
4696
			SourceTypeBinding invocationType,
4697
			BlockScope scope,
4698
			ObjectVector typesFound) {
4815
4699
4816
			if (fieldLength > field.name.length)
4700
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
4817
				continue next;
4701
			ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
4818
4702
4819
			if (field.isSynthetic())
4703
			findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
4820
				continue next;
4704
		}
4705
	}
4706
	private void findExplicitConstructors(
4707
		char[] name,
4708
		ReferenceBinding currentType,
4709
		MethodScope scope,
4710
		InvocationSite invocationSite) {
4821
4711
4822
			if (!field.isStatic())
4712
		ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
4823
				continue next;
4713
		MethodBinding enclosingConstructor = constructorDeclaration.binding;
4824
4714
4825
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
4715
		// No visibility checks can be performed without the scope & invocationSite
4826
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
4716
		MethodBinding[] methods = currentType.availableMethods();
4827
				continue next;
4717
		if(methods != null) {
4718
			next : for (int f = methods.length; --f >= 0;) {
4719
				MethodBinding constructor = methods[f];
4720
				if (constructor != enclosingConstructor && constructor.isConstructor()) {
4828
4721
4829
			if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
4722
					if (constructor.isSynthetic()) continue next;
4830
4723
4831
			if (this.options.checkVisibility
4724
					if (this.options.checkDeprecation &&
4832
				&& !field.canBeSeenBy(this.unitScope.fPackage))
4725
							constructor.isViewedAsDeprecated() &&
4833
				continue next;
4726
							!scope.isDefinedInSameUnit(constructor.declaringClass))
4727
						continue next;
4834
4728
4835
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
4729
					if (this.options.checkVisibility
4730
						&& !constructor.canBeSeenBy(invocationSite, scope))	continue next;
4836
4731
4837
			int relevance = computeBaseRelevance();
4732
					TypeBinding[] parameters = constructor.parameters;
4838
			relevance += computeRelevanceForResolution();
4733
					int paramLength = parameters.length;
4839
			relevance += computeRelevanceForInterestingProposal();
4840
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4841
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4842
4734
4843
			this.noProposal = false;
4735
					char[][] parameterPackageNames = new char[paramLength][];
4844
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
4736
					char[][] parameterTypeNames = new char[paramLength][];
4845
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4737
					for (int i = 0; i < paramLength; i++) {
4846
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
4738
						TypeBinding type = parameters[i];
4847
				proposal.setSignature(getSignature(field.type));
4739
						parameterPackageNames[i] = type.qualifiedPackageName();
4848
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4740
						parameterTypeNames[i] = type.qualifiedSourceName();
4849
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4741
					}
4850
				proposal.setPackageName(field.type.qualifiedPackageName());
4742
					char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
4851
				proposal.setTypeName(field.type.qualifiedSourceName());
4743
4852
				proposal.setName(field.name);
4744
					char[] completion = CharOperation.NO_CHAR;
4853
				proposal.setCompletion(completionName);
4745
					if (this.source != null
4854
				proposal.setFlags(field.modifiers);
4746
						&& this.source.length > this.endPosition
4855
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4747
						&& this.source[this.endPosition] == '(')
4856
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4748
						completion = name;
4857
				proposal.setRelevance(relevance);
4749
					else
4858
				this.requestor.accept(proposal);
4750
						completion = CharOperation.concat(name, new char[] { '(', ')' });
4859
				if(DEBUG) {
4751
4860
					this.printDebug(proposal);
4752
					int relevance = computeBaseRelevance();
4753
					relevance += computeRelevanceForResolution();
4754
					relevance += computeRelevanceForInterestingProposal();
4755
					relevance += computeRelevanceForCaseMatching(this.completionToken, name);
4756
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4757
4758
					this.noProposal = false;
4759
					if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
4760
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
4761
						proposal.setDeclarationSignature(getSignature(currentType));
4762
						proposal.setSignature(getSignature(constructor));
4763
						MethodBinding original = constructor.original();
4764
						if(original != constructor) {
4765
							proposal.setOriginalSignature(getSignature(original));
4766
						}
4767
						proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
4768
						proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
4769
						proposal.setParameterPackageNames(parameterPackageNames);
4770
						proposal.setParameterTypeNames(parameterTypeNames);
4771
						//proposal.setPackageName(null);
4772
						//proposal.setTypeName(null);
4773
						proposal.setName(name);
4774
						proposal.setIsContructor(true);
4775
						proposal.setCompletion(completion);
4776
						proposal.setFlags(constructor.modifiers);
4777
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4778
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4779
						proposal.setRelevance(relevance);
4780
						if(parameterNames != null) proposal.setParameterNames(parameterNames);
4781
						this.requestor.accept(proposal);
4782
						if(DEBUG) {
4783
							this.printDebug(proposal);
4784
						}
4785
					}
4861
				}
4786
				}
4862
			}
4787
			}
4863
		}
4788
		}
4864
	}
4789
	}
4790
	// Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
4791
	private void findFields(
4792
		char[] fieldName,
4793
		FieldBinding[] fields,
4794
		Scope scope,
4795
		ObjectVector fieldsFound,
4796
		ObjectVector localsFound,
4797
		boolean onlyStaticFields,
4798
		ReferenceBinding receiverType,
4799
		InvocationSite invocationSite,
4800
		Scope invocationScope,
4801
		boolean implicitCall,
4802
		boolean canBePrefixed,
4803
		Binding[] missingElements,
4804
		int[] missingElementsStarts,
4805
		int[] missingElementsEnds,
4806
		boolean missingElementsHaveProblems,
4807
		char[] castedReceiver,
4808
		int receiverStart,
4809
		int receiverEnd) {
4865
4810
4866
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
4811
		ObjectVector newFieldsFound = new ObjectVector();
4867
		MethodBinding[] methods = ref.availableMethods();
4812
		// Inherited fields which are hidden by subclasses are filtered out
4813
		// No visibility checks can be performed without the scope & invocationSite
4868
4814
4869
		int methodLength = methodName.length;
4815
		int fieldLength = fieldName.length;
4870
		next : for (int m = methods.length; --m >= 0;) {
4816
		next : for (int f = fields.length; --f >= 0;) {
4871
			MethodBinding method = methods[m];
4817
			FieldBinding field = fields[f];
4872
4818
4873
			if (method.isSynthetic()) continue next;
4819
			if (field.isSynthetic())	continue next;
4874
4820
4875
			if (method.isDefaultAbstract())	continue next;
4821
			if (onlyStaticFields && !field.isStatic()) continue next;
4876
4822
4877
			if (method.isConstructor()) continue next;
4823
			if (fieldLength > field.name.length) continue next;
4878
4824
4879
			if (!method.isStatic()) continue next;
4825
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
4826
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
4880
4827
4881
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
4828
			if (this.options.checkDeprecation &&
4829
					field.isViewedAsDeprecated() &&
4830
					!scope.isDefinedInSameUnit(field.declaringClass))
4831
				continue next;
4882
4832
4883
			if (this.options.checkVisibility
4833
			if (this.options.checkVisibility
4884
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
4834
				&& !field.canBeSeenBy(receiverType, invocationSite, scope))	continue next;
4885
4835
4886
			if (methodLength > method.selector.length)
4836
			boolean prefixRequired = false;
4887
				continue next;
4888
4837
4889
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
4838
			for (int i = fieldsFound.size; --i >= 0;) {
4890
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
4839
				Object[] other = (Object[])fieldsFound.elementAt(i);
4891
				continue next;
4840
				FieldBinding otherField = (FieldBinding) other[0];
4841
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
4842
				if (field == otherField && receiverType == otherReceiverType)
4843
					continue next;
4844
				if (CharOperation.equals(field.name, otherField.name, true)) {
4845
					if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
4846
						continue next;
4847
					if (otherField.declaringClass.isInterface()) {
4848
						if (field.declaringClass == scope.getJavaLangObject())
4849
							continue next;
4850
						if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
4851
							continue next;
4852
					}
4853
					if (field.declaringClass.isInterface())
4854
						if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
4855
							continue next;
4856
					if(canBePrefixed) {
4857
						prefixRequired = true;
4858
					} else {
4859
						continue next;
4860
					}
4861
				}
4862
			}
4892
4863
4893
			int length = method.parameters.length;
4864
			for (int l = localsFound.size; --l >= 0;) {
4894
			char[][] parameterPackageNames = new char[length][];
4865
				LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
4895
			char[][] parameterTypeNames = new char[length][];
4896
4866
4897
			for (int i = 0; i < length; i++) {
4867
				if (CharOperation.equals(field.name, local.name, true)) {
4898
				TypeBinding type = method.original().parameters[i];
4868
					SourceTypeBinding declarationType = scope.enclosingSourceType();
4899
				parameterPackageNames[i] = type.qualifiedPackageName();
4869
					if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
4900
				parameterTypeNames[i] = type.qualifiedSourceName();
4870
						continue next;
4871
					}
4872
					if(canBePrefixed) {
4873
						prefixRequired = true;
4874
					} else {
4875
						continue next;
4876
					}
4877
					break;
4878
				}
4901
			}
4879
			}
4902
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
4903
4880
4904
			char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
4881
			newFieldsFound.add(new Object[]{field, receiverType});
4882
4883
			char[] completion = field.name;
4884
4885
			if(prefixRequired || this.options.forceImplicitQualification){
4886
				char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
4887
				completion = CharOperation.concat(prefix,completion,'.');
4888
			}
4889
4890
4891
			if (castedReceiver != null) {
4892
				completion = CharOperation.concat(castedReceiver, completion);
4893
			}
4894
4895
			// Special case for javadoc completion
4896
			if (this.assistNodeInJavadoc > 0) {
4897
				if (invocationSite instanceof CompletionOnJavadocFieldReference) {
4898
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
4899
					if (fieldRef.receiver.isThis()) {
4900
						if (fieldRef.completeInText()) {
4901
							completion = CharOperation.concat(new char[] { '#' }, field.name);
4902
						}
4903
					} else if (fieldRef.completeInText()) {
4904
						if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
4905
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
4906
							completion = CharOperation.concat(typeRef.token, field.name, '#');
4907
						} else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
4908
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
4909
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
4910
						}
4911
					}
4912
				}
4913
			}
4905
4914
4906
			int relevance = computeBaseRelevance();
4915
			int relevance = computeBaseRelevance();
4907
			relevance += computeRelevanceForResolution();
4916
			relevance += computeRelevanceForResolution();
4908
			relevance += computeRelevanceForInterestingProposal();
4917
			relevance += computeRelevanceForInterestingProposal(field);
4909
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
4918
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
4919
			relevance += computeRelevanceForExpectingType(field.type);
4920
			relevance += computeRelevanceForEnumConstant(field.type);
4921
			relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
4922
			relevance += computeRelevanceForQualification(prefixRequired);
4910
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4923
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
4924
			if (onlyStaticFields && this.insideQualifiedReference) {
4925
				relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
4926
			}
4927
			if (missingElements != null) {
4928
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
4929
			}
4911
4930
4912
			this.noProposal = false;
4931
			this.noProposal = false;
4913
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
4932
			if (castedReceiver == null) {
4914
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
4933
				// Standard proposal
4915
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
4934
				if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
4916
				proposal.setSignature(getSignature(method));
4935
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
4917
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
4936
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4918
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
4937
					proposal.setSignature(getSignature(field.type));
4919
				proposal.setParameterPackageNames(parameterPackageNames);
4938
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4920
				proposal.setParameterTypeNames(parameterTypeNames);
4939
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4921
				proposal.setPackageName(method.returnType.qualifiedPackageName());
4940
					proposal.setPackageName(field.type.qualifiedPackageName());
4922
				proposal.setTypeName(method.returnType.qualifiedSourceName());
4941
					proposal.setTypeName(field.type.qualifiedSourceName());
4923
				proposal.setName(method.selector);
4942
					proposal.setName(field.name);
4924
				proposal.setCompletion(completionName);
4943
					if (missingElements != null) {
4925
				proposal.setFlags(method.modifiers);
4944
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
4926
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4945
						for (int i = 0; i < missingElements.length; i++) {
4927
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4946
							subProposals[i] =
4928
				proposal.setRelevance(relevance);
4947
								createRequiredTypeProposal(
4929
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
4948
										missingElements[i],
4930
				this.requestor.accept(proposal);
4949
										missingElementsStarts[i],
4931
				if(DEBUG) {
4950
										missingElementsEnds[i],
4932
					this.printDebug(proposal);
4951
										relevance);
4933
				}
4952
						}
4934
			}
4953
						proposal.setRequiredProposals(subProposals);
4935
		}
4954
					}
4936
	}
4955
					proposal.setCompletion(completion);
4937
4956
					proposal.setFlags(field.modifiers);
4938
	/*
4957
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4939
	 * Find javadoc block tags for a given completion javadoc tag node
4958
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4940
	 */
4959
					proposal.setRelevance(relevance);
4941
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
4960
					this.requestor.accept(proposal);
4942
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
4961
					if(DEBUG) {
4943
		if (possibleTags == null) return;
4962
						this.printDebug(proposal);
4944
		int length = possibleTags.length;
4963
					}
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
4950
			this.noProposal = false;
4951
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
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
			}
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
4983
			this.noProposal = false;
4984
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
4985
				char[] possibleTag = possibleTags[i];
4986
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
4987
				proposal.setName(possibleTag);
4988
				int tagLength = possibleTag.length;
4989
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
4990
				char[] completion = new char[2+tagLength+1];
4991
				completion[0] = '{';
4992
				completion[1] = '@';
4993
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
4994
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
4995
				//completion[tagLength+2] = ' ';
4996
				completion[tagLength+2] = '}';
4997
				proposal.setCompletion(completion);
4998
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4999
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5000
				proposal.setRelevance(relevance);
5001
				this.requestor.accept(proposal);
5002
				if (DEBUG) {
5003
					this.printDebug(proposal);
5004
				}
4964
				}
5005
			}
5006
		}
5007
	}
5008
5009
	// what about onDemand types? Ignore them since it does not happen!
5010
	// import p1.p2.A.*;
5011
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
5012
		if(choices == null || choices.length == 0) return;
5013
5014
		int length = keyword.length;
5015
		if (canCompleteEmptyToken || length > 0)
5016
			for (int i = 0; i < choices.length; i++)
5017
				if (length <= choices[i].length
5018
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
5019
				)){
5020
					int relevance = computeBaseRelevance();
5021
					relevance += computeRelevanceForResolution();
5022
					relevance += computeRelevanceForInterestingProposal();
5023
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
5024
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
5025
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
5026
4965
5027
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
4966
				// Javadoc completions
5028
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
4967
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
5029
						relevance += computeRelevanceForQualification(false);
4968
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
4969
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
4970
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
4971
					proposal.setSignature(getSignature(field.type));
4972
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
4973
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
4974
					proposal.setPackageName(field.type.qualifiedPackageName());
4975
					proposal.setTypeName(field.type.qualifiedSourceName());
4976
					proposal.setName(field.name);
4977
					proposal.setCompletion(javadocCompletion);
4978
					proposal.setFlags(field.modifiers);
4979
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
4980
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
4981
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4982
					proposal.setRelevance(relevance+R_INLINE_TAG);
4983
					this.requestor.accept(proposal);
4984
					if(DEBUG) {
4985
						this.printDebug(proposal);
5030
					}
4986
					}
5031
					this.noProposal = false;
4987
					// Javadoc value completion for static fields
5032
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
4988
					if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
5033
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
4989
						javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
5034
						proposal.setName(choices[i]);
4990
						InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
5035
						proposal.setCompletion(choices[i]);
4991
						valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
5036
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
4992
						valueProposal.setSignature(getSignature(field.type));
5037
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
4993
						valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5038
						proposal.setRelevance(relevance);
4994
						valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5039
						this.requestor.accept(proposal);
4995
						valueProposal.setPackageName(field.type.qualifiedPackageName());
4996
						valueProposal.setTypeName(field.type.qualifiedSourceName());
4997
						valueProposal.setName(field.name);
4998
						valueProposal.setCompletion(javadocCompletion);
4999
						valueProposal.setFlags(field.modifiers);
5000
						valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
5001
						valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5002
						valueProposal.setRelevance(relevance+R_VALUE_TAG);
5003
						this.requestor.accept(valueProposal);
5040
						if(DEBUG) {
5004
						if(DEBUG) {
5041
							this.printDebug(proposal);
5005
							this.printDebug(valueProposal);
5042
						}
5006
						}
5043
					}
5007
					}
5044
				}
5008
				}
5045
	}
5009
			} else {
5046
	private void findTrueOrFalseKeywords(char[][] choices) {
5010
				if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5047
		if(choices == null || choices.length == 0) return;
5011
					InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5048
5012
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
5049
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
5013
					proposal.setSignature(getSignature(field.type));
5050
5014
					proposal.setReceiverSignature(getSignature(receiverType));
5051
		for (int i = 0; i < choices.length; i++) {
5015
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
5052
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
5016
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
5053
					CharOperation.equals(choices[i], Keywords.FALSE)
5017
					proposal.setPackageName(field.type.qualifiedPackageName());
5054
			){
5018
					proposal.setTypeName(field.type.qualifiedSourceName());
5055
				int relevance = computeBaseRelevance();
5019
					proposal.setName(field.name);
5056
				relevance += computeRelevanceForResolution();
5020
					if (missingElements != null) {
5057
				relevance += computeRelevanceForInterestingProposal();
5021
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5058
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
5022
						for (int i = 0; i < missingElements.length; i++) {
5059
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
5023
							subProposals[i] =
5060
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
5024
								createRequiredTypeProposal(
5061
				relevance += computeRelevanceForQualification(false);
5025
										missingElements[i],
5062
				relevance += R_TRUE_OR_FALSE;
5026
										missingElementsStarts[i],
5063
5027
										missingElementsEnds[i],
5064
				this.noProposal = false;
5028
										relevance);
5065
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5029
						}
5066
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5030
						proposal.setRequiredProposals(subProposals);
5067
					proposal.setName(choices[i]);
5031
					}
5068
					proposal.setCompletion(choices[i]);
5032
					proposal.setCompletion(completion);
5033
					proposal.setFlags(field.modifiers);
5069
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5034
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5035
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5070
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5036
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5071
					proposal.setRelevance(relevance);
5037
					proposal.setRelevance(relevance);
5072
					this.requestor.accept(proposal);
5038
					this.requestor.accept(proposal);
Lines 5076-5682 Link Here
5076
				}
5042
				}
5077
			}
5043
			}
5078
		}
5044
		}
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
5045
5096
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
5046
		fieldsFound.addAll(newFieldsFound);
5097
			// abtract
5047
	}
5098
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
5048
	private void findFields(
5099
				keywords[count++] = Keywords.ABSTRACT;
5049
		char[] fieldName,
5100
			}
5050
		ReferenceBinding receiverType,
5101
5051
		Scope scope,
5102
			// final
5052
		ObjectVector fieldsFound,
5103
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
5053
		ObjectVector localsFound,
5104
				keywords[count++] = Keywords.FINAL;
5054
		boolean onlyStaticFields,
5105
			}
5055
		InvocationSite invocationSite,
5106
5056
		Scope invocationScope,
5107
			// static
5057
		boolean implicitCall,
5108
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
5058
		boolean canBePrefixed,
5109
				keywords[count++] = Keywords.STATIC;
5059
		Binding[] missingElements,
5110
			}
5060
		int[] missingElementsStarts,
5111
5061
		int[] missingElementsEnds,
5112
			boolean canBeField = true;
5062
		boolean missingElementsHaveProblems,
5113
			boolean canBeMethod = true;
5063
		char[] castedReceiver,
5114
			boolean canBeType = true;
5064
		int receiverStart,
5115
			if((modifiers & ClassFileConstants.AccNative) != 0
5065
		int receiverEnd) {
5116
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
5117
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
5118
				canBeField = false;
5119
				canBeType = false;
5120
			}
5121
5122
			if((modifiers & ClassFileConstants.AccTransient) != 0
5123
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
5124
				canBeMethod = false;
5125
				canBeType = false;
5126
			}
5127
5066
5128
			if(canBeField) {
5067
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
5129
				// transient
5068
		if (fieldName == null && notInJavadoc)
5130
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
5069
			return;
5131
					keywords[count++] = Keywords.TRANSIENT;
5132
				}
5133
5070
5134
				// volatile
5071
		ReferenceBinding currentType = receiverType;
5135
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
5072
		ReferenceBinding[] interfacesToVisit = null;
5136
					keywords[count++] = Keywords.VOLATILE;
5073
		int nextPosition = 0;
5074
		do {
5075
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5076
			if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5077
				if (interfacesToVisit == null) {
5078
					interfacesToVisit = itsInterfaces;
5079
					nextPosition = interfacesToVisit.length;
5080
				} else {
5081
					int itsLength = itsInterfaces.length;
5082
					if (nextPosition + itsLength >= interfacesToVisit.length)
5083
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5084
					nextInterface : for (int a = 0; a < itsLength; a++) {
5085
						ReferenceBinding next = itsInterfaces[a];
5086
						for (int b = 0; b < nextPosition; b++)
5087
							if (next == interfacesToVisit[b]) continue nextInterface;
5088
						interfacesToVisit[nextPosition++] = next;
5089
					}
5137
				}
5090
				}
5138
			}
5091
			}
5139
5092
5140
			if(canBeMethod) {
5093
			FieldBinding[] fields = currentType.availableFields();
5141
				// native
5094
			if(fields != null && fields.length > 0) {
5142
				if((modifiers & ClassFileConstants.AccNative) == 0) {
5095
				findFields(
5143
					keywords[count++] = Keywords.NATIVE;
5096
					fieldName,
5144
				}
5097
					fields,
5098
					scope,
5099
					fieldsFound,
5100
					localsFound,
5101
					onlyStaticFields,
5102
					receiverType,
5103
					invocationSite,
5104
					invocationScope,
5105
					implicitCall,
5106
					canBePrefixed,
5107
					missingElements,
5108
					missingElementsStarts,
5109
					missingElementsEnds,
5110
					missingElementsHaveProblems,
5111
					castedReceiver,
5112
					receiverStart,
5113
					receiverEnd);
5114
			}
5115
			currentType = currentType.superclass();
5116
		} while (notInJavadoc && currentType != null);
5145
5117
5146
				// strictfp
5118
		if (notInJavadoc && interfacesToVisit != null) {
5147
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
5119
			for (int i = 0; i < nextPosition; i++) {
5148
					keywords[count++] = Keywords.STRICTFP;
5120
				ReferenceBinding anInterface = interfacesToVisit[i];
5121
				FieldBinding[] fields = anInterface.availableFields();
5122
				if(fields !=  null) {
5123
					findFields(
5124
						fieldName,
5125
						fields,
5126
						scope,
5127
						fieldsFound,
5128
						localsFound,
5129
						onlyStaticFields,
5130
						receiverType,
5131
						invocationSite,
5132
						invocationScope,
5133
						implicitCall,
5134
						canBePrefixed,
5135
						missingElements,
5136
						missingElementsStarts,
5137
						missingElementsEnds,
5138
						missingElementsHaveProblems,
5139
						castedReceiver,
5140
						receiverStart,
5141
						receiverEnd);
5149
				}
5142
				}
5150
5143
5151
				// synchronized
5144
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5152
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
5145
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
5153
					keywords[count++] = Keywords.SYNCHRONIZED;
5146
					int itsLength = itsInterfaces.length;
5147
					if (nextPosition + itsLength >= interfacesToVisit.length)
5148
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5149
					nextInterface : for (int a = 0; a < itsLength; a++) {
5150
						ReferenceBinding next = itsInterfaces[a];
5151
						for (int b = 0; b < nextPosition; b++)
5152
							if (next == interfacesToVisit[b]) continue nextInterface;
5153
						interfacesToVisit[nextPosition++] = next;
5154
					}
5154
				}
5155
				}
5155
			}
5156
			}
5157
		}
5158
	}
5156
5159
5157
			if(canBeType) {
5160
	protected void findFieldsAndMethods(
5158
				keywords[count++] = Keywords.CLASS;
5161
		char[] token,
5159
				keywords[count++] = Keywords.INTERFACE;
5162
		TypeBinding receiverType,
5163
		Scope scope,
5164
		ObjectVector fieldsFound,
5165
		ObjectVector methodsFound,
5166
		InvocationSite invocationSite,
5167
		Scope invocationScope,
5168
		boolean implicitCall,
5169
		boolean superCall,
5170
		Binding[] missingElements,
5171
		int[] missingElementsStarts,
5172
		int[] missingElementsEnds,
5173
		boolean missingElementsHaveProblems,
5174
		char[] castedReceiver,
5175
		int receiverStart,
5176
		int receiverEnd) {
5160
5177
5161
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
5178
		if (token == null)
5162
					keywords[count++] = Keywords.ENUM;
5179
			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
5180
5172
		findKeywords(token, keywords, false, false);
5181
		if (receiverType.isBaseType())
5173
	}
5182
			return; // nothing else is possible with base types
5174
5183
5175
	protected void findMembers(
5184
		boolean proposeField =
5176
			char[] token,
5185
			castedReceiver == null ?
5177
			ReferenceBinding receiverType,
5186
					!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
5178
			Scope scope,
5187
					!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
5179
			InvocationSite invocationSite,
5188
		boolean proposeMethod =
5180
			boolean isInsideAnnotationAttribute,
5189
			castedReceiver == null ?
5181
			Binding[] missingElements,
5190
					!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
5182
			int[] missingElementsStarts,
5191
					!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
5183
			int[] missingElementsEnds,
5184
			boolean missingElementsHaveProblems) {
5185
5192
5186
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
5193
		if (receiverType.isArrayType()) {
5187
			findMemberTypes(
5194
			if (proposeField
5188
					token,
5195
				&& token.length <= lengthField.length
5189
					receiverType,
5196
				&& CharOperation.prefixEquals(token, lengthField, false /* ignore case */
5190
					scope,
5197
			)) {
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
5198
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();
5199
				int relevance = computeBaseRelevance();
5220
				relevance += computeRelevanceForResolution();
5200
				relevance += computeRelevanceForResolution();
5221
				relevance += computeRelevanceForInterestingProposal();
5201
				relevance += computeRelevanceForInterestingProposal();
5222
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
5202
				relevance += computeRelevanceForCaseMatching(token,lengthField);
5223
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
5203
				relevance += computeRelevanceForExpectingType(TypeBinding.INT);
5224
				relevance += R_NON_INHERITED;
5204
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
5225
5205
				if (missingElements != null) {
5206
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5207
				}
5226
				this.noProposal = false;
5208
				this.noProposal = false;
5227
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
5209
				if (castedReceiver == null) {
5228
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
5210
					if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
5229
					proposal.setName(Keywords.THIS);
5211
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
5230
					proposal.setCompletion(Keywords.THIS);
5212
						proposal.setDeclarationSignature(getSignature(receiverType));
5231
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5213
						proposal.setSignature(INT_SIGNATURE);
5232
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5214
						proposal.setTypeName(INT);
5233
					proposal.setRelevance(relevance);
5215
						proposal.setName(lengthField);
5234
					this.requestor.accept(proposal);
5216
						if (missingElements != null) {
5235
					if (DEBUG) {
5217
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5236
						this.printDebug(proposal);
5218
							for (int i = 0; i < missingElements.length; i++) {
5219
								subProposals[i] =
5220
									createRequiredTypeProposal(
5221
											missingElements[i],
5222
											missingElementsStarts[i],
5223
											missingElementsEnds[i],
5224
											relevance);
5225
							}
5226
							proposal.setRequiredProposals(subProposals);
5227
						}
5228
						proposal.setCompletion(lengthField);
5229
						proposal.setFlags(Flags.AccPublic);
5230
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5231
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5232
						proposal.setRelevance(relevance);
5233
						this.requestor.accept(proposal);
5234
						if(DEBUG) {
5235
							this.printDebug(proposal);
5236
						}
5237
					}
5238
				} else {
5239
					char[] completion = CharOperation.concat(castedReceiver, lengthField);
5240
5241
					if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5242
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5243
						proposal.setDeclarationSignature(getSignature(receiverType));
5244
						proposal.setSignature(INT_SIGNATURE);
5245
						proposal.setReceiverSignature(getSignature(receiverType));
5246
						proposal.setTypeName(INT);
5247
						proposal.setName(lengthField);
5248
						if (missingElements != null) {
5249
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5250
							for (int i = 0; i < missingElements.length; i++) {
5251
								subProposals[i] =
5252
									createRequiredTypeProposal(
5253
											missingElements[i],
5254
											missingElementsStarts[i],
5255
											missingElementsEnds[i],
5256
											relevance);
5257
							}
5258
							proposal.setRequiredProposals(subProposals);
5259
						}
5260
						proposal.setCompletion(completion);
5261
						proposal.setFlags(Flags.AccPublic);
5262
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5263
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5264
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5265
						proposal.setRelevance(relevance);
5266
						this.requestor.accept(proposal);
5267
						if(DEBUG) {
5268
							this.printDebug(proposal);
5269
						}
5237
					}
5270
					}
5238
				}
5271
				}
5239
			}
5272
			}
5240
		}
5273
			if (proposeMethod
5274
				&& token.length <= cloneMethod.length
5275
				&& CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
5276
			) {
5277
				ReferenceBinding objectRef = scope.getJavaLangObject();
5241
5278
5242
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
5279
				int relevance = computeBaseRelevance();
5280
				relevance += computeRelevanceForResolution();
5281
				relevance += computeRelevanceForInterestingProposal();
5282
				relevance += computeRelevanceForCaseMatching(token, cloneMethod);
5283
				relevance += computeRelevanceForExpectingType(objectRef);
5284
				relevance += computeRelevanceForStatic(false, false);
5285
				relevance += computeRelevanceForQualification(false);
5286
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
5287
				if (missingElements != null) {
5288
					relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5289
				}
5290
				char[] completion;
5291
				if (this.source != null
5292
					&& this.source.length > this.endPosition
5293
					&& this.source[this.endPosition] == '(') {
5294
					completion = cloneMethod;
5295
					} else {
5296
					completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
5297
				}
5298
5299
				if (castedReceiver != null) {
5300
					completion = CharOperation.concat(castedReceiver, completion);
5301
				}
5302
5303
				this.noProposal = false;
5304
				if (castedReceiver == null) {
5305
					if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
5306
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
5307
						proposal.setDeclarationSignature(getSignature(receiverType));
5308
						proposal.setSignature(
5309
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5310
										createMethodSignature(
5311
												CharOperation.NO_CHAR_CHAR,
5312
												CharOperation.NO_CHAR_CHAR,
5313
												getSignature(receiverType)) :
5314
										createMethodSignature(
5315
												CharOperation.NO_CHAR_CHAR,
5316
												CharOperation.NO_CHAR_CHAR,
5317
												CharOperation.concatWith(JAVA_LANG, '.'),
5318
												OBJECT));
5319
						//proposal.setOriginalSignature(null);
5320
						//proposal.setDeclarationPackageName(null);
5321
						//proposal.setDeclarationTypeName(null);
5322
						//proposal.setParameterPackageNames(null);
5323
						//proposal.setParameterTypeNames(null);
5324
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5325
						proposal.setTypeName(OBJECT);
5326
						proposal.setName(cloneMethod);
5327
						if (missingElements != null) {
5328
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5329
							for (int i = 0; i < missingElements.length; i++) {
5330
								subProposals[i] =
5331
									createRequiredTypeProposal(
5332
											missingElements[i],
5333
											missingElementsStarts[i],
5334
											missingElementsEnds[i],
5335
											relevance);
5336
							}
5337
							proposal.setRequiredProposals(subProposals);
5338
						}
5339
						proposal.setCompletion(completion);
5340
						proposal.setFlags(Flags.AccPublic);
5341
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5342
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5343
						proposal.setRelevance(relevance);
5344
						this.requestor.accept(proposal);
5345
						if(DEBUG) {
5346
							this.printDebug(proposal);
5347
						}
5348
					}
5349
					methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
5350
				} else {
5351
					if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
5352
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
5353
						proposal.setDeclarationSignature(getSignature(receiverType));
5354
						proposal.setSignature(
5355
								this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
5356
										createMethodSignature(
5357
												CharOperation.NO_CHAR_CHAR,
5358
												CharOperation.NO_CHAR_CHAR,
5359
												getSignature(receiverType)) :
5360
										createMethodSignature(
5361
												CharOperation.NO_CHAR_CHAR,
5362
												CharOperation.NO_CHAR_CHAR,
5363
												CharOperation.concatWith(JAVA_LANG, '.'),
5364
												OBJECT));
5365
						proposal.setReceiverSignature(getSignature(receiverType));
5366
						proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
5367
						proposal.setTypeName(OBJECT);
5368
						proposal.setName(cloneMethod);
5369
						if (missingElements != null) {
5370
							CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
5371
							for (int i = 0; i < missingElements.length; i++) {
5372
								subProposals[i] =
5373
									createRequiredTypeProposal(
5374
											missingElements[i],
5375
											missingElementsStarts[i],
5376
											missingElementsEnds[i],
5377
											relevance);
5378
							}
5379
							proposal.setRequiredProposals(subProposals);
5380
						}
5381
						proposal.setCompletion(completion);
5382
						proposal.setFlags(Flags.AccPublic);
5383
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5384
						proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
5385
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5386
						proposal.setRelevance(relevance);
5387
						this.requestor.accept(proposal);
5388
						if(DEBUG) {
5389
							this.printDebug(proposal);
5390
						}
5391
					}
5392
				}
5393
			}
5394
5395
			receiverType = scope.getJavaLangObject();
5396
		}
5397
		
5398
		checkCancel();
5399
		
5400
		if(proposeField) {
5243
			findFields(
5401
			findFields(
5244
				token,
5402
				token,
5245
				receiverType,
5403
				(ReferenceBinding) receiverType,
5246
				scope,
5404
				scope,
5405
				fieldsFound,
5247
				new ObjectVector(),
5406
				new ObjectVector(),
5248
				new ObjectVector(),
5249
				true,
5250
				invocationSite,
5251
				scope,
5252
				false,
5407
				false,
5408
				invocationSite,
5409
				invocationScope,
5410
				implicitCall,
5253
				false,
5411
				false,
5254
				missingElements,
5412
				missingElements,
5255
				missingElementsStarts,
5413
				missingElementsStarts,
5256
				missingElementsEnds,
5414
				missingElementsEnds,
5257
				missingElementsHaveProblems,
5415
				missingElementsHaveProblems,
5258
				null,
5416
				castedReceiver,
5259
				-1,
5417
				receiverStart,
5260
				-1);
5418
				receiverEnd);
5261
		}
5419
		}
5262
5420
5263
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
5421
		if(proposeMethod) {
5264
			findMethods(
5422
			findMethods(
5265
				token,
5423
				token,
5266
				null,
5424
				null,
5267
				null,
5425
				null,
5268
				receiverType,
5426
				(ReferenceBinding) receiverType,
5269
				scope,
5427
				scope,
5270
				new ObjectVector(),
5428
				methodsFound,
5271
				true,
5272
				false,
5429
				false,
5273
				false,
5430
				false,
5274
				invocationSite,
5431
				invocationSite,
5275
				scope,
5432
				invocationScope,
5276
				false,
5433
				implicitCall,
5277
				false,
5434
				superCall,
5278
				false,
5435
				false,
5279
				missingElements,
5436
				missingElements,
5280
				missingElementsStarts,
5437
				missingElementsStarts,
5281
				missingElementsEnds,
5438
				missingElementsEnds,
5282
				missingElementsHaveProblems,
5439
				missingElementsHaveProblems,
5283
				null,
5440
				castedReceiver,
5284
				-1,
5441
				receiverStart,
5285
				-1);
5442
				receiverEnd);
5286
		}
5443
		}
5287
	}
5444
	}
5288
5445
5289
	private void findMembersFromMissingType(
5446
	protected void findFieldsAndMethodsFromAnotherReceiver(
5290
			final char[] token,
5447
			char[] token,
5291
			final long pos,
5448
			TypeReference receiverType,
5292
			TypeBinding resolveType,
5449
			Scope scope,
5293
			final Scope scope,
5450
			ObjectVector fieldsFound,
5294
			final InvocationSite invocationSite,
5451
			ObjectVector methodsFound,
5295
			final boolean isInsideAnnotationAttribute) {
5452
			InvocationSite invocationSite,
5296
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5453
			Scope invocationScope,
5297
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5454
			boolean implicitCall,
5298
			new MissingTypesGuesser.GuessedTypeRequestor() {
5455
			boolean superCall,
5299
				public void accept(
5456
			Binding[] missingElements,
5300
						TypeBinding guessedType,
5457
			int[] missingElementsStarts,
5301
						Binding[] missingElements,
5458
			int[] missingElementsEnds,
5302
						int[] missingElementsStarts,
5459
			boolean missingElementsHaveProblems,
5303
						int[] missingElementsEnds,
5460
			char[][] receiverName,
5304
						boolean hasProblems) {
5461
			int receiverStart,
5305
					if (guessedType instanceof ReferenceBinding) {
5462
			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
5463
5324
	// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
5464
		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
5465
5341
		// Inherited member types which are hidden by subclasses are filtered out
5466
		TypeBinding receiverTypeBinding = receiverType.resolvedType;
5342
		// No visibility checks can be performed without the scope & invocationSite
5467
		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
5468
5349
			if (staticOnly && !memberType.isStatic()) continue next;
5469
		char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
5470
		if(this.source != null) {
5471
			int memberRefStart = this.startPosition;
5350
5472
5351
			if (isForbidden(memberType)) continue next;
5473
			char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5474
			char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
5352
5475
5353
			if (typeLength > memberType.sourceName.length)
5476
			castedReceiver =
5354
				continue next;
5477
				CharOperation.concat(
5478
					CharOperation.concat(
5479
						'(',
5480
						CharOperation.concat(
5481
							CharOperation.concat('(', castedTypeChars, ')'),
5482
							receiverChars),
5483
						')'),
5484
					dotChars);
5485
		} else {
5486
			castedReceiver =
5487
				CharOperation.concat(
5488
					CharOperation.concat(
5489
						'(',
5490
						CharOperation.concat(
5491
							CharOperation.concat('(', castedTypeChars, ')'),
5492
							CharOperation.concatWith(receiverName, '.')),
5493
						')'),
5494
					DOT);
5495
		}
5355
5496
5356
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
5497
		if (castedReceiver == null) return;
5357
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
5358
				continue next;
5359
5498
5360
			if (this.options.checkDeprecation &&
5499
		int oldStartPosition = this.startPosition;
5361
					memberType.isViewedAsDeprecated() &&
5500
		this.startPosition = receiverStart;
5362
					!scope.isDefinedInSameUnit(memberType))
5363
				continue next;
5364
5501
5365
			if (this.options.checkVisibility) {
5502
		findFieldsAndMethods(
5366
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
5503
				token,
5367
					continue next;
5504
				receiverTypeBinding,
5368
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
5505
				scope,
5369
					continue next;
5506
				fieldsFound,
5370
				}
5507
				methodsFound,
5371
			}
5508
				invocationSite,
5509
				invocationScope,
5510
				implicitCall,
5511
				superCall,
5512
				missingElements,
5513
				missingElementsStarts,
5514
				missingElementsEnds,
5515
				missingElementsHaveProblems,
5516
				castedReceiver,
5517
				receiverStart,
5518
				receiverEnd);
5372
5519
5373
			if (this.insideQualifiedReference &&
5520
		this.startPosition = oldStartPosition;
5374
					receiverType.isParameterizedType() &&
5521
	}
5375
					memberType.isStatic()) {
5522
	private void findFieldsAndMethodsFromCastedReceiver(
5376
				continue next;
5523
			ASTNode enclosingNode,
5377
			}
5524
			Binding qualifiedBinding,
5525
			Scope scope,
5526
			ObjectVector fieldsFound,
5527
			ObjectVector methodsFound,
5528
			InvocationSite invocationSite,
5529
			Scope invocationScope,
5530
			Expression receiver) {
5378
5531
5379
			for (int i = typesFound.size; --i >= 0;) {
5532
		if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
5380
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
5381
5533
5382
				if (memberType == otherType)
5534
		IfStatement ifStatement = (IfStatement)enclosingNode;
5383
					continue next;
5384
5535
5385
				if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
5536
		if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
5386
5537
5387
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
5538
		InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
5388
						continue next;
5389
5539
5390
					if (otherType.enclosingType().isInterface())
5540
		TypeReference instanceOfType = instanceOfExpression.type;
5391
						if (memberType.enclosingType()
5392
							.implementsInterface(otherType.enclosingType(), true))
5393
							continue next;
5394
5541
5395
					if (memberType.enclosingType().isInterface())
5542
		if (instanceOfType.resolvedType == null) return;
5396
						if (otherType.enclosingType()
5543
5397
							.implementsInterface(memberType.enclosingType(), true))
5544
		boolean findFromAnotherReceiver = false;
5398
							continue next;
5545
5399
				}
5546
		char[][] receiverName = null;
5547
		int receiverStart = -1;
5548
		int receiverEnd = -1;
5549
5550
		if (receiver instanceof QualifiedNameReference) {
5551
			QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
5552
5553
			receiverName = qualifiedNameReference.tokens;
5554
5555
			if (receiverName.length != 1) return;
5556
5557
			receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
5558
			receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
5559
5560
			// if (local instanceof X) local.|
5561
			// if (field instanceof X) field.|
5562
			if (instanceOfExpression.expression instanceof SingleNameReference &&
5563
					((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
5564
					(qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
5565
				findFromAnotherReceiver = true;
5400
			}
5566
			}
5401
5567
5402
			typesFound.add(memberType);
5568
			// if (this.field instanceof X) field.|
5569
			if (instanceOfExpression.expression instanceof FieldReference) {
5570
				FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
5403
5571
5404
			if(!this.insideQualifiedReference) {
5572
				if (fieldReference.receiver instanceof ThisReference &&
5405
				if(this.assistNodeIsClass) {
5573
						qualifiedBinding instanceof FieldBinding &&
5406
					if(!memberType.isClass()) continue next;
5574
						fieldReference.binding == qualifiedBinding) {
5407
				} else if(this.assistNodeIsInterface) {
5575
							findFromAnotherReceiver = true;
5408
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
5409
				} else if (this.assistNodeIsAnnotation) {
5410
					if(!memberType.isAnnotationType()) continue next;
5411
				}
5576
				}
5412
			}
5577
			}
5578
		} else if (receiver instanceof FieldReference) {
5579
			FieldReference fieldReference1 = (FieldReference) receiver;
5413
5580
5414
			char[] completionName = memberType.sourceName();
5581
			receiverStart = fieldReference1.sourceStart;
5582
			receiverEnd = fieldReference1.sourceEnd + 1;
5415
5583
5416
			boolean isQualified = false;
5584
			if (fieldReference1.receiver instanceof ThisReference) {
5417
			if(checkQualification && !fromStaticImport) {
5585
5418
				char[] memberPackageName = memberType.qualifiedPackageName();
5586
				receiverName = new char[][] {THIS, fieldReference1.token};
5419
				char[] memberTypeName = memberType.sourceName();
5587
5420
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
5588
				// if (field instanceof X) this.field.|
5421
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
5589
				if (instanceOfExpression.expression instanceof SingleNameReference &&
5422
					if (memberPackageName == null || memberPackageName.length == 0)
5590
						((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
5423
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
5591
					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
				}
5592
				}
5435
			}
5436
5593
5437
			int relevance = computeBaseRelevance();
5594
				// if (this.field instanceof X) this.field.|
5438
			relevance += computeRelevanceForResolution();
5595
				if (instanceOfExpression.expression instanceof FieldReference) {
5439
			relevance += computeRelevanceForInterestingProposal();
5596
					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
5597
5448
			if (memberType.isAnnotationType()) {
5598
					if (fieldReference2.receiver instanceof ThisReference &&
5449
				relevance += computeRelevanceForAnnotation();
5599
							fieldReference2.binding == fieldReference1.binding) {
5450
				relevance += computeRelevanceForAnnotationTarget(memberType);
5600
								findFromAnotherReceiver = true;
5451
			} else if (memberType.isClass()) {
5601
					}
5452
				relevance += computeRelevanceForClass();
5602
				}
5453
				relevance += computeRelevanceForException(memberType.sourceName);
5454
			} else if(memberType.isEnum()) {
5455
				relevance += computeRelevanceForEnum();
5456
			} else if(memberType.isInterface()) {
5457
				relevance += computeRelevanceForInterface();
5458
			}
5603
			}
5604
		}
5459
5605
5460
			if (missingElements != null) {
5606
		if (findFromAnotherReceiver) {
5461
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
5607
			TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
5462
			}
5608
			char[] castedReceiver = null;
5463
5609
5464
			this.noProposal = false;
5610
			char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
5465
			createTypeProposal(
5611
			if(this.source != null) {
5466
					memberType,
5612
				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
5613
5478
	protected void findMemberTypes(
5614
				char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
5479
		char[] typeName,
5615
				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
5616
5524
		ReferenceBinding currentType = receiverType;
5617
				castedReceiver =
5525
		if (typeName == null)
5618
					CharOperation.concat(
5526
			return;
5619
						CharOperation.concat(
5620
							'(',
5621
							CharOperation.concat(
5622
								CharOperation.concat('(', castedTypeChars, ')'),
5623
								receiverChars),
5624
							')'),
5625
						dotChars);
5626
			} else {
5627
				castedReceiver =
5628
					CharOperation.concat(
5629
						CharOperation.concat(
5630
							'(',
5631
							CharOperation.concat(
5632
								CharOperation.concat('(', castedTypeChars, ')'),
5633
								CharOperation.concatWith(receiverName, '.')),
5634
							')'),
5635
						DOT);
5636
			}
5527
5637
5528
		if (this.insideQualifiedReference
5638
			if (castedReceiver == null) return;
5529
			|| typeName.length == 0) { // do not search up the hierarchy
5530
5639
5531
			findMemberTypes(
5640
			int oldStartPosition = this.startPosition;
5532
				typeName,
5641
			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
5642
5549
		ReferenceBinding[] interfacesToVisit = null;
5643
			findFieldsAndMethods(
5550
		int nextPosition = 0;
5644
					this.completionToken,
5645
					receiverTypeBinding,
5646
					scope,
5647
					fieldsFound,
5648
					methodsFound,
5649
					invocationSite,
5650
					invocationScope,
5651
					false,
5652
					false,
5653
					null,
5654
					null,
5655
					null,
5656
					false,
5657
					castedReceiver,
5658
					receiverStart,
5659
					receiverEnd);
5551
5660
5552
		do {
5661
			this.startPosition = oldStartPosition;
5553
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
5662
		}
5554
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5663
	}
5555
				if (interfacesToVisit == null) {
5664
	private void findFieldsAndMethodsFromFavorites(
5556
					interfacesToVisit = itsInterfaces;
5665
			char[] token,
5557
					nextPosition = interfacesToVisit.length;
5666
			Scope scope,
5558
				} else {
5667
			InvocationSite invocationSite,
5559
					int itsLength = itsInterfaces.length;
5668
			Scope invocationScope,
5560
					if (nextPosition + itsLength >= interfacesToVisit.length)
5669
			ObjectVector localsFound,
5561
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5670
			ObjectVector fieldsFound,
5562
					nextInterface : for (int a = 0; a < itsLength; a++) {
5671
			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
5672
5571
			findMemberTypes(
5673
		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
5674
5587
			currentType = currentType.superclass();
5675
		ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
5588
		} while (currentType != null);
5589
5676
5590
		if(proposeAllMemberTypes) {
5677
		if (favoriteBindings != null && favoriteBindings.length > 0) {
5591
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
5678
			for (int i = 0; i < favoriteBindings.length; i++) {
5592
			for (int i = 0; i < memberTypes.length; i++) {
5679
				ImportBinding favoriteBinding = favoriteBindings[i];
5593
				if(memberTypes[i] != typeToIgnore) {
5680
				switch (favoriteBinding.resolvedImport.kind()) {
5594
					findSubMemberTypes(
5681
					case Binding.FIELD:
5595
						typeName,
5682
						FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
5596
						memberTypes[i],
5683
						findFieldsFromFavorites(
5597
						scope,
5684
								token,
5598
						typeInvocation,
5685
								new FieldBinding[]{fieldBinding},
5599
						staticOnly,
5686
								scope,
5600
						staticFieldsAndMethodOnly,
5687
								fieldsFound,
5601
						fromStaticImport,
5688
								localsFound,
5602
						typesFound);
5689
								fieldBinding.declaringClass,
5690
								invocationSite,
5691
								invocationScope);
5692
						break;
5693
					case Binding.METHOD:
5694
						MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
5695
						MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
5696
						long range;
5697
						if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
5698
							int start = (int) range, end = (int) (range >> 32);
5699
							int length = end - start + 1;
5700
							System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
5701
						} else {
5702
							methods = Binding.NO_METHODS;
5703
						}
5704
						findLocalMethodsFromFavorites(
5705
								token,
5706
								methods,
5707
								scope,
5708
								methodsFound,
5709
								methodsFoundFromFavorites,
5710
								methodBinding.declaringClass,
5711
								invocationSite,
5712
								invocationScope);
5713
						break;
5714
					case Binding.TYPE:
5715
						ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
5716
						if(favoriteBinding.onDemand) {
5717
							findFieldsFromFavorites(
5718
									token,
5719
									referenceBinding.availableFields(),
5720
									scope,
5721
									fieldsFound,
5722
									localsFound,
5723
									referenceBinding,
5724
									invocationSite,
5725
									invocationScope);
5726
5727
							findLocalMethodsFromFavorites(
5728
									token,
5729
									referenceBinding.availableMethods(),
5730
									scope,
5731
									methodsFound,
5732
									methodsFoundFromFavorites,
5733
									referenceBinding,
5734
									invocationSite,
5735
									invocationScope);
5736
						}
5737
						break;
5603
				}
5738
				}
5604
			}
5739
			}
5605
		}
5740
		}
5606
5741
5607
		if (interfacesToVisit != null) {
5742
		methodsFound.addAll(methodsFoundFromFavorites);
5608
			for (int i = 0; i < nextPosition; i++) {
5743
	}
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
5744
5626
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
5745
	private boolean findFieldsAndMethodsFromMissingFieldType(
5627
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
5746
		char[] token,
5628
					int itsLength = itsInterfaces.length;
5747
		Scope scope,
5629
					if (nextPosition + itsLength >= interfacesToVisit.length)
5748
		InvocationSite invocationSite,
5630
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
5749
		boolean insideTypeAnnotation) {
5631
					nextInterface : for (int a = 0; a < itsLength; a++) {
5750
5632
						ReferenceBinding next = itsInterfaces[a];
5751
		boolean foundSomeFields = false;
5633
						for (int b = 0; b < nextPosition; b++)
5752
5634
							if (next == interfacesToVisit[b]) continue nextInterface;
5753
		boolean staticsOnly = false;
5635
						interfacesToVisit[nextPosition++] = next;
5754
		Scope currentScope = scope;
5755
5756
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5757
5758
			switch (currentScope.kind) {
5759
5760
				case Scope.METHOD_SCOPE :
5761
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5762
					MethodScope methodScope = (MethodScope) currentScope;
5763
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5764
					break;
5765
				case Scope.CLASS_SCOPE :
5766
					ClassScope classScope = (ClassScope) currentScope;
5767
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5768
					if(!insideTypeAnnotation) {
5769
5770
						FieldDeclaration[] fields = classScope.referenceContext.fields;
5771
5772
						int fieldsCount = fields == null ? 0 : fields.length;
5773
						for (int i = 0; i < fieldsCount; i++) {
5774
							FieldDeclaration fieldDeclaration = fields[i];
5775
							if (CharOperation.equals(fieldDeclaration.name, token)) {
5776
								FieldBinding fieldBinding = fieldDeclaration.binding;
5777
								if (fieldBinding == null || fieldBinding.type == null  || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
5778
									foundSomeFields = true;
5779
									findFieldsAndMethodsFromMissingType(
5780
											fieldDeclaration.type,
5781
											currentScope,
5782
											invocationSite,
5783
											scope);
5784
								}
5785
								break done;
5786
							}
5787
						}
5636
					}
5788
					}
5637
				}
5789
					staticsOnly |= enclosingType.isStatic();
5790
					insideTypeAnnotation = false;
5791
					break;
5792
				case Scope.COMPILATION_UNIT_SCOPE :
5793
					break done;
5638
			}
5794
			}
5795
			currentScope = currentScope.parent;
5639
		}
5796
		}
5797
		return foundSomeFields;
5640
	}
5798
	}
5641
5799
5642
	private void findMemberTypesFromMissingType(
5800
	private void findFieldsAndMethodsFromMissingReturnType(
5643
			char[] typeName,
5801
		char[] token,
5644
			final long pos,
5802
		TypeBinding[] arguments,
5645
			final Scope scope)  {
5803
		Scope scope,
5646
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5804
		InvocationSite invocationSite,
5647
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5805
		boolean insideTypeAnnotation) {
5648
			new MissingTypesGuesser.GuessedTypeRequestor() {
5806
5649
				public void accept(
5807
		boolean staticsOnly = false;
5650
						TypeBinding guessedType,
5808
		Scope currentScope = scope;
5651
						Binding[] missingElements,
5809
5652
						int[] missingElementsStarts,
5810
		done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
5653
						int[] missingElementsEnds,
5811
5654
						boolean hasProblems) {
5812
			switch (currentScope.kind) {
5655
					if (guessedType instanceof ReferenceBinding) {
5813
5656
						findMemberTypes(
5814
				case Scope.METHOD_SCOPE :
5657
								CompletionEngine.this.completionToken,
5815
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
5658
								(ReferenceBinding)guessedType,
5816
					MethodScope methodScope = (MethodScope) currentScope;
5659
								scope,
5817
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
5660
								scope.enclosingSourceType(),
5818
					break;
5661
								false,
5819
				case Scope.CLASS_SCOPE :
5662
								false,
5820
					ClassScope classScope = (ClassScope) currentScope;
5663
								new ObjectVector(),
5821
					SourceTypeBinding enclosingType = classScope.referenceContext.binding;
5664
								missingElements,
5822
					if(!insideTypeAnnotation) {
5665
								missingElementsStarts,
5823
5666
								missingElementsEnds,
5824
						AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
5667
								hasProblems);
5825
5826
						int methodsCount = methods == null ? 0 : methods.length;
5827
						for (int i = 0; i < methodsCount; i++) {
5828
							AbstractMethodDeclaration methodDeclaration = methods[i];
5829
							if (methodDeclaration instanceof MethodDeclaration &&
5830
									CharOperation.equals(methodDeclaration.selector, token)) {
5831
								MethodDeclaration method = (MethodDeclaration) methodDeclaration;
5832
								MethodBinding methodBinding = method.binding;
5833
								if (methodBinding == null || methodBinding.returnType == null  || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
5834
									Argument[] parameters = method.arguments;
5835
									int parametersLength = parameters == null ? 0 : parameters.length;
5836
									int argumentsLength = arguments == null ? 0 : arguments.length;
5837
5838
									if (parametersLength == 0) {
5839
										if (argumentsLength == 0) {
5840
											findFieldsAndMethodsFromMissingType(
5841
													method.returnType,
5842
													currentScope,
5843
													invocationSite,
5844
													scope);
5845
											break done;
5846
										}
5847
									} else {
5848
										TypeBinding[] parametersBindings;
5849
										if (methodBinding == null) { // since no binding, extra types from type references
5850
											parametersBindings = new TypeBinding[parametersLength];
5851
											for (int j = 0; j < parametersLength; j++) {
5852
												TypeBinding parameterType = parameters[j].type.resolvedType;
5853
												if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
5854
													parameterType = parameterType.closestMatch();
5855
												}
5856
												parametersBindings[j] = parameterType;
5857
											}
5858
										} else {
5859
											parametersBindings = methodBinding.parameters;
5860
										}
5861
										if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
5862
											findFieldsAndMethodsFromMissingType(
5863
													method.returnType,
5864
													currentScope,
5865
													invocationSite,
5866
													scope);
5867
											break done;
5868
										}
5869
									}
5870
								}
5871
5872
							}
5873
						}
5668
					}
5874
					}
5669
				}
5875
					staticsOnly |= enclosingType.isStatic();
5670
			};
5876
					insideTypeAnnotation = false;
5671
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
5877
					break;
5672
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
5878
				case Scope.COMPILATION_UNIT_SCOPE :
5673
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5879
					break done;
5880
			}
5881
			currentScope = currentScope.parent;
5882
		}
5674
	}
5883
	}
5675
5884
5676
	private void findMemberTypesFromMissingType(
5885
	private void findFieldsAndMethodsFromMissingType(
5677
			TypeReference typeRef,
5886
			TypeReference typeRef,
5678
			final long pos,
5887
			final Scope scope,
5679
			final Scope scope)  {
5888
			final InvocationSite invocationSite,
5889
			final Scope invocationScope) {
5680
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5890
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
5681
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5891
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
5682
			new MissingTypesGuesser.GuessedTypeRequestor() {
5892
			new MissingTypesGuesser.GuessedTypeRequestor() {
Lines 5686-5896 Link Here
5686
						int[] missingElementsStarts,
5896
						int[] missingElementsStarts,
5687
						int[] missingElementsEnds,
5897
						int[] missingElementsEnds,
5688
						boolean hasProblems) {
5898
						boolean hasProblems) {
5689
					if (guessedType instanceof ReferenceBinding) {
5899
					findFieldsAndMethods(
5690
						findMemberTypes(
5900
						CompletionEngine.this.completionToken,
5691
								CompletionEngine.this.completionToken,
5901
						guessedType,
5692
								(ReferenceBinding)guessedType,
5902
						scope,
5693
								scope,
5903
						new ObjectVector(),
5694
								scope.enclosingSourceType(),
5904
						new ObjectVector(),
5695
								false,
5905
						invocationSite,
5696
								false,
5906
						invocationScope,
5697
								new ObjectVector(),
5907
						false,
5698
								missingElements,
5908
						false,
5699
								missingElementsStarts,
5909
						missingElements,
5700
								missingElementsEnds,
5910
						missingElementsStarts,
5701
								hasProblems);
5911
						missingElementsEnds,
5702
					}
5912
						hasProblems,
5913
						null,
5914
						-1,
5915
						-1);
5916
5703
				}
5917
				}
5704
			};
5918
			};
5705
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5919
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
5706
	}
5920
	}
5707
5921
5708
	/*
5922
	private void findFieldsAndMethodsFromStaticImports(
5709
	 * Find javadoc parameter names.
5923
			char[] token,
5710
	 */
5924
			Scope scope,
5711
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
5925
			InvocationSite invocationSite,
5712
5926
			Scope invocationScope,
5713
		if (missingParams == null) return;
5927
			boolean exactMatch,
5714
5928
			boolean insideAnnotationAttribute,
5715
		// Get relevance
5929
			ObjectVector localsFound,
5716
		int relevance = computeBaseRelevance();
5930
			ObjectVector fieldsFound,
5717
		relevance += computeRelevanceForInterestingProposal();
5931
			ObjectVector methodsFound,
5718
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
5932
			boolean proposeField,
5719
		if (!isTypeParam) relevance += R_INTERESTING;
5933
			boolean proposeMethod) {
5720
5934
		// search in static import
5721
		// Propose missing param
5935
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
5722
		int length = missingParams.length;
5936
		for (int i = 0; i < importBindings.length; i++) {
5723
		relevance += length;
5937
			ImportBinding importBinding = importBindings[i];
5724
		for (int i=0; i<length; i++) {
5938
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
5725
			char[] argName = missingParams[i];
5939
				Binding binding = importBinding.resolvedImport;
5726
			if (token == null || CharOperation.prefixEquals(token, argName)) {
5940
				if(binding != null && binding.isValidBinding()) {
5727
5941
					if(importBinding.onDemand) {
5728
				this.noProposal = false;
5942
						if((binding.kind() & Binding.TYPE) != 0) {
5729
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
5943
							if(proposeField) {
5730
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
5944
								findFields(
5731
					proposal.setName(argName);
5945
									token,
5732
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
5946
									(ReferenceBinding)binding,
5733
					proposal.setCompletion(completion);
5947
									scope,
5734
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
5948
									fieldsFound,
5735
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
5949
									localsFound,
5736
					proposal.setRelevance(--relevance);
5950
									true,
5737
					this.requestor.accept(proposal);
5951
									invocationSite,
5738
					if (DEBUG) {
5952
									invocationScope,
5739
						this.printDebug(proposal);
5953
									true,
5740
					}
5954
									false,
5955
									null,
5956
									null,
5957
									null,
5958
									false,
5959
									null,
5960
									-1,
5961
									-1);
5962
							}
5963
							if(proposeMethod && !insideAnnotationAttribute) {
5964
								findMethods(
5965
									token,
5966
									null,
5967
									null,
5968
									(ReferenceBinding)binding,
5969
									scope,
5970
									methodsFound,
5971
									true,
5972
									exactMatch,
5973
									invocationSite,
5974
									invocationScope,
5975
									true,
5976
									false,
5977
									false,
5978
									null,
5979
									null,
5980
									null,
5981
									false,
5982
									null,
5983
									-1,
5984
									-1);
5985
							}
5986
						}
5987
					} else {
5988
						if ((binding.kind() & Binding.FIELD) != 0) {
5989
							if(proposeField) {
5990
									findFields(
5991
											token,
5992
											new FieldBinding[]{(FieldBinding)binding},
5993
											scope,
5994
											fieldsFound,
5995
											localsFound,
5996
											true,
5997
											((FieldBinding)binding).declaringClass,
5998
											invocationSite,
5999
											invocationScope,
6000
											true,
6001
											false,
6002
											null,
6003
											null,
6004
											null,
6005
											false,
6006
											null,
6007
											-1,
6008
											-1);
6009
							}
6010
						} else if ((binding.kind() & Binding.METHOD) != 0) {
6011
							if(proposeMethod && !insideAnnotationAttribute) {
6012
								MethodBinding methodBinding = (MethodBinding)binding;
6013
								if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
6014
										!exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
6015
6016
									findLocalMethodsFromStaticImports(
6017
											methodBinding.selector,
6018
											methodBinding.declaringClass.methods(),
6019
											scope,
6020
											exactMatch,
6021
											methodsFound,
6022
											methodBinding.declaringClass,
6023
											invocationSite);
6024
								}
6025
							}
6026
						}
6027
					}
5741
				}
6028
				}
5742
			}
6029
			}
5743
		}
6030
		}
5744
	}
6031
	}
5745
6032
5746
	private void findSubMemberTypes(
6033
	private void findFieldsFromFavorites(
5747
		char[] typeName,
6034
			char[] fieldName,
5748
		ReferenceBinding receiverType,
6035
			FieldBinding[] fields,
5749
		Scope scope,
6036
			Scope scope,
5750
		SourceTypeBinding typeInvocation,
6037
			ObjectVector fieldsFound,
5751
		boolean staticOnly,
6038
			ObjectVector localsFound,
5752
		boolean staticFieldsAndMethodOnly,
6039
			ReferenceBinding receiverType,
5753
		boolean fromStaticImport,
6040
			InvocationSite invocationSite,
5754
		ObjectVector typesFound) {
6041
			Scope invocationScope) {
5755
6042
5756
		ReferenceBinding currentType = receiverType;
6043
		char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
5757
		if (typeName == null || typeName.length == 0)
5758
			return;
5759
6044
5760
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
6045
		int fieldLength = fieldName.length;
6046
		next : for (int f = fields.length; --f >= 0;) {
6047
			FieldBinding field = fields[f];
5761
6048
5762
		findMemberTypes(
6049
			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
6050
5778
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
6051
			// only static fields must be proposed
5779
		next : for (int i = 0; i < memberTypes.length; i++) {
6052
			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
6053
5799
	private void findInterfacesMethods(
6054
			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
6055
5823
		if (selector == null)
6056
			if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
5824
			return;
6057
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))	continue next;
5825
6058
5826
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6059
			if (this.options.checkDeprecation &&
5827
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6060
					field.isViewedAsDeprecated() &&
5828
			int nextPosition = interfacesToVisit.length;
6061
					!scope.isDefinedInSameUnit(field.declaringClass))
6062
				continue next;
5829
6063
5830
			for (int i = 0; i < nextPosition; i++) {
6064
			if (this.options.checkVisibility
5831
				ReferenceBinding currentType = interfacesToVisit[i];
6065
				&& !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
6066
5868
				itsInterfaces = currentType.superInterfaces();
6067
			for (int i = fieldsFound.size; --i >= 0;) {
5869
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6068
				Object[] other = (Object[])fieldsFound.elementAt(i);
5870
					int itsLength = itsInterfaces.length;
6069
				FieldBinding otherField = (FieldBinding) other[0];
5871
					if (nextPosition + itsLength >= interfacesToVisit.length)
6070
5872
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6071
				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
			}
6072
			}
5881
		}
5882
	}
5883
6073
5884
	private void findImplicitMessageSends(
6074
			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
6075
5892
		if (token == null)
6076
			int relevance = computeBaseRelevance();
5893
			return;
6077
			relevance += computeRelevanceForResolution();
6078
			relevance += computeRelevanceForInterestingProposal(field);
6079
			if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6080
			relevance += computeRelevanceForExpectingType(field.type);
6081
			relevance += computeRelevanceForEnumConstant(field.type);
6082
			relevance += computeRelevanceForStatic(true, true);
6083
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6084
6085
			CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6086
			int importStart = cu.types[0].declarationSourceStart;
6087
			int importEnd = importStart;
6088
6089
			this.noProposal = false;
6090
6091
			if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
6092
					!this.options.suggestStaticImport) {
6093
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
6094
					char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
6095
6096
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6097
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6098
					proposal.setSignature(getSignature(field.type));
6099
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6100
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6101
					proposal.setPackageName(field.type.qualifiedPackageName());
6102
					proposal.setTypeName(field.type.qualifiedSourceName());
6103
					proposal.setName(field.name);
6104
					proposal.setCompletion(completion);
6105
					proposal.setFlags(field.modifiers);
6106
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6107
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6108
					proposal.setRelevance(relevance);
6109
6110
					char[] typeImportCompletion = createImportCharArray(typeName, false, false);
6111
6112
					InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
6113
					typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
6114
					typeImportProposal.completionEngine = this;
6115
					char[] packageName = receiverType.qualifiedPackageName();
6116
					typeImportProposal.setDeclarationSignature(packageName);
6117
					typeImportProposal.setSignature(getSignature(receiverType));
6118
					typeImportProposal.setPackageName(packageName);
6119
					typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
6120
					typeImportProposal.setCompletion(typeImportCompletion);
6121
					typeImportProposal.setFlags(receiverType.modifiers);
6122
					typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
6123
					typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6124
					typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6125
					typeImportProposal.setRelevance(relevance);
6126
6127
					proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
6128
6129
					this.requestor.accept(proposal);
6130
					if(DEBUG) {
6131
						this.printDebug(proposal);
6132
					}
6133
				}
6134
			} else {
6135
				if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
6136
					char[] completion = field.name;
6137
6138
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6139
					proposal.setDeclarationSignature(getSignature(field.declaringClass));
6140
					proposal.setSignature(getSignature(field.type));
6141
					proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6142
					proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6143
					proposal.setPackageName(field.type.qualifiedPackageName());
6144
					proposal.setTypeName(field.type.qualifiedSourceName());
6145
					proposal.setName(field.name);
6146
					proposal.setCompletion(completion);
6147
					proposal.setFlags(field.modifiers);
6148
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6149
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6150
					proposal.setRelevance(relevance);
6151
6152
					char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
6153
6154
					InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
6155
					fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
6156
					fieldImportProposal.setSignature(getSignature(field.type));
6157
					fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6158
					fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6159
					fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
6160
					fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
6161
					fieldImportProposal.setName(field.name);
6162
					fieldImportProposal.setCompletion(fieldImportCompletion);
6163
					fieldImportProposal.setFlags(field.modifiers);
6164
					fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
6165
					fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
6166
					fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
6167
					fieldImportProposal.setRelevance(relevance);
6168
6169
					proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
6170
6171
					this.requestor.accept(proposal);
6172
					if(DEBUG) {
6173
						this.printDebug(proposal);
6174
					}
6175
				}
6176
			}
6177
		}
6178
	}
6179
	private void findImplicitMessageSends(
6180
		char[] token,
6181
		TypeBinding[] argTypes,
6182
		Scope scope,
6183
		InvocationSite invocationSite,
6184
		Scope invocationScope,
6185
		ObjectVector methodsFound) {
6186
6187
		if (token == null)
6188
			return;
5894
6189
5895
		boolean staticsOnly = false;
6190
		boolean staticsOnly = false;
5896
		// need to know if we're in a static context (or inside a constructor)
6191
		// need to know if we're in a static context (or inside a constructor)
Lines 5917-5923 Link Here
5917
						methodsFound,
6212
						methodsFound,
5918
						staticsOnly,
6213
						staticsOnly,
5919
						true,
6214
						true,
5920
						false,
5921
						invocationSite,
6215
						invocationSite,
5922
						invocationScope,
6216
						invocationScope,
5923
						true,
6217
						true,
Lines 5939-6075 Link Here
5939
			scope = scope.parent;
6233
			scope = scope.parent;
5940
		}
6234
		}
5941
	}
6235
	}
6236
	private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
6237
		char[][] tokens = importReference.tokens;
5942
6238
5943
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6239
		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
6240
5967
		ObjectVector newMethodsFound =  new ObjectVector();
6241
		if (importName.length == 0)
5968
		// Inherited methods which are hidden by subclasses are filtered out
6242
			return;
5969
		// No visibility checks can be performed without the scope & invocationSite
5970
6243
5971
		int methodLength = methodName.length;
6244
		char[] lastToken = tokens[tokens.length - 1];
5972
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
6245
		if(lastToken != null && lastToken.length == 0)
5973
		int minArgLength = argTypes == null ? 0 : argTypes.length;
6246
			importName = CharOperation.concat(importName, new char[]{'.'});
5974
6247
5975
		next : for (int f = methods.length; --f >= 0;) {
6248
		this.resolvingImports = true;
5976
			MethodBinding method = methods[f];
6249
		this.resolvingStaticImports = importReference.isStatic();
5977
6250
5978
			if (method.isSynthetic()) continue next;
6251
		this.completionToken =  lastToken;
6252
		this.qualifiedCompletionToken = importName;
5979
6253
5980
			if (method.isDefaultAbstract())	continue next;
6254
		// want to replace the existing .*;
6255
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
6256
			int oldStart = this.startPosition;
6257
			int oldEnd = this.endPosition;
6258
			setSourceRange(
6259
				importReference.sourceStart,
6260
				importReference.declarationSourceEnd);
6261
			this.nameEnvironment.findPackages(importName, this);
6262
			setSourceRange(
6263
				oldStart,
6264
				oldEnd - 1,
6265
				false);
6266
		}
6267
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6268
			this.foundTypesCount = 0;
6269
			this.nameEnvironment.findTypes(
6270
					importName,
6271
					findMembers,
6272
					this.options.camelCaseMatch,
6273
					IJavaSearchConstants.TYPE,
6274
					this);
6275
			acceptTypes(null);
6276
		}
6277
	}
5981
6278
5982
			if (method.isConstructor()) continue next;
6279
	private void findImportsOfMemberTypes(char[] typeName,	ReferenceBinding ref, boolean onlyStatic) {
6280
		ReferenceBinding[] memberTypes = ref.memberTypes();
5983
6281
5984
			if (this.options.checkDeprecation &&
6282
		int typeLength = typeName.length;
5985
					method.isViewedAsDeprecated() &&
6283
		next : for (int m = memberTypes.length; --m >= 0;) {
5986
					!scope.isDefinedInSameUnit(method.declaringClass))
6284
			ReferenceBinding memberType = memberTypes[m];
6285
			//		if (!wantClasses && memberType.isClass()) continue next;
6286
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
6287
6288
			if (onlyStatic && !memberType.isStatic())
5987
				continue next;
6289
				continue next;
5988
6290
5989
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
6291
			if (typeLength > memberType.sourceName.length)
5990
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
6292
				continue next;
5991
6293
5992
			if (onlyStaticMethods && !method.isStatic()) continue next;
6294
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
6295
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
6296
				continue next;
5993
6297
5994
			if (this.options.checkVisibility
6298
			if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
5995
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
5996
6299
5997
			if(superCall && method.isAbstract()) {
6300
			if (this.options.checkVisibility
5998
				methodsFound.add(new Object[]{method, receiverType});
6301
				&& !memberType.canBeSeenBy(this.unitScope.fPackage))
5999
				continue next;
6302
				continue next;
6000
			}
6001
6303
6002
			if (exactMatch) {
6304
			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
6305
6014
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
6306
			int relevance = computeBaseRelevance();
6015
				continue next;
6307
			relevance += computeRelevanceForResolution();
6308
			relevance += computeRelevanceForInterestingProposal();
6309
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
6310
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6016
6311
6017
			if (minTypeArgLength != 0) {
6312
			if (memberType.isClass()) {
6018
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
6313
				relevance += computeRelevanceForClass();
6314
			} else if(memberType.isEnum()) {
6315
				relevance += computeRelevanceForEnum();
6316
			} else if (memberType.isInterface()) {
6317
				relevance += computeRelevanceForInterface();
6318
			}
6319
			this.noProposal = false;
6320
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
6321
				createTypeProposal(
6322
						memberType,
6323
						memberType.qualifiedSourceName(),
6324
						IAccessRule.K_ACCESSIBLE,
6325
						completionName,
6326
						relevance,
6327
						null,
6328
						null,
6329
						null,
6330
						false);
6019
			}
6331
			}
6332
		}
6333
	}
6020
6334
6021
			if (minArgLength > method.parameters.length)
6335
	private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
6336
		FieldBinding[] fields = ref.availableFields();
6337
6338
		int fieldLength = fieldName.length;
6339
		next : for (int m = fields.length; --m >= 0;) {
6340
			FieldBinding field = fields[m];
6341
6342
			if (fieldLength > field.name.length)
6022
				continue next;
6343
				continue next;
6023
6344
6024
			for (int a = minArgLength; --a >= 0;){
6345
			if (field.isSynthetic())
6025
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
6346
				continue next;
6026
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
6027
						continue next;
6028
					}
6029
				}
6030
			}
6031
6347
6032
			boolean prefixRequired = false;
6348
			if (!field.isStatic())
6349
				continue next;
6033
6350
6034
			for (int i = methodsFound.size; --i >= 0;) {
6351
			if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
6035
				Object[] other = (Object[]) methodsFound.elementAt(i);
6352
				&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
6036
				MethodBinding otherMethod = (MethodBinding) other[0];
6353
				continue next;
6037
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6038
				if (method == otherMethod && receiverType == otherReceiverType)
6039
					continue next;
6040
6354
6041
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6355
			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
6356
6052
							if(!superCall) {
6357
			if (this.options.checkVisibility
6053
								if(!canBePrefixed) continue next;
6358
				&& !field.canBeSeenBy(this.unitScope.fPackage))
6359
				continue next;
6054
6360
6055
								prefixRequired = true;
6361
			char[] completionName = CharOperation.concat(field.name, SEMICOLON);
6056
							}
6057
						}
6058
					}
6059
				}
6060
			}
6061
6362
6062
			newMethodsFound.add(new Object[]{method, receiverType});
6363
			int relevance = computeBaseRelevance();
6364
			relevance += computeRelevanceForResolution();
6365
			relevance += computeRelevanceForInterestingProposal();
6366
			relevance += computeRelevanceForCaseMatching(fieldName, field.name);
6367
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6063
6368
6064
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6369
			this.noProposal = false;
6065
			if (method.declaringClass != superTypeWithSameErasure) {
6370
			if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
6066
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6371
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
6067
				for (int i = 0; i < otherMethods.length; i++) {
6372
				proposal.setDeclarationSignature(getSignature(field.declaringClass));
6068
					if(otherMethods[i].original() == method.original()) {
6373
				proposal.setSignature(getSignature(field.type));
6069
						method = otherMethods[i];
6374
				proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
6070
					}
6375
				proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
6376
				proposal.setPackageName(field.type.qualifiedPackageName());
6377
				proposal.setTypeName(field.type.qualifiedSourceName());
6378
				proposal.setName(field.name);
6379
				proposal.setCompletion(completionName);
6380
				proposal.setFlags(field.modifiers);
6381
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6382
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6383
				proposal.setRelevance(relevance);
6384
				this.requestor.accept(proposal);
6385
				if(DEBUG) {
6386
					this.printDebug(proposal);
6071
				}
6387
				}
6072
			}
6388
			}
6389
		}
6390
	}
6391
6392
	private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
6393
		MethodBinding[] methods = ref.availableMethods();
6394
6395
		int methodLength = methodName.length;
6396
		next : for (int m = methods.length; --m >= 0;) {
6397
			MethodBinding method = methods[m];
6398
6399
			if (method.isSynthetic()) continue next;
6400
6401
			if (method.isDefaultAbstract())	continue next;
6402
6403
			if (method.isConstructor()) continue next;
6404
6405
			if (!method.isStatic()) continue next;
6406
6407
			if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
6408
6409
			if (this.options.checkVisibility
6410
				&& !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
6411
6412
			if (methodLength > method.selector.length)
6413
				continue next;
6414
6415
			if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
6416
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6417
				continue next;
6073
6418
6074
			int length = method.parameters.length;
6419
			int length = method.parameters.length;
6075
			char[][] parameterPackageNames = new char[length][];
6420
			char[][] parameterPackageNames = new char[length][];
Lines 6082-6728 Link Here
6082
			}
6427
			}
6083
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6428
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6084
6429
6085
			char[] completion = CharOperation.NO_CHAR;
6430
			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
6431
6167
			int relevance = computeBaseRelevance();
6432
			int relevance = computeBaseRelevance();
6168
			relevance += computeRelevanceForResolution();
6433
			relevance += computeRelevanceForResolution();
6169
			relevance += computeRelevanceForInterestingProposal();
6434
			relevance += computeRelevanceForInterestingProposal();
6170
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6435
			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);
6436
			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
6437
6183
			this.noProposal = false;
6438
			this.noProposal = false;
6184
6439
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
6185
			if (castedReceiver == null) {
6440
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
6186
				// Standard proposal
6441
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6187
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
6442
				proposal.setSignature(getSignature(method));
6188
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6443
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6189
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
6444
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6190
					proposal.setSignature(getSignature(method));
6445
				proposal.setParameterPackageNames(parameterPackageNames);
6191
					MethodBinding original = method.original();
6446
				proposal.setParameterTypeNames(parameterTypeNames);
6192
					if(original != method) {
6447
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6193
						proposal.setOriginalSignature(getSignature(original));
6448
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6194
					}
6449
				proposal.setName(method.selector);
6195
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6450
				proposal.setCompletion(completionName);
6196
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6451
				proposal.setFlags(method.modifiers);
6197
					proposal.setParameterPackageNames(parameterPackageNames);
6452
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6198
					proposal.setParameterTypeNames(parameterTypeNames);
6453
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6199
					proposal.setPackageName(method.returnType.qualifiedPackageName());
6454
				proposal.setRelevance(relevance);
6200
					proposal.setTypeName(method.returnType.qualifiedSourceName());
6455
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
6201
					proposal.setName(method.selector);
6456
				this.requestor.accept(proposal);
6202
					if (missingElements != null) {
6457
				if(DEBUG) {
6203
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
6458
					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
				}
6459
				}
6296
			}
6460
			}
6297
			this.startPosition = previousStartPosition;
6298
			this.tokenStart = previousTokenStart;
6299
		}
6461
		}
6300
6301
		methodsFound.addAll(newMethodsFound);
6302
	}
6462
	}
6463
	
6464
	private void findInterfacesMethodDeclarations(
6465
		char[] selector,
6466
		ReferenceBinding receiverType,
6467
		ReferenceBinding[] itsInterfaces,
6468
		Scope scope,
6469
		ObjectVector methodsFound,
6470
		Binding[] missingElements,
6471
		int[] missingElementssStarts,
6472
		int[] missingElementsEnds,
6473
		boolean missingElementsHaveProblems) {
6303
6474
6304
	private void findLocalMethodsFromFavorites(
6475
		if (selector == null)
6305
			char[] methodName,
6476
			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
6477
6337
				if (methodLength > method.selector.length) continue next;
6478
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6479
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6480
			int nextPosition = interfacesToVisit.length;
6338
6481
6339
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6482
			for (int i = 0; i < nextPosition; i++) {
6340
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6483
				ReferenceBinding currentType = interfacesToVisit[i];
6341
					continue next;
6484
				MethodBinding[] methods = currentType.availableMethods();
6485
				if(methods != null) {
6486
					findLocalMethodDeclarations(
6487
						selector,
6488
						methods,
6489
						scope,
6490
						methodsFound,
6491
						false,
6492
						receiverType);
6342
				}
6493
				}
6343
6494
6344
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
6495
				itsInterfaces = currentType.superInterfaces();
6345
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
6496
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6346
					MethodBinding otherMethod = (MethodBinding) other[0];
6497
					int itsLength = itsInterfaces.length;
6347
6498
					if (nextPosition + itsLength >= interfacesToVisit.length)
6348
					if (method == otherMethod) continue next;
6499
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6349
6500
					nextInterface : for (int a = 0; a < itsLength; a++) {
6350
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6501
						ReferenceBinding next = itsInterfaces[a];
6351
						if (otherMethod.declaringClass == method.declaringClass &&
6502
						for (int b = 0; b < nextPosition; b++)
6352
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6503
							if (next == interfacesToVisit[b]) continue nextInterface;
6353
							continue next;
6504
						interfacesToVisit[nextPosition++] = next;
6354
						}
6355
					}
6505
					}
6356
				}
6506
				}
6507
			}
6508
		}
6509
	}
6510
	
6511
	private void findInterfacesMethods(
6512
		char[] selector,
6513
		TypeBinding[] typeArgTypes,
6514
		TypeBinding[] argTypes,
6515
		ReferenceBinding receiverType,
6516
		ReferenceBinding[] itsInterfaces,
6517
		Scope scope,
6518
		ObjectVector methodsFound,
6519
		boolean onlyStaticMethods,
6520
		boolean exactMatch,
6521
		InvocationSite invocationSite,
6522
		Scope invocationScope,
6523
		boolean implicitCall,
6524
		boolean superCall,
6525
		boolean canBePrefixed,
6526
		Binding[] missingElements,
6527
		int[] missingElementssStarts,
6528
		int[] missingElementsEnds,
6529
		boolean missingElementsHaveProblems,
6530
		char[] castedReceiver,
6531
		int receiverStart,
6532
		int receiverEnd) {
6357
6533
6358
				for (int i = methodsFound.size; --i >= 0;) {
6534
		if (selector == null)
6359
					Object[] other = (Object[]) methodsFound.elementAt(i);
6535
			return;
6360
					MethodBinding otherMethod = (MethodBinding) other[0];
6361
6536
6362
					if (method == otherMethod) continue next;
6537
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
6538
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
6539
			int nextPosition = interfacesToVisit.length;
6363
6540
6364
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6541
			for (int i = 0; i < nextPosition; i++) {
6365
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6542
				ReferenceBinding currentType = interfacesToVisit[i];
6366
							continue next;
6543
				MethodBinding[] methods = currentType.availableMethods();
6367
						}
6544
				if(methods != null) {
6368
					}
6545
					findLocalMethods(
6546
						selector,
6547
						typeArgTypes,
6548
						argTypes,
6549
						methods,
6550
						scope,
6551
						methodsFound,
6552
						onlyStaticMethods,
6553
						exactMatch,
6554
						receiverType,
6555
						invocationSite,
6556
						invocationScope,
6557
						implicitCall,
6558
						superCall,
6559
						canBePrefixed,
6560
						missingElements,
6561
						missingElementssStarts,
6562
						missingElementsEnds,
6563
						missingElementsHaveProblems,
6564
						castedReceiver,
6565
						receiverStart,
6566
						receiverEnd);
6369
				}
6567
				}
6370
6568
6371
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
6569
				itsInterfaces = currentType.superInterfaces();
6372
					this.options.suggestStaticImport;
6570
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
6373
6571
					int itsLength = itsInterfaces.length;
6374
				boolean isAlreadyImported = false;
6572
					if (nextPosition + itsLength >= interfacesToVisit.length)
6375
				if (!proposeStaticImport) {
6573
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
6376
					if(!this.importCachesInitialized) {
6574
					nextInterface : for (int a = 0; a < itsLength; a++) {
6377
						initializeImportCaches();
6575
						ReferenceBinding next = itsInterfaces[a];
6378
					}
6576
						for (int b = 0; b < nextPosition; b++)
6379
					for (int j = 0; j < this.importCacheCount; j++) {
6577
							if (next == interfacesToVisit[b]) continue nextInterface;
6380
						char[][] importName = this.importsCache[j];
6578
						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
					}
6579
					}
6389
				}
6580
				}
6390
6581
			}
6391
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
6582
		}
6392
6583
	}
6393
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
6584
	/*
6394
				if (method.declaringClass != superTypeWithSameErasure) {
6585
	 * Find javadoc block tags for a given completion javadoc tag node
6395
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
6586
	 */
6396
					for (int i = 0; i < otherMethods.length; i++) {
6587
	private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
6397
						if(otherMethods[i].original() == method.original()) {
6588
		char[][] possibleTags = javadocTag.getPossibleBlockTags();
6398
							method = otherMethods[i];
6589
		if (possibleTags == null) return;
6399
						}
6590
		int length = possibleTags.length;
6400
					}
6591
		for (int i=0; i<length; i++) {
6592
			int relevance = computeBaseRelevance();
6593
			relevance += computeRelevanceForInterestingProposal();
6594
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6595
6596
			this.noProposal = false;
6597
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_BLOCK_TAG)) {
6598
				char[] possibleTag = possibleTags[i];
6599
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_BLOCK_TAG, this.actualCompletionPosition);
6600
				proposal.setName(possibleTag);
6601
				int tagLength = possibleTag.length;
6602
				char[] completion = new char[1+tagLength];
6603
				completion[0] = '@';
6604
				System.arraycopy(possibleTag, 0, completion, 1, tagLength);
6605
				proposal.setCompletion(completion);
6606
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6607
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6608
				proposal.setRelevance(relevance);
6609
				this.requestor.accept(proposal);
6610
				if (DEBUG) {
6611
					this.printDebug(proposal);
6401
				}
6612
				}
6613
			}
6614
		}
6615
	}
6402
6616
6403
				int length = method.parameters.length;
6617
	/*
6404
				char[][] parameterPackageNames = new char[length][];
6618
	 * Find javadoc inline tags for a given completion javadoc tag node
6405
				char[][] parameterTypeNames = new char[length][];
6619
	 */
6620
	private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
6621
		char[][] possibleTags = javadocTag.getPossibleInlineTags();
6622
		if (possibleTags == null) return;
6623
		int length = possibleTags.length;
6624
		for (int i=0; i<length; i++) {
6625
			int relevance = computeBaseRelevance();
6626
			relevance += computeRelevanceForInterestingProposal();
6627
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6406
6628
6407
				for (int i = 0; i < length; i++) {
6629
			this.noProposal = false;
6408
					TypeBinding type = method.original().parameters[i];
6630
			if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_INLINE_TAG)) {
6409
					parameterPackageNames[i] = type.qualifiedPackageName();
6631
				char[] possibleTag = possibleTags[i];
6410
					parameterTypeNames[i] = type.qualifiedSourceName();
6632
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_INLINE_TAG, this.actualCompletionPosition);
6633
				proposal.setName(possibleTag);
6634
				int tagLength = possibleTag.length;
6635
//				boolean inlineTagStarted = javadocTag.completeInlineTagStarted();
6636
				char[] completion = new char[2+tagLength+1];
6637
				completion[0] = '{';
6638
				completion[1] = '@';
6639
				System.arraycopy(possibleTag, 0, completion, 2, tagLength);
6640
				// do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
6641
				//completion[tagLength+2] = ' ';
6642
				completion[tagLength+2] = '}';
6643
				proposal.setCompletion(completion);
6644
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6645
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6646
				proposal.setRelevance(relevance);
6647
				this.requestor.accept(proposal);
6648
				if (DEBUG) {
6649
					this.printDebug(proposal);
6411
				}
6650
				}
6412
				char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6651
			}
6413
6652
		}
6414
				char[] completion = CharOperation.NO_CHAR;
6653
	}
6415
6654
6416
				int previousStartPosition = this.startPosition;
6655
	/*
6417
				int previousTokenStart = this.tokenStart;
6656
	 * Find javadoc parameter names.
6657
	 */
6658
	private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
6418
6659
6419
				if (this.source != null
6660
		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
6661
6427
				int relevance = computeBaseRelevance();
6662
		// Get relevance
6428
				relevance += computeRelevanceForResolution();
6663
		int relevance = computeBaseRelevance();
6429
				relevance += computeRelevanceForInterestingProposal();
6664
		relevance += computeRelevanceForInterestingProposal();
6430
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6665
		relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
6431
				relevance += computeRelevanceForExpectingType(method.returnType);
6666
		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
6667
6437
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
6668
		// Propose missing param
6438
				int importStart = cu.types[0].declarationSourceStart;
6669
		int length = missingParams.length;
6439
				int importEnd = importStart;
6670
		relevance += length;
6671
		for (int i=0; i<length; i++) {
6672
			char[] argName = missingParams[i];
6673
			if (token == null || CharOperation.prefixEquals(token, argName)) {
6440
6674
6441
				this.noProposal = false;
6675
				this.noProposal = false;
6676
				if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
6677
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_PARAM_REF, this.actualCompletionPosition);
6678
					proposal.setName(argName);
6679
					char[] completion = isTypeParam ? CharOperation.concat('<', argName, '>') : argName;
6680
					proposal.setCompletion(completion);
6681
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6682
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6683
					proposal.setRelevance(--relevance);
6684
					this.requestor.accept(proposal);
6685
					if (DEBUG) {
6686
						this.printDebug(proposal);
6687
					}
6688
				}
6689
			}
6690
		}
6691
	}
6442
6692
6443
				if (!proposeStaticImport) {
6693
	// what about onDemand types? Ignore them since it does not happen!
6444
					if (isAlreadyImported) {
6694
	// import p1.p2.A.*;
6445
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
6695
	private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
6446
							completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6696
		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
6697
6469
							this.requestor.accept(proposal);
6698
		int length = keyword.length;
6470
							if(DEBUG) {
6699
		if (canCompleteEmptyToken || length > 0)
6471
								this.printDebug(proposal);
6700
			for (int i = 0; i < choices.length; i++)
6472
							}
6701
				if (length <= choices[i].length
6473
						}
6702
					&& CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
6474
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
6703
				)){
6475
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
6704
					int relevance = computeBaseRelevance();
6705
					relevance += computeRelevanceForResolution();
6706
					relevance += computeRelevanceForInterestingProposal();
6707
					relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
6708
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
6709
					if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
6476
6710
6477
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6711
					if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
6478
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6712
						relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
6479
						proposal.setSignature(getSignature(method));
6713
						relevance += computeRelevanceForQualification(false);
6480
						MethodBinding original = method.original();
6714
					}
6481
						if(original != method) {
6715
					this.noProposal = false;
6482
							proposal.setOriginalSignature(getSignature(original));
6716
					if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
6483
						}
6717
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
6484
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6718
						proposal.setName(choices[i]);
6485
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6719
						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);
6720
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6494
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6721
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6495
						proposal.setRelevance(relevance);
6722
						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);
6723
						this.requestor.accept(proposal);
6518
						if(DEBUG) {
6724
						if(DEBUG) {
6519
							this.printDebug(proposal);
6725
							this.printDebug(proposal);
6520
						}
6726
						}
6521
					}
6727
					}
6522
				} else {
6728
				}
6523
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
6729
	}
6524
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6730
	private void findKeywordsForMember(char[] token, int modifiers) {
6525
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
6731
		char[][] keywords = new char[Keywords.COUNT][];
6526
						proposal.setSignature(getSignature(method));
6732
		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
6733
6568
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
6734
		// visibility
6735
		if((modifiers & ClassFileConstants.AccPrivate) == 0
6736
			&& (modifiers & ClassFileConstants.AccProtected) == 0
6737
			&& (modifiers & ClassFileConstants.AccPublic) == 0) {
6738
			keywords[count++] = Keywords.PROTECTED;
6739
			keywords[count++] = Keywords.PUBLIC;
6740
			if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6741
				keywords[count++] = Keywords.PRIVATE;
6742
			}
6743
		}
6569
6744
6570
						this.requestor.accept(proposal);
6745
		if((modifiers & ClassFileConstants.AccAbstract) == 0) {
6571
						if(DEBUG) {
6746
			// abtract
6572
							this.printDebug(proposal);
6747
			if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
6573
						}
6748
				keywords[count++] = Keywords.ABSTRACT;
6574
					}
6749
			}
6750
6751
			// final
6752
			if((modifiers & ClassFileConstants.AccFinal) == 0) {
6753
				keywords[count++] = Keywords.FINAL;
6754
			}
6755
6756
			// static
6757
			if((modifiers & ClassFileConstants.AccStatic) == 0) {
6758
				keywords[count++] = Keywords.STATIC;
6759
			}
6760
6761
			boolean canBeField = true;
6762
			boolean canBeMethod = true;
6763
			boolean canBeType = true;
6764
			if((modifiers & ClassFileConstants.AccNative) != 0
6765
				|| (modifiers & ClassFileConstants.AccStrictfp) != 0
6766
				|| (modifiers & ClassFileConstants.AccSynchronized) != 0) {
6767
				canBeField = false;
6768
				canBeType = false;
6769
			}
6770
6771
			if((modifiers & ClassFileConstants.AccTransient) != 0
6772
				|| (modifiers & ClassFileConstants.AccVolatile) != 0) {
6773
				canBeMethod = false;
6774
				canBeType = false;
6775
			}
6776
6777
			if(canBeField) {
6778
				// transient
6779
				if((modifiers & ClassFileConstants.AccTransient) == 0) {
6780
					keywords[count++] = Keywords.TRANSIENT;
6575
				}
6781
				}
6576
6782
6577
				this.startPosition = previousStartPosition;
6783
				// volatile
6578
				this.tokenStart = previousTokenStart;
6784
				if((modifiers & ClassFileConstants.AccVolatile) == 0) {
6785
					keywords[count++] = Keywords.VOLATILE;
6786
				}
6579
			}
6787
			}
6580
		}
6581
6788
6582
	private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
6789
			if(canBeMethod) {
6583
		InternalCompletionProposal proposal = null;
6790
				// native
6584
		if (binding instanceof ReferenceBinding) {
6791
				if((modifiers & ClassFileConstants.AccNative) == 0) {
6585
			ReferenceBinding typeBinding = (ReferenceBinding) binding;
6792
					keywords[count++] = Keywords.NATIVE;
6793
				}
6586
6794
6587
			char[] packageName = typeBinding.qualifiedPackageName();
6795
				// strictfp
6588
			char[] typeName = typeBinding.qualifiedSourceName();
6796
				if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
6589
			char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
6797
					keywords[count++] = Keywords.STRICTFP;
6798
				}
6590
6799
6591
			proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
6800
				// synchronized
6592
			proposal.nameLookup = this.nameEnvironment.nameLookup;
6801
				if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
6593
			proposal.completionEngine = this;
6802
					keywords[count++] = Keywords.SYNCHRONIZED;
6594
			proposal.setDeclarationSignature(packageName);
6803
				}
6595
			proposal.setSignature(getRequiredTypeSignature(typeBinding));
6804
			}
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
6805
6606
			char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
6806
			if(canBeType) {
6807
				keywords[count++] = Keywords.CLASS;
6808
				keywords[count++] = Keywords.INTERFACE;
6607
6809
6608
			proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
6810
				if((modifiers & ClassFileConstants.AccFinal) == 0) {
6609
			proposal.setDeclarationSignature(packageName);
6811
					keywords[count++] = Keywords.ENUM;
6610
			proposal.setPackageName(packageName);
6812
				}
6611
			proposal.setCompletion(packageName);
6813
			}
6612
			proposal.setReplaceRange(start - this.offset, end - this.offset);
6814
		} else {
6613
			proposal.setTokenRange(start - this.offset, end - this.offset);
6815
			// class
6614
			proposal.setRelevance(relevance);
6816
			keywords[count++] = Keywords.CLASS;
6817
			keywords[count++] = Keywords.INTERFACE;
6615
		}
6818
		}
6616
		return proposal;
6819
		System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
6820
6821
		findKeywords(token, keywords, false, false);
6617
	}
6822
	}
6823
	private void findLabels(char[] label, char[][] choices) {
6824
		if(choices == null || choices.length == 0) return;
6618
6825
6619
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6826
		int length = label.length;
6620
	private void findLocalMethodsFromStaticImports(
6827
		for (int i = 0; i < choices.length; i++) {
6828
			if (length <= choices[i].length
6829
				&& CharOperation.prefixEquals(label, choices[i], false /* ignore case */
6830
			)){
6831
				int relevance = computeBaseRelevance();
6832
				relevance += computeRelevanceForResolution();
6833
				relevance += computeRelevanceForInterestingProposal();
6834
				relevance += computeRelevanceForCaseMatching(label, choices[i]);
6835
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
6836
6837
				this.noProposal = false;
6838
				if(!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
6839
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.LABEL_REF, this.actualCompletionPosition);
6840
					proposal.setName(choices[i]);
6841
					proposal.setCompletion(choices[i]);
6842
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6843
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6844
					proposal.setRelevance(relevance);
6845
					this.requestor.accept(proposal);
6846
					if(DEBUG) {
6847
						this.printDebug(proposal);
6848
					}
6849
				}
6850
			}
6851
		}
6852
	}
6853
6854
	// Helper method for findMethods(char[], MethodBinding[], Scope, ObjectVector, boolean, boolean, boolean, TypeBinding)
6855
	private void findLocalMethodDeclarations(
6621
		char[] methodName,
6856
		char[] methodName,
6622
		MethodBinding[] methods,
6857
		MethodBinding[] methods,
6623
		Scope scope,
6858
		Scope scope,
6624
		boolean exactMatch,
6625
		ObjectVector methodsFound,
6859
		ObjectVector methodsFound,
6626
		ReferenceBinding receiverType,
6860
		//	boolean noVoidReturnType, how do you know?
6627
		InvocationSite invocationSite) {
6861
		boolean exactMatch,
6862
		ReferenceBinding receiverType) {
6628
6863
6629
		ObjectVector newMethodsFound =  new ObjectVector();
6864
		ObjectVector newMethodsFound =  new ObjectVector();
6630
6865
		// Inherited methods which are hidden by subclasses are filtered out
6866
		// No visibility checks can be performed without the scope & invocationSite
6867
		int methodLength = methodName.length;
6631
		next : for (int f = methods.length; --f >= 0;) {
6868
		next : for (int f = methods.length; --f >= 0;) {
6632
			MethodBinding method = methods[f];
6633
6869
6634
			if (method.isSynthetic()) continue next;
6870
			MethodBinding method = methods[f];
6871
			if (method.isSynthetic())	continue next;
6635
6872
6636
			if (method.isDefaultAbstract())	continue next;
6873
			if (method.isDefaultAbstract()) continue next;
6637
6874
6638
			if (method.isConstructor()) continue next;
6875
			if (method.isConstructor()) continue next;
6639
6876
6640
			if (!method.isStatic()) continue next;
6877
			if (method.isFinal()) {
6878
                newMethodsFound.add(method);
6879
                continue next;
6880
            }
6641
6881
6642
			if (this.options.checkDeprecation &&
6882
			if (this.options.checkDeprecation &&
6643
					method.isViewedAsDeprecated() &&
6883
					method.isViewedAsDeprecated() &&
6644
					!scope.isDefinedInSameUnit(method.declaringClass))
6884
					!scope.isDefinedInSameUnit(method.declaringClass))
6645
				continue next;
6885
				continue next;
6646
6886
6647
			if (this.options.checkVisibility
6887
			//		if (noVoidReturnType && method.returnType == BaseTypes.VoidBinding) continue next;
6648
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
6888
			if(method.isStatic()) continue next;
6649
6889
6650
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
6890
			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
6651
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6891
6652
				continue next;
6892
			if (exactMatch) {
6893
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
6894
					))
6895
					continue next;
6896
6897
			} else {
6898
6899
				if (methodLength > method.selector.length)
6900
					continue next;
6901
6902
				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
6903
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
6904
					continue next;
6905
			}
6653
6906
6654
			for (int i = methodsFound.size; --i >= 0;) {
6907
			for (int i = methodsFound.size; --i >= 0;) {
6655
				Object[] other = (Object[]) methodsFound.elementAt(i);
6908
				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
6656
				MethodBinding otherMethod = (MethodBinding) other[0];
6909
				if (method == otherMethod)
6657
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
6658
				if (method == otherMethod && receiverType == otherReceiverType)
6659
					continue next;
6910
					continue next;
6660
6911
6661
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
6912
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
6662
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6913
						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
6663
						continue next;
6914
					continue next;
6664
					}
6665
				}
6915
				}
6666
			}
6916
			}
6667
6917
6668
			newMethodsFound.add(new Object[]{method, receiverType});
6918
			newMethodsFound.add(method);
6669
6919
6670
			int length = method.parameters.length;
6920
			int length = method.parameters.length;
6671
			char[][] parameterPackageNames = new char[length][];
6921
			char[][] parameterPackageNames = new char[length][];
6672
			char[][] parameterTypeNames = new char[length][];
6922
			char[][] parameterFullTypeNames = new char[length][];
6673
6923
6674
			for (int i = 0; i < length; i++) {
6924
			for (int i = 0; i < length; i++) {
6675
				TypeBinding type = method.original().parameters[i];
6925
				TypeBinding type = method.parameters[i];
6676
				parameterPackageNames[i] = type.qualifiedPackageName();
6926
				parameterPackageNames[i] = type.qualifiedPackageName();
6677
				parameterTypeNames[i] = type.qualifiedSourceName();
6927
				parameterFullTypeNames[i] = type.qualifiedSourceName();
6678
			}
6928
			}
6679
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
6680
6681
			char[] completion = CharOperation.NO_CHAR;
6682
6929
6683
			int previousStartPosition = this.startPosition;
6930
			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
6684
			int previousTokenStart = this.tokenStart;
6685
6931
6686
			if (!exactMatch) {
6932
			if(method.typeVariables != null && method.typeVariables.length > 0) {
6687
				if (this.source != null
6933
				char[][] excludedNames = findEnclosingTypeNames(scope);
6688
					&& this.source.length > this.endPosition
6934
				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
6689
					&& this.source[this.endPosition] == '(') {
6935
				if(substituedParameterNames != null) {
6690
					completion = method.selector;
6936
					method = new ParameterizedMethodBinding(
6691
				} else {
6937
								method.declaringClass,
6692
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
6938
								method,
6693
				}
6939
								substituedParameterNames,
6694
			} else {
6940
								scope.environment());
6695
				this.startPosition = this.endPosition;
6941
				}
6696
				this.tokenStart = this.tokenEnd;
6942
			}
6943
6944
			StringBuffer completion = new StringBuffer(10);
6945
			if (!exactMatch) {
6946
				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
6697
			}
6947
			}
6698
6948
6699
			int relevance = computeBaseRelevance();
6949
			int relevance = computeBaseRelevance();
6700
			relevance += computeRelevanceForResolution();
6950
			relevance += computeRelevanceForResolution();
6701
			relevance += computeRelevanceForInterestingProposal();
6951
			relevance += computeRelevanceForInterestingProposal();
6702
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6952
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
6703
			relevance += computeRelevanceForExpectingType(method.returnType);
6953
			relevance += R_METHOD_OVERIDE;
6704
			relevance += computeRelevanceForEnumConstant(method.returnType);
6954
			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
6705
			relevance += computeRelevanceForStatic(true, method.isStatic());
6706
			relevance += computeRelevanceForQualification(false);
6707
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6955
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
6708
6956
6709
			this.noProposal = false;
6957
			this.noProposal = false;
6710
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
6958
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
6711
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
6959
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
6712
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6960
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
6961
				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
6713
				proposal.setSignature(getSignature(method));
6962
				proposal.setSignature(getSignature(method));
6714
				MethodBinding original = method.original();
6963
				MethodBinding original = method.original();
6715
				if(original != method) {
6964
				if(original != method) {
6716
					proposal.setOriginalSignature(getSignature(original));
6965
					proposal.setOriginalSignature(getSignature(original));
6717
				}
6966
				}
6967
				proposal.setKey(method.computeUniqueKey());
6718
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6968
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
6719
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6969
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
6720
				proposal.setParameterPackageNames(parameterPackageNames);
6970
				proposal.setParameterPackageNames(parameterPackageNames);
6721
				proposal.setParameterTypeNames(parameterTypeNames);
6971
				proposal.setParameterTypeNames(parameterFullTypeNames);
6722
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6972
				proposal.setPackageName(method.returnType.qualifiedPackageName());
6723
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6973
				proposal.setTypeName(method.returnType.qualifiedSourceName());
6974
				proposal.setCompletion(completion.toString().toCharArray());
6724
				proposal.setName(method.selector);
6975
				proposal.setName(method.selector);
6725
				proposal.setCompletion(completion);
6726
				proposal.setFlags(method.modifiers);
6976
				proposal.setFlags(method.modifiers);
6727
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6977
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
6728
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
6978
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
Lines 6733-10022 Link Here
6733
					this.printDebug(proposal);
6983
					this.printDebug(proposal);
6734
				}
6984
				}
6735
			}
6985
			}
6736
			this.startPosition = previousStartPosition;
6737
			this.tokenStart = previousTokenStart;
6738
		}
6986
		}
6739
6740
		methodsFound.addAll(newMethodsFound);
6987
		methodsFound.addAll(newMethodsFound);
6741
	}
6988
	}
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
6989
6809
		if(prefixRequired && this.insideQualifiedReference) {
6990
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
6810
			return R_QUALIFIED;
6991
	private void findLocalMethods(
6811
		}
6992
		char[] methodName,
6812
		return 0;
6993
		TypeBinding[] typeArgTypes,
6813
	}
6994
		TypeBinding[] argTypes,
6814
	int computeRelevanceForRestrictions(int accessRuleKind) {
6995
		MethodBinding[] methods,
6815
		if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
6996
		Scope scope,
6816
			return R_NON_RESTRICTED;
6997
		ObjectVector methodsFound,
6817
		}
6998
		boolean onlyStaticMethods,
6818
		return 0;
6999
		boolean exactMatch,
6819
	}
7000
		ReferenceBinding receiverType,
6820
	private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
7001
		InvocationSite invocationSite,
6821
		if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
7002
		Scope invocationScope,
6822
			return R_NON_STATIC;
7003
		boolean implicitCall,
6823
		}
7004
		boolean superCall,
6824
		return 0;
7005
		boolean canBePrefixed,
6825
	}
7006
		Binding[] missingElements,
6826
	private int computeRelevanceForEnumConstant(TypeBinding proposalType){
7007
		int[] missingElementsStarts,
6827
		if(this.assistNodeIsEnum &&
7008
		int[] missingElementsEnds,
6828
				proposalType != null &&
7009
		boolean missingElementsHaveProblems,
6829
				this.expectedTypes != null) {
7010
		char[] castedReceiver,
6830
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
7011
		int receiverStart,
6831
				if (proposalType.isEnum() &&
7012
		int receiverEnd) {
6832
						proposalType == this.expectedTypes[i]) {
6833
					return R_ENUM + R_ENUM_CONSTANT;
6834
				}
6835
7013
6836
			}
7014
		ObjectVector newMethodsFound =  new ObjectVector();
6837
		}
7015
		// Inherited methods which are hidden by subclasses are filtered out
6838
		return 0;
7016
		// 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
7017
6848
		if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
7018
		int methodLength = methodName.length;
6849
			(CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
7019
		int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
6850
			CharOperation.match(ERROR_PATTERN, proposalName, false))) {
7020
		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
7021
6862
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
7022
		next : for (int f = methods.length; --f >= 0;) {
6863
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
7023
			MethodBinding method = methods[f];
6864
						return R_EXACT_EXPECTED_TYPE;
6865
					}
6866
7024
6867
					relevance = R_EXPECTED_TYPE;
7025
			if (method.isSynthetic()) continue next;
6868
				}
6869
				if((this.expectedTypesFilter & SUPERTYPE) != 0
6870
						&& this.expectedTypes[i].isCompatibleWith(proposalType)) {
6871
7026
6872
					if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
7027
			if (method.isDefaultAbstract())	continue next;
6873
							CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
6874
						return R_EXACT_EXPECTED_TYPE;
6875
					}
6876
7028
6877
					relevance = R_EXPECTED_TYPE;
7029
			if (method.isConstructor()) continue next;
6878
				}
7030
7031
			if (this.options.checkDeprecation &&
7032
					method.isViewedAsDeprecated() &&
7033
					!scope.isDefinedInSameUnit(method.declaringClass))
7034
				continue next;
7035
7036
			//TODO (david) perhaps the relevance of a void method must be lesser than other methods
7037
			//if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
7038
7039
			if (onlyStaticMethods && !method.isStatic()) continue next;
7040
7041
			if (this.options.checkVisibility
7042
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7043
7044
			if(superCall && method.isAbstract()) {
7045
				methodsFound.add(new Object[]{method, receiverType});
7046
				continue next;
6879
			}
7047
			}
6880
			return relevance;
7048
6881
		}
7049
			if (exactMatch) {
6882
		return 0;
7050
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
6883
	}
7051
					continue next;
6884
	private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
7052
				}
6885
		if(this.expectedTypes != null) {
7053
			} else {
6886
			for (int i = 0; i <= this.expectedTypesPtr; i++) {
7054
				if (methodLength > method.selector.length) continue next;
6887
				if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
7055
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
6888
					CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
7056
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
6889
					return R_EXACT_EXPECTED_TYPE;
7057
					continue next;
6890
				}
7058
				}
6891
			}
7059
			}
6892
			if(this.hasJavaLangObjectAsExpectedType) {
7060
6893
				return R_EXPECTED_TYPE;
7061
			if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
7062
				continue next;
7063
7064
			if (minTypeArgLength != 0) {
7065
				method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
6894
			}
7066
			}
6895
		}
6896
		return 0;
6897
	}
6898
7067
6899
	private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
7068
			if (minArgLength > method.parameters.length)
6900
		if (receiverType == declaringClass) return R_NON_INHERITED;
7069
				continue next;
6901
		return 0;
6902
	}
6903
7070
6904
	int computeRelevanceForInterestingProposal(){
7071
			for (int a = minArgLength; --a >= 0;){
6905
		return computeRelevanceForInterestingProposal(null);
7072
				if (argTypes[a] != null) { // can be null if it could not be resolved properly
6906
	}
7073
					if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
6907
	private int computeRelevanceForInterestingProposal(Binding binding){
7074
						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
					}
7075
					}
6951
				}
7076
				}
6952
			}
7077
			}
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
7078
6992
			if (!method.canBeSeenBy(receiverType, FakeInvocationSite , scope)) continue next;
7079
			boolean prefixRequired = false;
6993
7080
6994
			if (exactMatch) {
7081
			for (int i = methodsFound.size; --i >= 0;) {
6995
				if (!CharOperation.equals(methodName, method.selector, false /* ignore case */
7082
				Object[] other = (Object[]) methodsFound.elementAt(i);
6996
					))
7083
				MethodBinding otherMethod = (MethodBinding) other[0];
7084
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
7085
				if (method == otherMethod && receiverType == otherReceiverType)
6997
					continue next;
7086
					continue next;
6998
7087
6999
			} else {
7088
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7089
					if (receiverType == otherReceiverType) {
7090
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7091
							if (!superCall || !otherMethod.declaringClass.isInterface()) {
7092
								continue next;
7093
							}
7094
						}
7095
					} else {
7096
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7097
							if(receiverType.isAnonymousType()) continue next;
7000
7098
7001
				if (methodLength > method.selector.length)
7099
							if(!superCall) {
7002
					continue next;
7100
								if(!canBePrefixed) continue next;
7003
7101
7004
				if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
7102
								prefixRequired = true;
7005
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
7103
							}
7006
					continue next;
7104
						}
7105
					}
7106
				}
7007
			}
7107
			}
7008
7108
7009
			for (int i = methodsFound.size; --i >= 0;) {
7109
			newMethodsFound.add(new Object[]{method, receiverType});
7010
				MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
7011
				if (method == otherMethod)
7012
					continue next;
7013
7110
7014
				if (CharOperation.equals(method.selector, otherMethod.selector, true)
7111
			ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7015
						&& this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7112
			if (method.declaringClass != superTypeWithSameErasure) {
7016
					continue next;
7113
				MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7114
				for (int i = 0; i < otherMethods.length; i++) {
7115
					if(otherMethods[i].original() == method.original()) {
7116
						method = otherMethods[i];
7117
					}
7017
				}
7118
				}
7018
			}
7119
			}
7019
7120
7020
			newMethodsFound.add(method);
7021
7022
			int length = method.parameters.length;
7121
			int length = method.parameters.length;
7023
			char[][] parameterPackageNames = new char[length][];
7122
			char[][] parameterPackageNames = new char[length][];
7024
			char[][] parameterFullTypeNames = new char[length][];
7123
			char[][] parameterTypeNames = new char[length][];
7025
7124
7026
			for (int i = 0; i < length; i++) {
7125
			for (int i = 0; i < length; i++) {
7027
				TypeBinding type = method.parameters[i];
7126
				TypeBinding type = method.original().parameters[i];
7028
				parameterPackageNames[i] = type.qualifiedPackageName();
7127
				parameterPackageNames[i] = type.qualifiedPackageName();
7029
				parameterFullTypeNames[i] = type.qualifiedSourceName();
7128
				parameterTypeNames[i] = type.qualifiedSourceName();
7030
			}
7129
			}
7130
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7031
7131
7032
			char[][] parameterNames = findMethodParameterNames(method, parameterFullTypeNames);
7132
			char[] completion = CharOperation.NO_CHAR;
7033
7133
7034
			if(method.typeVariables != null && method.typeVariables.length > 0) {
7134
			int previousStartPosition = this.startPosition;
7035
				char[][] excludedNames = findEnclosingTypeNames(scope);
7135
			int previousTokenStart = this.tokenStart;
7036
				char[][] substituedParameterNames = substituteMethodTypeParameterNames(method.typeVariables, excludedNames);
7136
7037
				if(substituedParameterNames != null) {
7137
			// Special case for completion in javadoc
7038
					method = new ParameterizedMethodBinding(
7138
			if (this.assistNodeInJavadoc > 0) {
7039
								method.declaringClass,
7139
				Expression receiver = null;
7040
								method,
7140
				if (invocationSite instanceof CompletionOnJavadocMessageSend) {
7041
								substituedParameterNames,
7141
					CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
7042
								scope.environment());
7142
					receiver = msg.receiver;
7143
				} else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
7144
					CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
7145
					receiver = fieldRef.receiver;
7043
				}
7146
				}
7044
			}
7147
				if (receiver != null) {
7148
					StringBuffer javadocCompletion = new StringBuffer();
7149
					if (receiver.isThis()) {
7150
						if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7151
							javadocCompletion.append('#');
7152
						}
7153
					} else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
7154
						if (receiver instanceof JavadocSingleTypeReference) {
7155
							JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
7156
							javadocCompletion.append(typeRef.token);
7157
							javadocCompletion.append('#');
7158
						} else if (receiver instanceof JavadocQualifiedTypeReference) {
7159
							JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
7160
							completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
7161
							for (int t=0,nt =typeRef.tokens.length; t<nt; t++) {
7162
								if (t>0) javadocCompletion.append('.');
7163
								javadocCompletion.append(typeRef.tokens[t]);
7164
							}
7165
							javadocCompletion.append('#');
7166
						}
7167
					}
7168
					javadocCompletion.append(method.selector);
7169
					// Append parameters types
7170
					javadocCompletion.append('(');
7171
					if (method.parameters != null) {
7172
						boolean isVarargs = method.isVarargs();
7173
						for (int p=0, ln=method.parameters.length; p<ln; p++) {
7174
							if (p>0) javadocCompletion.append(", "); //$NON-NLS-1$
7175
							TypeBinding argTypeBinding = method.parameters[p];
7176
							if (isVarargs && p == ln - 1)  {
7177
								createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
7178
							} else {
7179
								createType(argTypeBinding.erasure(), scope,javadocCompletion);
7180
							}
7181
						}
7182
					}
7183
					javadocCompletion.append(')');
7184
					completion = javadocCompletion.toString().toCharArray();
7185
				}
7186
			} else {
7187
				// nothing to insert - do not want to replace the existing selector & arguments
7188
				if (!exactMatch) {
7189
					if (this.source != null
7190
						&& this.source.length > this.endPosition
7191
						&& this.source[this.endPosition] == '(')
7192
						completion = method.selector;
7193
					else
7194
						completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7045
7195
7046
			StringBuffer completion = new StringBuffer(10);
7196
					if (castedReceiver != null) {
7047
			if (!exactMatch) {
7197
						completion = CharOperation.concat(castedReceiver, completion);
7048
				createMethod(method, parameterPackageNames, parameterFullTypeNames, parameterNames, scope, completion);
7198
					}
7199
				} else {
7200
					if(prefixRequired && (this.source != null)) {
7201
						completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
7202
					} else {
7203
						this.startPosition = this.endPosition;
7204
					}
7205
					this.tokenStart = this.tokenEnd;
7206
				}
7207
7208
				if(prefixRequired || this.options.forceImplicitQualification){
7209
					char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
7210
					completion = CharOperation.concat(prefix,completion,'.');
7211
				}
7049
			}
7212
			}
7050
7213
7051
			int relevance = computeBaseRelevance();
7214
			int relevance = computeBaseRelevance();
7052
			relevance += computeRelevanceForResolution();
7215
			relevance += computeRelevanceForResolution();
7053
			relevance += computeRelevanceForInterestingProposal();
7216
			relevance += computeRelevanceForInterestingProposal();
7054
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7217
			if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7055
			relevance += R_METHOD_OVERIDE;
7218
			relevance += computeRelevanceForExpectingType(method.returnType);
7056
			if(method.isAbstract()) relevance += R_ABSTRACT_METHOD;
7219
			relevance += computeRelevanceForEnumConstant(method.returnType);
7220
			relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
7221
			relevance += computeRelevanceForQualification(prefixRequired);
7057
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7222
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7223
			if (onlyStaticMethods && this.insideQualifiedReference) {
7224
				relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
7225
			}
7226
			if (missingElements != null) {
7227
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
7228
			}
7058
7229
7059
			this.noProposal = false;
7230
			this.noProposal = false;
7060
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
7231
7061
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_DECLARATION, this.actualCompletionPosition);
7232
			if (castedReceiver == null) {
7062
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
7233
				// Standard proposal
7063
				proposal.setDeclarationKey(method.declaringClass.computeUniqueKey());
7234
				if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
7064
				proposal.setSignature(getSignature(method));
7235
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7065
				MethodBinding original = method.original();
7236
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7066
				if(original != method) {
7237
					proposal.setSignature(getSignature(method));
7067
					proposal.setOriginalSignature(getSignature(original));
7238
					MethodBinding original = method.original();
7239
					if(original != method) {
7240
						proposal.setOriginalSignature(getSignature(original));
7241
					}
7242
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7243
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7244
					proposal.setParameterPackageNames(parameterPackageNames);
7245
					proposal.setParameterTypeNames(parameterTypeNames);
7246
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7247
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7248
					proposal.setName(method.selector);
7249
					if (missingElements != null) {
7250
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7251
						for (int i = 0; i < missingElements.length; i++) {
7252
							subProposals[i] =
7253
								createRequiredTypeProposal(
7254
										missingElements[i],
7255
										missingElementsStarts[i],
7256
										missingElementsEnds[i],
7257
										relevance);
7258
						}
7259
						proposal.setRequiredProposals(subProposals);
7260
					}
7261
					proposal.setCompletion(completion);
7262
					proposal.setFlags(method.modifiers);
7263
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7264
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7265
					proposal.setRelevance(relevance);
7266
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7267
					this.requestor.accept(proposal);
7268
					if(DEBUG) {
7269
						this.printDebug(proposal);
7270
					}
7068
				}
7271
				}
7069
				proposal.setKey(method.computeUniqueKey());
7272
7070
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7273
				// Javadoc proposal
7071
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7274
				if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
7072
				proposal.setParameterPackageNames(parameterPackageNames);
7275
					char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
7073
				proposal.setParameterTypeNames(parameterFullTypeNames);
7276
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
7074
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7277
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7075
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7278
					proposal.setSignature(getSignature(method));
7076
				proposal.setCompletion(completion.toString().toCharArray());
7279
					MethodBinding original = method.original();
7077
				proposal.setName(method.selector);
7280
					if(original != method) {
7078
				proposal.setFlags(method.modifiers);
7281
						proposal.setOriginalSignature(getSignature(original));
7079
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7282
					}
7080
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7283
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7081
				proposal.setRelevance(relevance);
7284
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7082
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7285
					proposal.setParameterPackageNames(parameterPackageNames);
7083
				this.requestor.accept(proposal);
7286
					proposal.setParameterTypeNames(parameterTypeNames);
7084
				if(DEBUG) {
7287
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7085
					this.printDebug(proposal);
7288
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7289
					proposal.setName(method.selector);
7290
					proposal.setCompletion(javadocCompletion);
7291
					proposal.setFlags(method.modifiers);
7292
					int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
7293
					proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
7294
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7295
					proposal.setRelevance(relevance+R_INLINE_TAG);
7296
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7297
					this.requestor.accept(proposal);
7298
					if(DEBUG) {
7299
						this.printDebug(proposal);
7300
					}
7301
				}
7302
			} else {
7303
				if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
7304
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
7305
					proposal.setDeclarationSignature(getSignature(method.declaringClass));
7306
					proposal.setSignature(getSignature(method));
7307
					MethodBinding original = method.original();
7308
					if(original != method) {
7309
						proposal.setOriginalSignature(getSignature(original));
7310
					}
7311
					proposal.setReceiverSignature(getSignature(receiverType));
7312
					proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7313
					proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7314
					proposal.setParameterPackageNames(parameterPackageNames);
7315
					proposal.setParameterTypeNames(parameterTypeNames);
7316
					proposal.setPackageName(method.returnType.qualifiedPackageName());
7317
					proposal.setTypeName(method.returnType.qualifiedSourceName());
7318
					proposal.setName(method.selector);
7319
					if (missingElements != null) {
7320
						CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
7321
						for (int i = 0; i < missingElements.length; i++) {
7322
							subProposals[i] =
7323
								createRequiredTypeProposal(
7324
										missingElements[i],
7325
										missingElementsStarts[i],
7326
										missingElementsEnds[i],
7327
										relevance);
7328
						}
7329
						proposal.setRequiredProposals(subProposals);
7330
					}
7331
					proposal.setCompletion(completion);
7332
					proposal.setFlags(method.modifiers);
7333
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7334
					proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
7335
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7336
					proposal.setRelevance(relevance);
7337
					if(parameterNames != null) proposal.setParameterNames(parameterNames);
7338
					this.requestor.accept(proposal);
7339
					if(DEBUG) {
7340
						this.printDebug(proposal);
7341
					}
7086
				}
7342
				}
7087
			}
7343
			}
7344
			this.startPosition = previousStartPosition;
7345
			this.tokenStart = previousTokenStart;
7088
		}
7346
		}
7347
7089
		methodsFound.addAll(newMethodsFound);
7348
		methodsFound.addAll(newMethodsFound);
7090
	}
7349
	}
7350
	private void findLocalMethodsFromFavorites(
7351
			char[] methodName,
7352
			MethodBinding[] methods,
7353
			Scope scope,
7354
			ObjectVector methodsFound,
7355
			ObjectVector methodsFoundFromFavorites,
7356
			ReferenceBinding receiverType,
7357
			InvocationSite invocationSite,
7358
			Scope invocationScope) {
7091
7359
7092
	private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
7360
			char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
7093
		completion.append(typeVariable.sourceName);
7094
7361
7095
		if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
7362
			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
7363
7118
	private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
7364
			next : for (int f = methods.length; --f >= 0;) {
7119
		switch (type.kind()) {
7365
				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
7366
7135
							int length = wildcardBinding.otherBounds.length;
7367
				if (method.isSynthetic()) continue next;
7136
							for (int i = 0; i < length; i++) {
7368
7137
								completion.append(' ');
7369
				if (method.isDefaultAbstract())	continue next;
7138
								completion.append('&');
7370
7139
								completion.append(' ');
7371
				if (method.isConstructor()) continue next;
7140
								createType(wildcardBinding.otherBounds[i], scope, completion);
7372
7141
							}
7373
				if (this.options.checkDeprecation &&
7374
						method.isViewedAsDeprecated() &&
7375
						!scope.isDefinedInSameUnit(method.declaringClass))
7376
					continue next;
7377
7378
				if (!method.isStatic()) continue next;
7379
7380
				if (this.options.checkVisibility
7381
					&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7382
7383
				if (methodLength > method.selector.length) continue next;
7384
7385
				if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
7386
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
7387
					continue next;
7388
				}
7389
7390
				for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
7391
					Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
7392
					MethodBinding otherMethod = (MethodBinding) other[0];
7393
7394
					if (method == otherMethod) continue next;
7395
7396
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7397
						if (otherMethod.declaringClass == method.declaringClass &&
7398
								this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7399
							continue next;
7142
						}
7400
						}
7143
						break;
7401
					}
7144
					case Wildcard.SUPER:
7145
						completion.append(' ');
7146
						completion.append(SUPER);
7147
						completion.append(' ');
7148
						createType(wildcardBinding.bound, scope, completion);
7149
						break;
7150
				}
7402
				}
7151
				break;
7403
7152
			case Binding.ARRAY_TYPE :
7404
				for (int i = methodsFound.size; --i >= 0;) {
7153
				createType(type.leafComponentType(), scope, completion);
7405
					Object[] other = (Object[]) methodsFound.elementAt(i);
7154
				int dim = type.dimensions();
7406
					MethodBinding otherMethod = (MethodBinding) other[0];
7155
				for (int i = 0; i < dim; i++) {
7407
7156
					completion.append('[');
7408
					if (method == otherMethod) continue next;
7157
					completion.append(']');
7409
7410
					if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7411
						if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7412
							continue next;
7413
						}
7414
					}
7158
				}
7415
				}
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
7416
7225
		//// Type parameters
7417
				boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
7418
					this.options.suggestStaticImport;
7226
7419
7227
		TypeVariableBinding[] typeVariableBindings = method.typeVariables;
7420
				boolean isAlreadyImported = false;
7228
		if(typeVariableBindings != null && typeVariableBindings.length != 0) {
7421
				if (!proposeStaticImport) {
7229
			completion.append('<');
7422
					if(!this.importCachesInitialized) {
7230
			for (int i = 0; i < typeVariableBindings.length; i++) {
7423
						initializeImportCaches();
7231
				if(i != 0) {
7424
					}
7232
					completion.append(',');
7425
					for (int j = 0; j < this.importCacheCount; j++) {
7233
					completion.append(' ');
7426
						char[][] importName = this.importsCache[j];
7427
						if(CharOperation.equals(receiverType.sourceName, importName[0])) {
7428
							if (!CharOperation.equals(typeName, importName[1])) {
7429
								continue next;
7430
							} else {
7431
								isAlreadyImported = true;
7432
							}
7433
						}
7434
					}
7234
				}
7435
				}
7235
				createTypeVariable(typeVariableBindings[i], scope, completion);
7236
			}
7237
			completion.append('>');
7238
			completion.append(' ');
7239
		}
7240
7436
7241
		//// Return type
7437
				methodsFoundFromFavorites.add(new Object[]{method, receiverType});
7242
		createType(method.returnType, scope, completion);
7243
		completion.append(' ');
7244
7438
7245
		//// Selector
7439
				ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
7246
		completion.append(method.selector);
7440
				if (method.declaringClass != superTypeWithSameErasure) {
7441
					MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
7442
					for (int i = 0; i < otherMethods.length; i++) {
7443
						if(otherMethods[i].original() == method.original()) {
7444
							method = otherMethods[i];
7445
						}
7446
					}
7447
				}
7247
7448
7248
		completion.append('(');
7449
				int length = method.parameters.length;
7450
				char[][] parameterPackageNames = new char[length][];
7451
				char[][] parameterTypeNames = new char[length][];
7249
7452
7250
		////Parameters
7453
				for (int i = 0; i < length; i++) {
7251
		TypeBinding[] parameterTypes = method.parameters;
7454
					TypeBinding type = method.original().parameters[i];
7252
		int length = parameterTypes.length;
7455
					parameterPackageNames[i] = type.qualifiedPackageName();
7253
		for (int i = 0; i < length; i++) {
7456
					parameterTypeNames[i] = type.qualifiedSourceName();
7254
			if(i != 0) {
7457
				}
7255
				completion.append(',');
7458
				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
7459
7267
		completion.append(')');
7460
				char[] completion = CharOperation.NO_CHAR;
7268
7461
7269
		//// Exceptions
7462
				int previousStartPosition = this.startPosition;
7270
		ReferenceBinding[] exceptions = method.thrownExceptions;
7463
				int previousTokenStart = this.tokenStart;
7271
7464
7272
		if (exceptions != null && exceptions.length > 0){
7465
				if (this.source != null
7273
			completion.append(' ');
7466
					&& this.source.length > this.endPosition
7274
			completion.append(THROWS);
7467
					&& this.source[this.endPosition] == '(') {
7275
			completion.append(' ');
7468
					completion = method.selector;
7276
			for(int i = 0; i < exceptions.length ; i++){
7469
				} else {
7277
				if(i != 0) {
7470
					completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
7278
					completion.append(' ');
7279
					completion.append(',');
7280
				}
7471
				}
7281
				createType(exceptions[i], scope, completion);
7282
			}
7283
		}
7284
	}
7285
7472
7286
	private boolean isIgnored(int kind, boolean missingTypes) {
7473
				int relevance = computeBaseRelevance();
7287
		return this.requestor.isIgnored(kind) ||
7474
				relevance += computeRelevanceForResolution();
7288
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
7475
				relevance += computeRelevanceForInterestingProposal();
7289
	}
7476
				if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7477
				relevance += computeRelevanceForExpectingType(method.returnType);
7478
				relevance += computeRelevanceForEnumConstant(method.returnType);
7479
				relevance += computeRelevanceForStatic(true, method.isStatic());
7480
				relevance += computeRelevanceForQualification(true);
7481
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
7290
7482
7291
	private boolean isIgnored(int kind) {
7483
				CompilationUnitDeclaration cu = this.unitScope.referenceContext;
7292
		return this.requestor.isIgnored(kind);
7484
				int importStart = cu.types[0].declarationSourceStart;
7293
	}
7485
				int importEnd = importStart;
7294
7486
7295
	private boolean isIgnored(int kind, int requiredProposalKind) {
7487
				this.noProposal = false;
7296
		return this.requestor.isIgnored(kind) ||
7297
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
7298
	}
7299
7488
7300
	private void findMethods(
7489
				if (!proposeStaticImport) {
7301
		char[] selector,
7490
					if (isAlreadyImported) {
7302
		TypeBinding[] typeArgTypes,
7491
						if (!isIgnored(CompletionProposal.METHOD_REF)) {
7303
		TypeBinding[] argTypes,
7492
							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
7493
7323
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
7494
							InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7324
		if (selector == null && notInJavadoc) {
7495
							proposal.setDeclarationSignature(getSignature(method.declaringClass));
7325
			return;
7496
							proposal.setSignature(getSignature(method));
7326
		}
7497
							MethodBinding original = method.original();
7498
							if(original != method) {
7499
								proposal.setOriginalSignature(getSignature(original));
7500
							}
7501
							proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7502
							proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7503
							proposal.setParameterPackageNames(parameterPackageNames);
7504
							proposal.setParameterTypeNames(parameterTypeNames);
7505
							proposal.setPackageName(method.returnType.qualifiedPackageName());
7506
							proposal.setTypeName(method.returnType.qualifiedSourceName());
7507
							proposal.setName(method.selector);
7508
							proposal.setCompletion(completion);
7509
							proposal.setFlags(method.modifiers);
7510
							proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7511
							proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7512
							proposal.setRelevance(relevance);
7513
							if(parameterNames != null) proposal.setParameterNames(parameterNames);
7327
7514
7328
		if(isCompletingDeclaration) {
7515
							this.requestor.accept(proposal);
7329
			MethodBinding[] methods = receiverType.availableMethods();
7516
							if(DEBUG) {
7330
			if (methods != null){
7517
								this.printDebug(proposal);
7331
				for (int i = 0; i < methods.length; i++) {
7518
							}
7332
					if(!methods[i].isDefaultAbstract()) {
7519
						}
7333
						methodsFound.add(methods[i]);
7520
					} else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
7334
					}
7521
						completion = CharOperation.concat(receiverType.sourceName, completion, '.');
7335
				}
7336
			}
7337
		}
7338
7522
7339
		ReferenceBinding currentType = receiverType;
7523
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7340
		if (notInJavadoc) {
7524
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7341
			if (receiverType.isInterface()) {
7525
						proposal.setSignature(getSignature(method));
7342
				if (isCompletingDeclaration) {
7526
						MethodBinding original = method.original();
7343
					findInterfacesMethods(
7527
						if(original != method) {
7344
						selector,
7528
							proposal.setOriginalSignature(getSignature(original));
7345
						typeArgTypes,
7529
						}
7346
						argTypes,
7530
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7347
						receiverType,
7531
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7348
						currentType.superInterfaces(),
7532
						proposal.setParameterPackageNames(parameterPackageNames);
7349
						scope,
7533
						proposal.setParameterTypeNames(parameterTypeNames);
7350
						methodsFound,
7534
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7351
						onlyStaticMethods,
7535
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7352
						exactMatch,
7536
						proposal.setName(method.selector);
7353
						isCompletingDeclaration,
7537
						proposal.setCompletion(completion);
7354
						invocationSite,
7538
						proposal.setFlags(method.modifiers);
7355
						invocationScope,
7539
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7356
						implicitCall,
7540
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7357
						superCall,
7541
						proposal.setRelevance(relevance);
7358
						canBePrefixed,
7542
						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
7543
7419
					currentType = receiverType.superclass();
7544
						char[] typeImportCompletion = createImportCharArray(typeName, false, false);
7420
				}
7421
			}
7422
		}
7423
		boolean hasPotentialDefaultAbstractMethods = true;
7424
		while (currentType != null) {
7425
7545
7426
			MethodBinding[] methods = currentType.availableMethods();
7546
						InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
7427
			if (methods != null) {
7547
						typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
7428
				if (isCompletingDeclaration){
7548
						typeImportProposal.completionEngine = this;
7429
					findLocalMethodDeclarations(
7549
						char[] packageName = receiverType.qualifiedPackageName();
7430
						selector,
7550
						typeImportProposal.setDeclarationSignature(packageName);
7431
						methods,
7551
						typeImportProposal.setSignature(getSignature(receiverType));
7432
						scope,
7552
						typeImportProposal.setPackageName(packageName);
7433
						methodsFound,
7553
						typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
7434
						exactMatch,
7554
						typeImportProposal.setCompletion(typeImportCompletion);
7435
						receiverType);
7555
						typeImportProposal.setFlags(receiverType.modifiers);
7436
				} else{
7556
						typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
7437
					findLocalMethods(
7557
						typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7438
						selector,
7558
						typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7439
						typeArgTypes,
7559
						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
7560
7462
			if (hasPotentialDefaultAbstractMethods &&
7561
						proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
7463
					(currentType.isAbstract() ||
7464
							currentType.isTypeVariable() ||
7465
							currentType.isIntersectionType() ||
7466
							currentType.isEnum())){
7467
7562
7468
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
7563
						this.requestor.accept(proposal);
7469
				if (superInterfaces != null && currentType.isIntersectionType()) {
7564
						if(DEBUG) {
7470
					for (int i = 0; i < superInterfaces.length; i++) {
7565
							this.printDebug(proposal);
7471
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
7566
						}
7472
					}
7567
					}
7473
				}
7568
				} else {
7474
7569
					if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
7475
				findInterfacesMethods(
7570
						InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7476
					selector,
7571
						proposal.setDeclarationSignature(getSignature(method.declaringClass));
7477
					typeArgTypes,
7572
						proposal.setSignature(getSignature(method));
7478
					argTypes,
7573
						MethodBinding original = method.original();
7479
					receiverType,
7574
						if(original != method) {
7480
					superInterfaces,
7575
							proposal.setOriginalSignature(getSignature(original));
7481
					scope,
7576
						}
7482
					methodsFound,
7577
						proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7483
					onlyStaticMethods,
7578
						proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7484
					exactMatch,
7579
						proposal.setParameterPackageNames(parameterPackageNames);
7485
					isCompletingDeclaration,
7580
						proposal.setParameterTypeNames(parameterTypeNames);
7486
					invocationSite,
7581
						proposal.setPackageName(method.returnType.qualifiedPackageName());
7487
					invocationScope,
7582
						proposal.setTypeName(method.returnType.qualifiedSourceName());
7488
					implicitCall,
7583
						proposal.setName(method.selector);
7489
					superCall,
7584
						proposal.setCompletion(completion);
7490
					canBePrefixed,
7585
						proposal.setFlags(method.modifiers);
7491
					missingElements,
7586
						proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7492
					missingElementsStarts,
7587
						proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7493
					missingElementsEnds,
7588
						proposal.setRelevance(relevance);
7494
					missingElementsHaveProblems,
7589
						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
7590
7519
			if (sourceType.scope != null){
7591
						char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
7520
				TypeDeclaration parsedType;
7521
7592
7522
				if ((parsedType = sourceType.scope.referenceContext) != null){
7593
						InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
7523
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
7594
						methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
7595
						methodImportProposal.setSignature(getSignature(method));
7596
						if(original != method) {
7597
							proposal.setOriginalSignature(getSignature(original));
7598
						}
7599
						methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7600
						methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7601
						methodImportProposal.setParameterPackageNames(parameterPackageNames);
7602
						methodImportProposal.setParameterTypeNames(parameterTypeNames);
7603
						methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
7604
						methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
7605
						methodImportProposal.setName(method.selector);
7606
						methodImportProposal.setCompletion(methodImportCompletion);
7607
						methodImportProposal.setFlags(method.modifiers);
7608
						methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
7609
						methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
7610
						methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
7611
						methodImportProposal.setRelevance(relevance);
7612
						if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
7524
7613
7525
					if (methodDecl != null){
7614
						proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
7526
						Argument[] arguments = methodDecl.arguments;
7527
						parameterNames = new char[length][];
7528
7615
7529
						for(int i = 0 ; i < length ; i++){
7616
						this.requestor.accept(proposal);
7530
							parameterNames[i] = arguments[i].name;
7617
						if(DEBUG) {
7618
							this.printDebug(proposal);
7531
						}
7619
						}
7532
					}
7620
					}
7533
				}
7621
				}
7622
7623
				this.startPosition = previousStartPosition;
7624
				this.tokenStart = previousTokenStart;
7534
			}
7625
			}
7535
		}
7626
		}
7536
		// look into the model
7537
		if(parameterNames == null){
7538
7627
7539
			ReferenceBinding bindingType = (ReferenceBinding)erasure;
7628
	// Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
7629
	private void findLocalMethodsFromStaticImports(
7630
		char[] methodName,
7631
		MethodBinding[] methods,
7632
		Scope scope,
7633
		boolean exactMatch,
7634
		ObjectVector methodsFound,
7635
		ReferenceBinding receiverType,
7636
		InvocationSite invocationSite) {
7540
7637
7541
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
7638
		ObjectVector newMethodsFound =  new ObjectVector();
7542
			Object type = this.typeCache.get(compoundName);
7543
7639
7544
			ISourceType sourceType = null;
7640
		next : for (int f = methods.length; --f >= 0;) {
7545
			if(type != null) {
7641
			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
7642
7603
					next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
7643
			if (method.isSynthetic()) continue next;
7604
7644
7605
						if (blockScope.subscopes[i] instanceof ClassScope) {
7645
			if (method.isDefaultAbstract())	continue next;
7606
							SourceTypeBinding localType =
7607
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
7608
7646
7609
							if (!localType.isAnonymousType()) {
7647
			if (method.isConstructor()) continue next;
7610
								if (isForbidden(localType))
7611
									continue next;
7612
7648
7613
								if (typeLength > localType.sourceName.length)
7649
			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
7650
7619
								for (int j = typesFound.size; --j >= 0;) {
7651
			if (this.options.checkDeprecation &&
7620
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
7652
					method.isViewedAsDeprecated() &&
7653
					!scope.isDefinedInSameUnit(method.declaringClass))
7654
				continue next;
7621
7655
7622
									if (localType == otherType)
7656
			if (this.options.checkVisibility
7623
										continue next;
7657
				&& !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
7624
								}
7625
7658
7626
								if(this.assistNodeIsClass) {
7659
			if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
7627
									if(!localType.isClass()) continue next;
7660
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
7628
								} else if(this.assistNodeIsInterface) {
7661
				continue next;
7629
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
7630
								} else if (this.assistNodeIsAnnotation) {
7631
									if(!localType.isAnnotationType()) continue next;
7632
								}
7633
7662
7634
								int relevance = computeBaseRelevance();
7663
			for (int i = methodsFound.size; --i >= 0;) {
7635
								relevance += computeRelevanceForResolution();
7664
				Object[] other = (Object[]) methodsFound.elementAt(i);
7636
								relevance += computeRelevanceForInterestingProposal();
7665
				MethodBinding otherMethod = (MethodBinding) other[0];
7637
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
7666
				ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
7638
								relevance += computeRelevanceForExpectingType(localType);
7667
				if (method == otherMethod && receiverType == otherReceiverType)
7639
								relevance += computeRelevanceForException(localType.sourceName);
7668
					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
7669
7645
								this.noProposal = false;
7670
				if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
7646
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7671
					if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
7647
									createTypeProposal(
7672
						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
					}
7673
					}
7661
					break;
7674
				}
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
			}
7675
			}
7689
			scope = scope.parent;
7690
		}
7691
	}
7692
7676
7693
	private void findPackages(CompletionOnPackageReference packageStatement) {
7677
			newMethodsFound.add(new Object[]{method, receiverType});
7694
7678
7695
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
7679
			int length = method.parameters.length;
7696
		if (this.completionToken.length == 0)
7680
			char[][] parameterPackageNames = new char[length][];
7697
			return;
7681
			char[][] parameterTypeNames = new char[length][];
7698
7682
7699
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
7683
			for (int i = 0; i < length; i++) {
7700
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
7684
				TypeBinding type = method.original().parameters[i];
7701
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
7685
				parameterPackageNames[i] = type.qualifiedPackageName();
7702
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
7686
				parameterTypeNames[i] = type.qualifiedSourceName();
7703
	}
7687
			}
7688
			char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
7704
7689
7705
	private void findParameterizedType(TypeReference ref, Scope scope) {
7690
			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
7691
7713
			int accessibility = IAccessRule.K_ACCESSIBLE;
7692
			int previousStartPosition = this.startPosition;
7714
			if(refBinding.hasRestrictedAccess()) {
7693
			int previousTokenStart = this.tokenStart;
7715
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7694
7716
				if(accessRestriction != null) {
7695
			if (!exactMatch) {
7717
					switch (accessRestriction.getProblemId()) {
7696
				if (this.source != null
7718
						case IProblem.ForbiddenReference:
7697
					&& this.source.length > this.endPosition
7719
							if (this.options.checkForbiddenReference) {
7698
					&& this.source[this.endPosition] == '(') {
7720
								return;
7699
					completion = method.selector;
7721
							}
7700
				} else {
7722
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
7701
					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
				}
7702
				}
7703
			} else {
7704
				this.startPosition = this.endPosition;
7705
				this.tokenStart = this.tokenEnd;
7732
			}
7706
			}
7733
7707
7734
			int relevance = computeBaseRelevance();
7708
			int relevance = computeBaseRelevance();
7735
			relevance += computeRelevanceForResolution();
7709
			relevance += computeRelevanceForResolution();
7736
			relevance += computeRelevanceForInterestingProposal();
7710
			relevance += computeRelevanceForInterestingProposal();
7737
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
7711
			relevance += computeRelevanceForCaseMatching(methodName, method.selector);
7738
			relevance += computeRelevanceForExpectingType(refBinding);
7712
			relevance += computeRelevanceForExpectingType(method.returnType);
7713
			relevance += computeRelevanceForEnumConstant(method.returnType);
7714
			relevance += computeRelevanceForStatic(true, method.isStatic());
7739
			relevance += computeRelevanceForQualification(false);
7715
			relevance += computeRelevanceForQualification(false);
7740
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
7716
			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
7717
7759
		TypeParameter[] typeParameters = null;
7718
			this.noProposal = false;
7760
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
7719
			if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7761
			typeParameters = null;
7720
				InternalCompletionProposal proposal =  createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
7762
			switch (scope.kind) {
7721
				proposal.setDeclarationSignature(getSignature(method.declaringClass));
7763
				case Scope.METHOD_SCOPE :
7722
				proposal.setSignature(getSignature(method));
7764
					MethodScope methodScope = (MethodScope) scope;
7723
				MethodBinding original = method.original();
7765
					if(methodScope.referenceContext instanceof MethodDeclaration) {
7724
				if(original != method) {
7766
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
7725
					proposal.setOriginalSignature(getSignature(original));
7767
						typeParameters = methodDeclaration.typeParameters;
7726
				}
7768
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
7727
				proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
7769
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
7728
				proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
7770
						typeParameters = methodDeclaration.typeParameters;
7729
				proposal.setParameterPackageNames(parameterPackageNames);
7771
					}
7730
				proposal.setParameterTypeNames(parameterTypeNames);
7772
					break;
7731
				proposal.setPackageName(method.returnType.qualifiedPackageName());
7773
				case Scope.CLASS_SCOPE :
7732
				proposal.setTypeName(method.returnType.qualifiedSourceName());
7774
					ClassScope classScope = (ClassScope) scope;
7733
				proposal.setName(method.selector);
7775
					typeParameters = classScope.referenceContext.typeParameters;
7734
				proposal.setCompletion(completion);
7776
					break;
7735
				proposal.setFlags(method.modifiers);
7777
				case Scope.COMPILATION_UNIT_SCOPE :
7736
				proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7778
					return;
7737
				proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7779
			}
7738
				proposal.setRelevance(relevance);
7780
			if(typeParameters != null) {
7739
				if(parameterNames != null) proposal.setParameterNames(parameterNames);
7781
				for (int i = 0; i < typeParameters.length; i++) {
7740
				this.requestor.accept(proposal);
7782
					int typeLength = token.length;
7741
				if(DEBUG) {
7783
					TypeParameter typeParameter = typeParameters[i];
7742
					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
				}
7743
				}
7806
			}
7744
			}
7807
			scope = scope.parent;
7745
			this.startPosition = previousStartPosition;
7746
			this.tokenStart = previousTokenStart;
7808
		}
7747
		}
7748
7749
		methodsFound.addAll(newMethodsFound);
7809
	}
7750
	}
7810
	private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
7811
7751
7812
		if (token == null)
7752
	private void findLocalMethodsFromStaticImports(
7813
			return;
7753
			char[] token,
7754
			Scope scope,
7755
			InvocationSite invocationSite,
7756
			Scope invocationScope,
7757
			boolean exactMatch,
7758
			ObjectVector methodsFound,
7759
			boolean proposeMethod) {
7760
		findFieldsAndMethodsFromStaticImports(
7761
				token,
7762
				scope,
7763
				invocationSite,
7764
				invocationScope,
7765
				exactMatch,
7766
				false,
7767
				new ObjectVector(),
7768
				new ObjectVector(),
7769
				methodsFound,
7770
				false,
7771
				proposeMethod);
7772
	}
7773
	protected void findMembers(
7774
			char[] token,
7775
			ReferenceBinding receiverType,
7776
			Scope scope,
7777
			InvocationSite invocationSite,
7778
			boolean isInsideAnnotationAttribute,
7779
			Binding[] missingElements,
7780
			int[] missingElementsStarts,
7781
			int[] missingElementsEnds,
7782
			boolean missingElementsHaveProblems) {
7814
7783
7815
		// do not propose type if completion token is empty
7784
		if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7816
		boolean skip = false;
7785
			findMemberTypes(
7817
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
7786
					token,
7818
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
7787
					receiverType,
7819
				return;
7788
					scope,
7820
			}
7789
					scope.enclosingSourceType(),
7821
			skip = true;
7790
					false,
7791
					true,
7792
					new ObjectVector(),
7793
					missingElements,
7794
					missingElementsStarts,
7795
					missingElementsEnds,
7796
					missingElementsHaveProblems);
7822
		}
7797
		}
7823
7798
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
7824
		boolean proposeType =
7799
			findClassField(
7825
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
7800
					token,
7826
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
7801
					receiverType,
7827
7802
					scope,
7828
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
7803
					missingElements,
7829
7804
					missingElementsStarts,
7830
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
7805
					missingElementsEnds,
7831
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
7806
					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
		}
7807
		}
7840
7808
7841
		boolean isEmptyPrefix = token.length == 0;
7809
		MethodScope methodScope = null;
7842
7810
		if (!isInsideAnnotationAttribute &&
7843
		if (!skip && proposeType && this.unitScope != null) {
7811
				!this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
7844
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
7812
				((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
7845
			if(outerInvocationType != null) {
7813
				|| ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
7846
				ReferenceBinding temp = outerInvocationType.enclosingType();
7814
			if (token.length > 0) {
7847
				while(temp != null) {
7815
				findKeywords(token, new char[][]{Keywords.THIS}, false, true);
7848
					outerInvocationType = temp;
7816
			} 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();
7817
				int relevance = computeBaseRelevance();
7907
				relevance += computeRelevanceForResolution();
7818
				relevance += computeRelevanceForResolution();
7908
				relevance += computeRelevanceForInterestingProposal();
7819
				relevance += computeRelevanceForInterestingProposal();
7909
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
7820
				relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
7910
				relevance += computeRelevanceForExpectingType(sourceType);
7821
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
7911
				relevance += computeRelevanceForQualification(false);
7822
				relevance += R_NON_INHERITED;
7912
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
7913
7823
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;
7824
				this.noProposal = false;
7924
				if(proposeType) {
7825
				if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
7925
					char[] typeName = sourceType.sourceName();
7826
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
7926
					createTypeProposal(
7827
					proposal.setName(Keywords.THIS);
7927
							sourceType,
7828
					proposal.setCompletion(Keywords.THIS);
7928
							typeName,
7829
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7929
							IAccessRule.K_ACCESSIBLE,
7830
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7930
							typeName,
7831
					proposal.setRelevance(relevance);
7931
							relevance,
7832
					this.requestor.accept(proposal);
7932
							null,
7833
					if (DEBUG) {
7933
							null,
7834
						this.printDebug(proposal);
7934
							null,
7835
					}
7935
							false);
7936
				}
7836
				}
7937
			}
7837
			}
7938
		}
7838
		}
7939
7839
7940
		if(!skip && proposeType) {
7840
		if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
7941
			findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
7841
			findFields(
7842
				token,
7843
				receiverType,
7844
				scope,
7845
				new ObjectVector(),
7846
				new ObjectVector(),
7847
				true,
7848
				invocationSite,
7849
				scope,
7850
				false,
7851
				false,
7852
				missingElements,
7853
				missingElementsStarts,
7854
				missingElementsEnds,
7855
				missingElementsHaveProblems,
7856
				null,
7857
				-1,
7858
				-1);
7942
		}
7859
		}
7943
7860
7944
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
7861
		if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
7945
			if(proposeType && this.expectedTypesPtr > -1) {
7862
			findMethods(
7946
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
7863
				token,
7947
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
7864
				null,
7948
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
7865
				null,
7949
7866
				receiverType,
7950
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
7867
				scope,
7951
							// don't propose type variable if the completion is a constructor ('new |')
7868
				new ObjectVector(),
7952
							continue next;
7869
				true,
7953
						}
7870
				false,
7954
						if (this.options.checkDeprecation &&
7871
				invocationSite,
7955
								refBinding.isViewedAsDeprecated() &&
7872
				scope,
7956
								!scope.isDefinedInSameUnit(refBinding))
7873
				false,
7957
							continue next;
7874
				false,
7958
7875
				false,
7959
						int accessibility = IAccessRule.K_ACCESSIBLE;
7876
				missingElements,
7960
						if(refBinding.hasRestrictedAccess()) {
7877
				missingElementsStarts,
7961
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
7878
				missingElementsEnds,
7962
							if(accessRestriction != null) {
7879
				missingElementsHaveProblems,
7963
								switch (accessRestriction.getProblemId()) {
7880
				null,
7964
									case IProblem.ForbiddenReference:
7881
				-1,
7965
										if (this.options.checkForbiddenReference) {
7882
				-1);
7966
											continue next;
7883
		}
7967
										}
7884
	}
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
7885
7987
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
7886
	private void findMembersFromMissingType(
7887
			final char[] token,
7888
			final long pos,
7889
			TypeBinding resolveType,
7890
			final Scope scope,
7891
			final InvocationSite invocationSite,
7892
			final boolean isInsideAnnotationAttribute) {
7893
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
7894
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
7895
			new MissingTypesGuesser.GuessedTypeRequestor() {
7896
				public void accept(
7897
						TypeBinding guessedType,
7898
						Binding[] missingElements,
7899
						int[] missingElementsStarts,
7900
						int[] missingElementsEnds,
7901
						boolean hasProblems) {
7902
					if (guessedType instanceof ReferenceBinding) {
7903
						findMembers(
7904
								CompletionEngine.this.completionToken,
7905
								(ReferenceBinding)guessedType,
7906
								scope,
7907
								invocationSite,
7908
								isInsideAnnotationAttribute,
7909
								missingElements,
7910
								missingElementsStarts,
7911
								missingElementsEnds,
7912
								hasProblems);
7913
					}
7914
				}
7915
			};
7916
		SingleTypeReference typeRef = new SingleTypeReference(token, pos);
7917
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
7918
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
7919
	}
7988
7920
7989
						// top level types of the current unit are already proposed.
7921
	private void findMemberTypes(
7990
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
7922
		char[] typeName,
7991
							char[] packageName = refBinding.qualifiedPackageName();
7923
		ReferenceBinding receiverType,
7992
							char[] typeName = refBinding.sourceName();
7924
		Scope scope,
7993
							char[] completionName = typeName;
7925
		SourceTypeBinding typeInvocation,
7926
		boolean staticOnly,
7927
		boolean staticFieldsAndMethodOnly,
7928
		boolean fromStaticImport,
7929
		boolean checkQualification,
7930
		boolean proposeAllMemberTypes,
7931
		SourceTypeBinding typeToIgnore,
7932
		ObjectVector typesFound,
7933
		Binding[] missingElements,
7934
		int[] missingElementsStarts,
7935
		int[] missingElementsEnds,
7936
		boolean missingElementsHaveProblems) {
7994
7937
7995
							boolean isQualified = false;
7938
		ReferenceBinding currentType = receiverType;
7996
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
7939
		if (typeName == null)
7997
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
7940
			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
7941
8006
							if(this.assistNodeIsClass) {
7942
		if (this.insideQualifiedReference
8007
								if(!refBinding.isClass()) continue next;
7943
			|| 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
7944
8014
							int relevance = computeBaseRelevance();
7945
			findMemberTypes(
8015
							relevance += computeRelevanceForResolution();
7946
				typeName,
8016
							relevance += computeRelevanceForInterestingProposal();
7947
				currentType.memberTypes(),
8017
							relevance += computeRelevanceForCaseMatching(token, typeName);
7948
				typesFound,
8018
							relevance += computeRelevanceForExpectingType(refBinding);
7949
				receiverType,
8019
							relevance += computeRelevanceForQualification(isQualified);
7950
				typeInvocation,
8020
							relevance += computeRelevanceForRestrictions(accessibility);
7951
				staticOnly,
7952
				staticFieldsAndMethodOnly,
7953
				fromStaticImport,
7954
				checkQualification,
7955
				scope,
7956
				missingElements,
7957
				missingElementsStarts,
7958
				missingElementsEnds,
7959
				missingElementsHaveProblems);
7960
			return;
7961
		}
8021
7962
8022
							if(refBinding.isClass()) {
7963
		ReferenceBinding[] interfacesToVisit = null;
8023
								relevance += computeRelevanceForClass();
7964
		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
7965
8031
							this.noProposal = false;
7966
		do {
8032
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
7967
			ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
8033
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
7968
			if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8034
								proposal.setDeclarationSignature(packageName);
7969
				if (interfacesToVisit == null) {
8035
								proposal.setSignature(getSignature(refBinding));
7970
					interfacesToVisit = itsInterfaces;
8036
								proposal.setPackageName(packageName);
7971
					nextPosition = interfacesToVisit.length;
8037
								proposal.setTypeName(typeName);
7972
				} else {
8038
								proposal.setCompletion(completionName);
7973
					int itsLength = itsInterfaces.length;
8039
								proposal.setFlags(refBinding.modifiers);
7974
					if (nextPosition + itsLength >= interfacesToVisit.length)
8040
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
7975
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8041
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
7976
					nextInterface : for (int a = 0; a < itsLength; a++) {
8042
								proposal.setRelevance(relevance);
7977
						ReferenceBinding next = itsInterfaces[a];
8043
								proposal.setAccessibility(accessibility);
7978
						for (int b = 0; b < nextPosition; b++)
8044
								this.requestor.accept(proposal);
7979
							if (next == interfacesToVisit[b]) continue nextInterface;
8045
								if(DEBUG) {
7980
						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
					}
7981
					}
8063
				}
7982
				}
8064
			}
7983
			}
8065
			if(proposeType) {
7984
8066
				int l = typesFound.size();
7985
			findMemberTypes(
8067
				for (int i = 0; i < l; i++) {
7986
				typeName,
8068
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
7987
				currentType.memberTypes(),
8069
					char[] fullyQualifiedTypeName =
7988
				typesFound,
8070
						CharOperation.concat(
7989
				receiverType,
8071
								typeFound.qualifiedPackageName(),
7990
				typeInvocation,
8072
								typeFound.qualifiedSourceName(),
7991
				staticOnly,
8073
								'.');
7992
				staticFieldsAndMethodOnly,
8074
					this.knownTypes.put(fullyQualifiedTypeName, this);
7993
				fromStaticImport,
8075
				}
7994
				checkQualification,
8076
				int searchFor = IJavaSearchConstants.TYPE;
7995
				scope,
8077
				if(this.assistNodeIsClass) {
7996
				missingElements,
8078
					searchFor = IJavaSearchConstants.CLASS;
7997
				missingElementsStarts,
8079
				} else if(this.assistNodeIsInterface) {
7998
				missingElementsEnds,
8080
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
7999
				missingElementsHaveProblems);
8081
				} else if(this.assistNodeIsEnum) {
8000
8082
					searchFor = IJavaSearchConstants.ENUM;
8001
			currentType = currentType.superclass();
8083
				} else if(this.assistNodeIsAnnotation) {
8002
		} while (currentType != null);
8084
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
8003
8004
		if(proposeAllMemberTypes) {
8005
			ReferenceBinding[] memberTypes = receiverType.memberTypes();
8006
			for (int i = 0; i < memberTypes.length; i++) {
8007
				if(memberTypes[i] != typeToIgnore) {
8008
					findSubMemberTypes(
8009
						typeName,
8010
						memberTypes[i],
8011
						scope,
8012
						typeInvocation,
8013
						staticOnly,
8014
						staticFieldsAndMethodOnly,
8015
						fromStaticImport,
8016
						typesFound);
8085
				}
8017
				}
8086
				this.nameEnvironment.findTypes(
8087
						token,
8088
						proposeAllMemberTypes,
8089
						this.options.camelCaseMatch,
8090
						searchFor,
8091
						this);
8092
				acceptTypes(scope);
8093
			}
8018
			}
8094
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
8019
		}
8095
				this.nameEnvironment.findPackages(token, this);
8020
8021
		if (interfacesToVisit != null) {
8022
			for (int i = 0; i < nextPosition; i++) {
8023
				ReferenceBinding anInterface = interfacesToVisit[i];
8024
				findMemberTypes(
8025
					typeName,
8026
					anInterface.memberTypes(),
8027
					typesFound,
8028
					receiverType,
8029
					typeInvocation,
8030
					staticOnly,
8031
					staticFieldsAndMethodOnly,
8032
					fromStaticImport,
8033
					checkQualification,
8034
					scope,
8035
					missingElements,
8036
					missingElementsStarts,
8037
					missingElementsEnds,
8038
					missingElementsHaveProblems);
8039
8040
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
8041
				if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
8042
					int itsLength = itsInterfaces.length;
8043
					if (nextPosition + itsLength >= interfacesToVisit.length)
8044
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
8045
					nextInterface : for (int a = 0; a < itsLength; a++) {
8046
						ReferenceBinding next = itsInterfaces[a];
8047
						for (int b = 0; b < nextPosition; b++)
8048
							if (next == interfacesToVisit[b]) continue nextInterface;
8049
						interfacesToVisit[nextPosition++] = next;
8050
					}
8051
				}
8096
			}
8052
			}
8097
		}
8053
		}
8098
	}
8054
	}
8099
8055
8100
	private void findTypesAndSubpackages(
8056
	protected void findMemberTypes(
8101
		char[] token,
8057
		char[] typeName,
8102
		PackageBinding packageBinding,
8058
		ReferenceBinding receiverType,
8103
		Scope scope) {
8059
		Scope scope,
8060
		SourceTypeBinding typeInvocation,
8061
		boolean staticOnly,
8062
		boolean staticFieldsAndMethodOnly,
8063
		ObjectVector typesFound,
8064
		Binding[] missingElements,
8065
		int[] missingElementsStarts,
8066
		int[] missingElementsEnds,
8067
		boolean missingElementsHaveProblems)  {
8068
		findMemberTypes(
8069
				typeName,
8070
				receiverType,
8071
				scope,
8072
				typeInvocation,
8073
				staticOnly,
8074
				staticFieldsAndMethodOnly,
8075
				false,
8076
				false,
8077
				false,
8078
				null,
8079
				typesFound,
8080
				missingElements,
8081
				missingElementsStarts,
8082
				missingElementsEnds,
8083
				missingElementsHaveProblems);
8084
	}
8085
		// Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
8086
	private void findMemberTypes(
8087
		char[] typeName,
8088
		ReferenceBinding[] memberTypes,
8089
		ObjectVector typesFound,
8090
		ReferenceBinding receiverType,
8091
		SourceTypeBinding invocationType,
8092
		boolean staticOnly,
8093
		boolean staticFieldsAndMethodOnly,
8094
		boolean fromStaticImport,
8095
		boolean checkQualification,
8096
		Scope scope,
8097
		Binding[] missingElements,
8098
		int[] missingElementsStarts,
8099
		int[] missingElementsEnds,
8100
		boolean missingElementsHaveProblems) {
8104
8101
8105
		boolean proposeType =
8102
		// Inherited member types which are hidden by subclasses are filtered out
8106
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
8103
		// No visibility checks can be performed without the scope & invocationSite
8107
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
8104
		int typeLength = typeName.length;
8105
		next : for (int m = memberTypes.length; --m >= 0;) {
8106
			ReferenceBinding memberType = memberTypes[m];
8107
			//		if (!wantClasses && memberType.isClass()) continue next;
8108
			//		if (!wantInterfaces && memberType.isInterface()) continue next;
8108
8109
8109
		char[] qualifiedName =
8110
			if (staticOnly && !memberType.isStatic()) continue next;
8110
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
8111
8111
8112
		if (token == null || token.length == 0) {
8112
			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
8113
8123
		this.qualifiedCompletionToken = qualifiedName;
8114
			if (typeLength > memberType.sourceName.length)
8115
				continue next;
8124
8116
8125
		if (proposeType && this.unitScope != null) {
8117
			if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
8126
			int typeLength = qualifiedName.length;
8118
					&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
8127
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
8119
				continue next;
8128
8120
8129
			for (int i = 0, length = types.length; i < length; i++) {
8121
			if (this.options.checkDeprecation &&
8130
				SourceTypeBinding sourceType = types[i];
8122
					memberType.isViewedAsDeprecated() &&
8123
					!scope.isDefinedInSameUnit(memberType))
8124
				continue next;
8131
8125
8132
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
8126
			if (this.options.checkVisibility) {
8127
				if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
8128
					continue next;
8129
				} else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
8130
					continue next;
8131
				}
8132
			}
8133
8133
8134
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
8134
			if (this.insideQualifiedReference &&
8135
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
8135
					receiverType.isParameterizedType() &&
8136
				if (typeLength > qualifiedSourceTypeName.length) continue;
8136
					memberType.isStatic()) {
8137
				if (!(packageBinding == sourceType.getPackage())) continue;
8137
				continue next;
8138
			}
8138
8139
8139
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
8140
			for (int i = typesFound.size; --i >= 0;) {
8140
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
8141
				ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
8141
8142
8142
				if (this.options.checkDeprecation &&
8143
				if (memberType == otherType)
8143
						sourceType.isViewedAsDeprecated() &&
8144
					continue next;
8144
						!scope.isDefinedInSameUnit(sourceType))
8145
					continue;
8146
8145
8147
				int accessibility = IAccessRule.K_ACCESSIBLE;
8146
				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
8147
8168
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
8148
					if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
8149
						continue next;
8169
8150
8170
				int relevance = computeBaseRelevance();
8151
					if (otherType.enclosingType().isInterface())
8171
				relevance += computeRelevanceForResolution();
8152
						if (memberType.enclosingType()
8172
				relevance += computeRelevanceForInterestingProposal();
8153
							.implementsInterface(otherType.enclosingType(), true))
8173
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
8154
							continue next;
8174
				relevance += computeRelevanceForExpectingType(sourceType);
8175
				relevance += computeRelevanceForQualification(false);
8176
				relevance += computeRelevanceForRestrictions(accessibility);
8177
8155
8178
				if (sourceType.isAnnotationType()) {
8156
					if (memberType.enclosingType().isInterface())
8179
					relevance += computeRelevanceForAnnotation();
8157
						if (otherType.enclosingType()
8180
				} else if (sourceType.isInterface()) {
8158
							.implementsInterface(memberType.enclosingType(), true))
8181
					relevance += computeRelevanceForInterface();
8159
							continue next;
8182
				} else if (sourceType.isClass()) {
8183
					relevance += computeRelevanceForClass();
8184
					relevance += computeRelevanceForException(sourceType.sourceName);
8185
				}
8160
				}
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
			}
8161
			}
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
8162
8260
							if (typeLength > typeBinding.sourceName.length)	continue;
8163
			typesFound.add(memberType);
8261
8164
8262
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
8165
			if(!this.insideQualifiedReference) {
8263
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
8166
				if(this.assistNodeIsClass) {
8167
					if(!memberType.isClass()) continue next;
8168
				} else if(this.assistNodeIsInterface) {
8169
					if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
8170
				} else if (this.assistNodeIsAnnotation) {
8171
					if(!memberType.isAnnotationType()) continue next;
8172
				}
8173
			}
8264
8174
8265
							if (typesFound.contains(typeBinding))  continue;
8175
			char[] completionName = memberType.sourceName();
8266
8176
8267
							typesFound.add(typeBinding);
8177
			boolean isQualified = false;
8178
			if(checkQualification && !fromStaticImport) {
8179
				char[] memberPackageName = memberType.qualifiedPackageName();
8180
				char[] memberTypeName = memberType.sourceName();
8181
				char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
8182
				if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
8183
					if (memberPackageName == null || memberPackageName.length == 0)
8184
						if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
8185
							break next; // ignore types from the default package from outside it
8186
					isQualified = true;
8187
					completionName =
8188
						CharOperation.concat(
8189
								memberPackageName,
8190
								CharOperation.concat(
8191
										memberEnclosingTypeNames,
8192
										memberTypeName,
8193
										'.'),
8194
								'.');
8195
				}
8196
			}
8268
8197
8269
							if(this.assistNodeIsClass) {
8198
			int relevance = computeBaseRelevance();
8270
								if(!typeBinding.isClass()) continue;
8199
			relevance += computeRelevanceForResolution();
8271
							} else if(this.assistNodeIsInterface) {
8200
			relevance += computeRelevanceForInterestingProposal();
8272
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
8201
			relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
8273
							} else if (this.assistNodeIsAnnotation) {
8202
			relevance += computeRelevanceForExpectingType(memberType);
8274
								if(!typeBinding.isAnnotationType()) continue;
8203
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8275
							}
8204
			if(!this.insideQualifiedReference) {
8205
				relevance += computeRelevanceForQualification(isQualified);
8206
			}
8207
			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
8208
8277
							int relevance = computeBaseRelevance();
8209
			if (memberType.isAnnotationType()) {
8278
							relevance += computeRelevanceForResolution();
8210
				relevance += computeRelevanceForAnnotation();
8279
							relevance += computeRelevanceForInterestingProposal();
8211
				relevance += computeRelevanceForAnnotationTarget(memberType);
8280
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
8212
			} else if (memberType.isClass()) {
8281
							relevance += computeRelevanceForExpectingType(typeBinding);
8213
				relevance += computeRelevanceForClass();
8282
							relevance += computeRelevanceForQualification(false);
8214
				relevance += computeRelevanceForException(memberType.sourceName);
8283
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
8215
			} else if(memberType.isEnum()) {
8216
				relevance += computeRelevanceForEnum();
8217
			} else if(memberType.isInterface()) {
8218
				relevance += computeRelevanceForInterface();
8219
			}
8284
8220
8285
							if (typeBinding.isClass()) {
8221
			if (missingElements != null) {
8286
								relevance += computeRelevanceForClass();
8222
				relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
8287
								relevance += computeRelevanceForException(typeBinding.sourceName);
8223
			}
8288
							} else if(typeBinding.isEnum()) {
8289
								relevance += computeRelevanceForEnum();
8290
							} else if(typeBinding.isInterface()) {
8291
								relevance += computeRelevanceForInterface();
8292
							}
8293
8224
8294
							this.noProposal = false;
8225
			this.noProposal = false;
8295
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8226
			createTypeProposal(
8296
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
8227
					memberType,
8297
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
8228
					memberType.qualifiedSourceName(),
8298
								proposal.setSignature(getSignature(typeBinding));
8229
					IAccessRule.K_ACCESSIBLE,
8299
								proposal.setPackageName(typeBinding.qualifiedPackageName());
8230
					completionName,
8300
								proposal.setTypeName(typeBinding.qualifiedSourceName());
8231
					relevance,
8301
								proposal.setCompletion(typeBinding.sourceName());
8232
					missingElements,
8302
								proposal.setFlags(typeBinding.modifiers);
8233
					missingElementsStarts,
8303
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8234
					missingElementsEnds,
8304
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8235
					missingElementsHaveProblems);
8305
								proposal.setRelevance(relevance);
8236
		}
8306
								this.requestor.accept(proposal);
8237
	}
8307
								if(DEBUG) {
8238
	private void findMemberTypesFromMissingType(
8308
									this.printDebug(proposal);
8239
			char[] typeName,
8309
								}
8240
			final long pos,
8310
							}
8241
			final Scope scope)  {
8311
						}
8242
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8243
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8244
			new MissingTypesGuesser.GuessedTypeRequestor() {
8245
				public void accept(
8246
						TypeBinding guessedType,
8247
						Binding[] missingElements,
8248
						int[] missingElementsStarts,
8249
						int[] missingElementsEnds,
8250
						boolean hasProblems) {
8251
					if (guessedType instanceof ReferenceBinding) {
8252
						findMemberTypes(
8253
								CompletionEngine.this.completionToken,
8254
								(ReferenceBinding)guessedType,
8255
								scope,
8256
								scope.enclosingSourceType(),
8257
								false,
8258
								false,
8259
								new ObjectVector(),
8260
								missingElements,
8261
								missingElementsStarts,
8262
								missingElementsEnds,
8263
								hasProblems);
8312
					}
8264
					}
8313
				}
8265
				}
8314
			}
8266
			};
8315
		}
8267
		SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
8268
		typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
8269
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8316
	}
8270
	}
8317
	private void findVariablesAndMethods(
8271
	
8318
		char[] token,
8272
	private void findMemberTypesFromMissingType(
8273
			TypeReference typeRef,
8274
			final long pos,
8275
			final Scope scope)  {
8276
		MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
8277
		MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
8278
			new MissingTypesGuesser.GuessedTypeRequestor() {
8279
				public void accept(
8280
						TypeBinding guessedType,
8281
						Binding[] missingElements,
8282
						int[] missingElementsStarts,
8283
						int[] missingElementsEnds,
8284
						boolean hasProblems) {
8285
					if (guessedType instanceof ReferenceBinding) {
8286
						findMemberTypes(
8287
								CompletionEngine.this.completionToken,
8288
								(ReferenceBinding)guessedType,
8289
								scope,
8290
								scope.enclosingSourceType(),
8291
								false,
8292
								false,
8293
								new ObjectVector(),
8294
								missingElements,
8295
								missingElementsStarts,
8296
								missingElementsEnds,
8297
								hasProblems);
8298
					}
8299
				}
8300
			};
8301
		missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
8302
	}
8303
8304
	private void findMethodDeclarations(
8305
		char[] selector,
8306
		ReferenceBinding receiverType,
8319
		Scope scope,
8307
		Scope scope,
8320
		InvocationSite invocationSite,
8308
		ObjectVector methodsFound,
8321
		Scope invocationScope,
8309
		Binding[] missingElements,
8322
		boolean insideTypeAnnotation,
8310
		int[] missingElementsStarts,
8323
		boolean insideAnnotationAttribute) {
8311
		int[] missingElementsEnds,
8312
		boolean missingElementsHaveProblems) {
8324
8313
8325
		if (token == null)
8314
		if (selector == null) {
8326
			return;
8315
			return;
8316
		}
8327
8317
8328
		// Should local variables hide fields from the receiver type or any of its enclosing types?
8318
		MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
8329
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
8319
		if (receiverTypeMethods != null){
8330
8320
			for (int i = 0; i < receiverTypeMethods.length; i++) {
8331
		boolean staticsOnly = false;
8321
				if(!receiverTypeMethods[i].isDefaultAbstract()) {
8332
		// need to know if we're in a static context (or inside a constructor)
8322
					methodsFound.add(receiverTypeMethods[i]);
8333
		int tokenLength = token.length;
8323
				}
8334
8324
			}
8335
		ObjectVector localsFound = new ObjectVector();
8325
		}
8336
		ObjectVector fieldsFound = new ObjectVector();
8337
		ObjectVector methodsFound = new ObjectVector();
8338
8326
8339
		Scope currentScope = scope;
8327
		ReferenceBinding currentType = receiverType;
8328
		
8329
		findInterfacesMethodDeclarations(
8330
			selector,
8331
			receiverType,
8332
			currentType.superInterfaces(),
8333
			scope,
8334
			methodsFound,
8335
			missingElements,
8336
			missingElementsStarts,
8337
			missingElementsEnds,
8338
			missingElementsHaveProblems);
8339
		
8340
		if (receiverType.isInterface()) {
8341
			currentType = scope.getJavaLangObject();
8342
		} else {
8343
			currentType = receiverType.superclass();
8344
		}
8345
		
8346
		boolean hasPotentialDefaultAbstractMethods = true;
8347
		while (currentType != null) {
8340
8348
8341
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
8349
			MethodBinding[] methods = currentType.availableMethods();
8342
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
8350
			if (methods != null) {
8351
				findLocalMethodDeclarations(
8352
					selector,
8353
					methods,
8354
					scope,
8355
					methodsFound,
8356
					false,
8357
					receiverType);
8358
			}
8343
8359
8344
				switch (currentScope.kind) {
8360
			if (hasPotentialDefaultAbstractMethods &&
8361
					(currentType.isAbstract() ||
8362
							currentType.isTypeVariable() ||
8363
							currentType.isIntersectionType() ||
8364
							currentType.isEnum())){
8345
8365
8346
					case Scope.METHOD_SCOPE :
8366
				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
8367
8351
					//$FALL-THROUGH$
8368
				findInterfacesMethodDeclarations(
8352
					case Scope.BLOCK_SCOPE :
8369
					selector,
8353
						BlockScope blockScope = (BlockScope) currentScope;
8370
					receiverType,
8371
					superInterfaces,
8372
					scope,
8373
					methodsFound,
8374
					missingElements,
8375
					missingElementsStarts,
8376
					missingElementsEnds,
8377
					missingElementsHaveProblems);
8378
			} else {
8379
				hasPotentialDefaultAbstractMethods = false;
8380
			}
8381
			currentType = currentType.superclass();
8382
		}
8383
	}
8384
	
8385
	private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
8386
		TypeBinding erasure =  method.declaringClass.erasure();
8387
		if(!(erasure instanceof ReferenceBinding)) return null;
8354
8388
8355
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
8389
		char[][] parameterNames = null;
8356
							LocalVariableBinding local = blockScope.locals[i];
8357
8390
8358
							if (local == null)
8391
		int length = parameterTypeNames.length;
8359
								break next;
8360
8392
8361
							if (tokenLength > local.name.length)
8393
		if (length == 0){
8362
								continue next;
8394
			return CharOperation.NO_CHAR_CHAR;
8395
		}
8396
		// look into the corresponding unit if it is available
8397
		if (erasure instanceof SourceTypeBinding){
8398
			SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
8363
8399
8364
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
8400
			if (sourceType.scope != null){
8365
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
8401
				TypeDeclaration parsedType;
8366
								continue next;
8367
8402
8368
							if (local.isSecret())
8403
				if ((parsedType = sourceType.scope.referenceContext) != null){
8369
								continue next;
8404
					AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
8370
8405
8371
							for (int f = 0; f < localsFound.size; f++) {
8406
					if (methodDecl != null){
8372
								LocalVariableBinding otherLocal =
8407
						Argument[] arguments = methodDecl.arguments;
8373
									(LocalVariableBinding) localsFound.elementAt(f);
8408
						parameterNames = new char[length][];
8374
								if (CharOperation.equals(otherLocal.name, local.name, true))
8375
									continue next;
8376
							}
8377
							localsFound.add(local);
8378
8409
8379
							int relevance = computeBaseRelevance();
8410
						for(int i = 0 ; i < length ; i++){
8380
							relevance += computeRelevanceForResolution();
8411
							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
						}
8412
						}
8415
						break;
8413
					}
8416
8417
					case Scope.COMPILATION_UNIT_SCOPE :
8418
						break done1;
8419
				}
8414
				}
8420
				currentScope = currentScope.parent;
8421
			}
8415
			}
8422
		}
8416
		}
8417
		// look into the model
8418
		if(parameterNames == null){
8423
8419
8424
		boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
8420
			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
8421
8433
				switch (currentScope.kind) {
8422
			char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
8434
					case Scope.METHOD_SCOPE :
8423
			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
8424
8498
					case Scope.COMPILATION_UNIT_SCOPE :
8425
			ISourceType sourceType = null;
8499
						break done2;
8426
			if(type != null) {
8427
				if(type instanceof ISourceType) {
8428
					sourceType = (ISourceType) type;
8429
				}
8430
			} else {
8431
				NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
8432
				if(answer != null && answer.isSourceType()) {
8433
					sourceType = answer.getSourceTypes()[0];
8434
					this.typeCache.put(compoundName, sourceType);
8500
				}
8435
				}
8501
				currentScope = currentScope.parent;
8502
			}
8436
			}
8503
8437
8504
			findFieldsAndMethodsFromStaticImports(
8438
			if(sourceType != null) {
8505
					token,
8439
				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
8440
8517
			if (this.assistNodeInJavadoc == 0) {
8441
				String[] parameterTypeSignatures = new String[length];
8518
				// search in favorites import
8442
				for (int i = 0; i < length; i++) {
8519
				findFieldsAndMethodsFromFavorites(
8443
					parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
8520
						token,
8444
				}
8521
						scope,
8445
				IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
8522
						invocationSite,
8446
				IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
8523
						invocationScope,
8524
						localsFound,
8525
						fieldsFound,
8526
						methodsFound);
8527
			}
8528
8447
8529
			findEnumConstantsFromExpectedTypes(
8448
				if(foundMethods != null) {
8530
					token,
8449
					int len = foundMethods.length;
8531
					invocationScope,
8450
					if(len == 1) {
8532
					fieldsFound);
8451
						try {
8533
		}
8452
							SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
8534
	}
8453
							parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
8535
8454
						} catch (JavaModelException e) {
8536
	private void findLocalMethodsFromStaticImports(
8455
							// 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
						}
8456
						}
8664
					}
8457
					}
8665
				}
8458
				}
8666
			}
8459
			}
8667
		}
8460
		}
8461
		return parameterNames;
8668
	}
8462
	}
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
8463
8675
			final ArrayList proposedNames = new ArrayList();
8464
	private void findMethods(
8465
		char[] selector,
8466
		TypeBinding[] typeArgTypes,
8467
		TypeBinding[] argTypes,
8468
		ReferenceBinding receiverType,
8469
		Scope scope,
8470
		ObjectVector methodsFound,
8471
		boolean onlyStaticMethods,
8472
		boolean exactMatch,
8473
		InvocationSite invocationSite,
8474
		Scope invocationScope,
8475
		boolean implicitCall,
8476
		boolean superCall,
8477
		boolean canBePrefixed,
8478
		Binding[] missingElements,
8479
		int[] missingElementsStarts,
8480
		int[] missingElementsEnds,
8481
		boolean missingElementsHaveProblems,
8482
		char[] castedReceiver,
8483
		int receiverStart,
8484
		int receiverEnd) {
8676
8485
8677
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8486
		boolean notInJavadoc = this.assistNodeInJavadoc == 0;
8678
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8487
		if (selector == null && notInJavadoc) {
8679
					public void acceptName(char[] name) {
8488
			return;
8680
						int relevance = computeBaseRelevance();
8489
		}
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
8490
8688
						// accept result
8491
		ReferenceBinding currentType = receiverType;
8689
						CompletionEngine.this.noProposal = false;
8492
		if (notInJavadoc) {
8690
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8493
			if (receiverType.isInterface()) {
8691
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8494
				findInterfacesMethods(
8692
							proposal.setSignature(getSignature(type.resolvedType));
8495
					selector,
8693
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
8496
					typeArgTypes,
8694
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
8497
					argTypes,
8695
							proposal.setName(name);
8498
					receiverType,
8696
							proposal.setCompletion(name);
8499
					new ReferenceBinding[]{currentType},
8697
							//proposal.setFlags(Flags.AccDefault);
8500
					scope,
8698
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8501
					methodsFound,
8699
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8502
					onlyStaticMethods,
8700
							proposal.setRelevance(relevance);
8503
					exactMatch,
8701
							CompletionEngine.this.requestor.accept(proposal);
8504
					invocationSite,
8702
							if(DEBUG) {
8505
					invocationScope,
8703
								CompletionEngine.this.printDebug(proposal);
8506
					implicitCall,
8704
							}
8507
					superCall,
8705
						}
8508
					canBePrefixed,
8706
						proposedNames.add(name);
8509
					missingElements,
8707
					}
8510
					missingElementsStarts,
8708
				};
8511
					missingElementsEnds,
8512
					missingElementsHaveProblems,
8513
					castedReceiver,
8514
					receiverStart,
8515
					receiverEnd);
8709
8516
8710
			ReferenceContext referenceContext = scope.referenceContext();
8517
				currentType = scope.getJavaLangObject();
8711
			if (referenceContext instanceof AbstractMethodDeclaration) {
8518
			}
8712
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8519
		}
8520
		boolean hasPotentialDefaultAbstractMethods = true;
8521
		while (currentType != null) {
8713
8522
8714
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8523
			MethodBinding[] methods = currentType.availableMethods();
8715
				nameFinder.find(
8524
			if (methods != null) {
8716
						this.completionToken,
8525
				findLocalMethods(
8717
						md,
8526
					selector,
8718
						variable.declarationSourceEnd + 1,
8527
					typeArgTypes,
8719
						discouragedNames,
8528
					argTypes,
8720
						nameRequestor);
8529
					methods,
8721
			} else if (referenceContext instanceof TypeDeclaration) {
8530
					scope,
8722
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
8531
					methodsFound,
8723
				FieldDeclaration[] fields = typeDeclaration.fields;
8532
					onlyStaticMethods,
8724
				if (fields != null) {
8533
					exactMatch,
8725
					done : for (int i = 0; i < fields.length; i++) {
8534
					receiverType,
8726
						if (fields[i] instanceof Initializer) {
8535
					invocationSite,
8727
							Initializer initializer = (Initializer) fields[i];
8536
					invocationScope,
8728
							if (initializer.bodyStart <= variable.sourceStart &&
8537
					implicitCall,
8729
									variable.sourceStart < initializer.bodyEnd) {
8538
					superCall,
8730
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8539
					canBePrefixed,
8731
								nameFinder.find(
8540
					missingElements,
8732
										this.completionToken,
8541
					missingElementsStarts,
8733
										initializer,
8542
					missingElementsEnds,
8734
										typeDeclaration.scope,
8543
					missingElementsHaveProblems,
8735
										variable.declarationSourceEnd + 1,
8544
					castedReceiver,
8736
										discouragedNames,
8545
					receiverStart,
8737
										nameRequestor);
8546
					receiverEnd);
8738
								break done;
8547
			}
8739
							}
8548
8740
						}
8549
			if (hasPotentialDefaultAbstractMethods &&
8550
					(currentType.isAbstract() ||
8551
							currentType.isTypeVariable() ||
8552
							currentType.isIntersectionType() ||
8553
							currentType.isEnum())){
8554
8555
				ReferenceBinding[] superInterfaces = currentType.superInterfaces();
8556
				if (superInterfaces != null && currentType.isIntersectionType()) {
8557
					for (int i = 0; i < superInterfaces.length; i++) {
8558
						superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
8741
					}
8559
					}
8742
				}
8560
				}
8743
			}
8744
8561
8745
			int proposedNamesCount = proposedNames.size();
8562
				findInterfacesMethods(
8746
			if (proposedNamesCount > 0) {
8563
					selector,
8747
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8564
					typeArgTypes,
8565
					argTypes,
8566
					receiverType,
8567
					superInterfaces,
8568
					scope,
8569
					methodsFound,
8570
					onlyStaticMethods,
8571
					exactMatch,
8572
					invocationSite,
8573
					invocationScope,
8574
					implicitCall,
8575
					superCall,
8576
					canBePrefixed,
8577
					missingElements,
8578
					missingElementsStarts,
8579
					missingElementsEnds,
8580
					missingElementsHaveProblems,
8581
					castedReceiver,
8582
					receiverStart,
8583
					receiverEnd);
8584
			} else {
8585
				hasPotentialDefaultAbstractMethods = false;
8748
			}
8586
			}
8587
			currentType = currentType.superclass();
8749
		}
8588
		}
8750
8751
		return null;
8752
	}
8589
	}
8753
8590
8754
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
8591
	private void findNestedTypes(
8755
		final ArrayList proposedNames = new ArrayList();
8592
		char[] typeName,
8756
8593
		SourceTypeBinding currentType,
8757
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8594
		Scope scope,
8758
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8595
		boolean proposeAllMemberTypes,
8759
				public void acceptName(char[] name) {
8596
		ObjectVector typesFound) {
8760
					CompletionEngine.this.acceptUnresolvedName(name);
8597
		
8761
					proposedNames.add(name);
8598
		if (typeName == null)
8762
				}
8599
			return;
8763
			};
8764
8600
8765
		ReferenceContext referenceContext = scope.referenceContext();
8601
		int typeLength = typeName.length;
8766
		if (referenceContext instanceof AbstractMethodDeclaration) {
8767
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8768
8602
8769
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8603
		SourceTypeBinding nextTypeToIgnore = null;
8770
			nameFinder.findAfter(
8604
		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
8605
8803
		int proposedNamesCount = proposedNames.size();
8606
			switch (scope.kind) {
8804
		if (proposedNamesCount > 0) {
8805
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8806
		}
8807
8607
8808
		return null;
8608
				case Scope.METHOD_SCOPE :
8809
	}
8609
				case Scope.BLOCK_SCOPE :
8610
					BlockScope blockScope = (BlockScope) scope;
8810
8611
8811
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
8612
					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
8613
8823
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
8614
						if (blockScope.subscopes[i] instanceof ClassScope) {
8824
		final ArrayList proposedNames = new ArrayList();
8615
							SourceTypeBinding localType =
8616
								((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
8825
8617
8826
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
8618
							if (!localType.isAnonymousType()) {
8827
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
8619
								if (isForbidden(localType))
8828
				public void acceptName(char[] name) {
8620
									continue next;
8829
					CompletionEngine.this.acceptUnresolvedName(name);
8830
					proposedNames.add(name);
8831
				}
8832
			};
8833
8621
8834
		BlockScope upperScope = scope;
8622
								if (typeLength > localType.sourceName.length)
8835
		while (upperScope.enclosingMethodScope() != null) {
8623
									continue next;
8836
			upperScope = upperScope.enclosingMethodScope();
8624
								if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
8837
		}
8625
										&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
8626
									continue next;
8838
8627
8839
		ReferenceContext referenceContext = upperScope.referenceContext();
8628
								for (int j = typesFound.size; --j >= 0;) {
8840
		if (referenceContext instanceof AbstractMethodDeclaration) {
8629
									ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
8841
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
8842
8630
8843
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8631
									if (localType == otherType)
8844
			nameFinder.findBefore(
8632
										continue next;
8845
					this.completionToken,
8633
								}
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
8634
8635
								if(this.assistNodeIsClass) {
8636
									if(!localType.isClass()) continue next;
8637
								} else if(this.assistNodeIsInterface) {
8638
									if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
8639
								} else if (this.assistNodeIsAnnotation) {
8640
									if(!localType.isAnnotationType()) continue next;
8641
								}
8856
8642
8857
			done : {
8643
								int relevance = computeBaseRelevance();
8858
				FieldDeclaration[] fields = typeDeclaration.fields;
8644
								relevance += computeRelevanceForResolution();
8859
				if (fields != null) {
8645
								relevance += computeRelevanceForInterestingProposal();
8860
					for (int i = 0; i < fields.length; i++) {
8646
								relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
8861
						if (fields[i] instanceof Initializer) {
8647
								relevance += computeRelevanceForExpectingType(localType);
8862
							Initializer initializer = (Initializer) fields[i];
8648
								relevance += computeRelevanceForException(localType.sourceName);
8863
							if (initializer.block.sourceStart <= recordTo &&
8649
								relevance += computeRelevanceForClass();
8864
									recordTo < initializer.bodyEnd) {
8650
								relevance += computeRelevanceForQualification(false);
8651
								relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
8652
								relevance += computeRelevanceForAnnotationTarget(localType);
8865
8653
8866
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
8654
								this.noProposal = false;
8867
								nameFinder.findBefore(
8655
								if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
8868
										this.completionToken,
8656
									createTypeProposal(
8869
										typeDeclaration.scope,
8657
											localType,
8870
										typeDeclaration.scope,
8658
											localType.sourceName,
8871
										initializer.block.sourceStart,
8659
											IAccessRule.K_ACCESSIBLE,
8872
										recordTo,
8660
											localType.sourceName,
8873
										parseTo,
8661
											relevance,
8874
										discouragedNames,
8662
											null,
8875
										nameRequestor);
8663
											null,
8876
								break done;
8664
											null,
8665
											false);
8666
								}
8877
							}
8667
							}
8878
						}
8668
						}
8879
					}
8669
					}
8880
				}
8670
					break;
8881
			}
8882
		}
8883
8884
		int proposedNamesCount = proposedNames.size();
8885
		if (proposedNamesCount > 0) {
8886
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
8887
		}
8888
8671
8889
		return null;
8672
				case Scope.CLASS_SCOPE :
8890
	}
8673
					SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
8891
		// Helper method for private void findVariableNames(char[] name, TypeReference type )
8674
					findMemberTypes(
8892
	private void findVariableName(
8675
							typeName,
8893
			char[] token,
8676
							enclosingSourceType,
8894
			char[] qualifiedPackageName,
8677
							scope,
8895
			char[] qualifiedSourceName,
8678
							currentType,
8896
			char[] sourceName,
8679
							false,
8897
			final TypeBinding typeBinding,
8680
							false,
8898
			char[][] discouragedNames,
8681
							false,
8899
			final char[][] forbiddenNames,
8682
							false,
8900
			int dim,
8683
							proposeAllMemberTypes,
8901
			int kind,
8684
							nextTypeToIgnore,
8902
			int modifiers){
8685
							typesFound,
8903
		findVariableName(
8686
							null,
8904
				token,
8687
							null,
8905
				qualifiedPackageName,
8688
							null,
8906
				qualifiedSourceName,
8689
							false);
8907
				sourceName,
8690
					nextTypeToIgnore = enclosingSourceType;
8908
				typeBinding,
8691
					if (typeLength == 0)
8909
				discouragedNames,
8692
						return; // do not search outside the class scope if no prefix was provided
8910
				forbiddenNames,
8693
					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
8694
8932
		// compute variable name for non base type
8695
				case Scope.COMPILATION_UNIT_SCOPE :
8933
		final char[] displayName;
8696
					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
			}
8697
			}
8946
		} else {
8698
			scope = scope.parent;
8947
			displayName = typeBinding.qualifiedSourceName();
8948
		}
8699
		}
8700
	}
8949
8701
8950
		final char[] t = token;
8702
	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
8703
8964
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
8704
		this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
8965
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
8705
		if (this.completionToken.length == 0)
8966
			}
8706
			return;
8967
8707
8968
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
8708
		setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
8969
				accept(name, 0, reusedCharacters);
8709
		long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
8970
			}
8710
		setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
8971
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
8711
		this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
8972
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
8712
	}
8973
				for (int i = 0; i < l; i++) {
8974
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
8975
				}
8976
8713
8977
				if (CharOperation.prefixEquals(t, name, false)) {
8714
	private void findParameterizedType(TypeReference ref, Scope scope) {
8978
					int relevance = computeBaseRelevance();
8715
		ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
8979
					relevance += computeRelevanceForInterestingProposal();
8716
		if(refBinding != null) {
8980
					relevance += computeRelevanceForCaseMatching(t, name);
8717
			if (this.options.checkDeprecation &&
8981
					relevance += prefixAndSuffixRelevance;
8718
					refBinding.isViewedAsDeprecated() &&
8982
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
8719
					!scope.isDefinedInSameUnit(refBinding))
8983
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
8720
				return;
8984
8721
8985
					// accept result
8722
			int accessibility = IAccessRule.K_ACCESSIBLE;
8986
					CompletionEngine.this.noProposal = false;
8723
			if(refBinding.hasRestrictedAccess()) {
8987
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
8724
				AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
8988
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
8725
				if(accessRestriction != null) {
8989
						proposal.setSignature(getSignature(typeBinding));
8726
					switch (accessRestriction.getProblemId()) {
8990
						proposal.setPackageName(q);
8727
						case IProblem.ForbiddenReference:
8991
						proposal.setTypeName(displayName);
8728
							if (this.options.checkForbiddenReference) {
8992
						proposal.setName(name);
8729
								return;
8993
						proposal.setCompletion(name);
8730
							}
8994
						//proposal.setFlags(Flags.AccDefault);
8731
							accessibility = IAccessRule.K_NON_ACCESSIBLE;
8995
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
8732
							break;
8996
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
8733
						case IProblem.DiscouragedReference:
8997
						proposal.setRelevance(relevance);
8734
							if (this.options.checkDiscouragedReference) {
8998
						CompletionEngine.this.requestor.accept(proposal);
8735
								return;
8999
						if(DEBUG) {
8736
							}
9000
							CompletionEngine.this.printDebug(proposal);
8737
							accessibility = IAccessRule.K_DISCOURAGED;
9001
						}
8738
							break;
9002
					}
8739
					}
9003
				}
8740
				}
9004
			}
8741
			}
9005
		};
9006
8742
9007
		switch (kind) {
8743
			int relevance = computeBaseRelevance();
9008
			case FIELD :
8744
			relevance += computeRelevanceForResolution();
9009
				InternalNamingConventions.suggestFieldNames(
8745
			relevance += computeRelevanceForInterestingProposal();
9010
					this.javaProject,
8746
			relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
9011
					qualifiedPackageName,
8747
			relevance += computeRelevanceForExpectingType(refBinding);
9012
					qualifiedSourceName,
8748
			relevance += computeRelevanceForQualification(false);
9013
					dim,
8749
			relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
9014
					modifiers,
8750
9015
					token,
8751
			if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9016
					discouragedNames,
8752
				createTypeProposal(
9017
					namingRequestor);
8753
						refBinding,
9018
				break;
8754
						refBinding.qualifiedSourceName(),
9019
			case LOCAL :
8755
						IAccessRule.K_ACCESSIBLE,
9020
				InternalNamingConventions.suggestLocalVariableNames(
8756
						CharOperation.NO_CHAR,
9021
					this.javaProject,
8757
						relevance,
9022
					qualifiedPackageName,
8758
						null,
9023
					qualifiedSourceName,
8759
						null,
9024
					dim,
8760
						null,
9025
					token,
8761
						false);
9026
					discouragedNames,
8762
			}
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
		}
8763
		}
9040
	}
8764
	}
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
8765
9053
		findVariableName(
8766
	private void findSubMemberTypes(
9054
				token,
8767
		char[] typeName,
9055
				qualifiedPackageName,
8768
		ReferenceBinding receiverType,
9056
				qualifiedSourceName,
8769
		Scope scope,
9057
				sourceName,
8770
		SourceTypeBinding typeInvocation,
9058
				typeBinding,
8771
		boolean staticOnly,
9059
				discouragedNames,
8772
		boolean staticFieldsAndMethodOnly,
9060
				forbiddenNames,
8773
		boolean fromStaticImport,
9061
				false,
8774
		ObjectVector typesFound) {
9062
				1,
9063
				kind,
9064
				modifiers);
9065
	}
9066
8775
9067
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
8776
		ReferenceBinding currentType = receiverType;
9068
		if(type != null &&
8777
		if (typeName == null || typeName.length == 0)
9069
			type.resolvedType != null) {
8778
			return;
9070
			TypeBinding tb = type.resolvedType;
9071
8779
9072
			if (tb.problemId() == ProblemReasons.NoError &&
8780
		if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
9073
					tb != Scope.getBaseType(VOID)) {
8781
9074
				findVariableName(
8782
		findMemberTypes(
9075
					name,
8783
				typeName,
9076
					tb.leafComponentType().qualifiedPackageName(),
8784
				currentType.memberTypes(),
9077
					tb.leafComponentType().qualifiedSourceName(),
8785
				typesFound,
9078
					tb.leafComponentType().sourceName(),
8786
				receiverType,
9079
					tb,
8787
				typeInvocation,
9080
					discouragedNames,
8788
				staticOnly,
9081
					forbiddenNames,
8789
				staticFieldsAndMethodOnly,
9082
					type.dimensions(),
8790
				fromStaticImport,
9083
					kind,
8791
				true,
9084
					modifiers);
8792
				scope,
9085
				
8793
				null,
9086
				if (tb.isParameterizedType() &&
8794
				null,
9087
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
8795
				null,
9088
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
8796
				false);
9089
					TypeBinding[] arguments = ptb.arguments;
8797
9090
					if (arguments != null && arguments.length == 1) {
8798
		ReferenceBinding[] memberTypes = receiverType.memberTypes();
9091
						TypeBinding argument = arguments[0];
8799
		next : for (int i = 0; i < memberTypes.length; i++) {
9092
						findVariableNameForCollection(
8800
			if (this.options.checkVisibility) {
9093
							name,
8801
				if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
9094
							argument.leafComponentType().qualifiedPackageName(),
8802
					continue next;
9095
							argument.leafComponentType().qualifiedSourceName(),
8803
				} else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
9096
							argument.leafComponentType().sourceName(),
8804
					continue next;
9097
							tb,
9098
							discouragedNames,
9099
							forbiddenNames,
9100
							kind,
9101
							modifiers);
9102
					}
9103
				}
8805
				}
9104
			}
8806
			}
8807
			findSubMemberTypes(
8808
				typeName,
8809
				memberTypes[i],
8810
				scope,
8811
				typeInvocation,
8812
				staticOnly,
8813
				staticFieldsAndMethodOnly,
8814
				fromStaticImport,
8815
				typesFound);
9105
		}
8816
		}
9106
9107
	}
8817
	}
9108
8818
9109
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
8819
	private void findTrueOrFalseKeywords(char[][] choices) {
9110
		if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
8820
		if(choices == null || choices.length == 0) return;
9111
8821
9112
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
8822
		if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
9113
8823
9114
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
8824
		for (int i = 0; i < choices.length; i++) {
8825
			if (CharOperation.equals(choices[i], Keywords.TRUE) ||
8826
					CharOperation.equals(choices[i], Keywords.FALSE)
8827
			){
8828
				int relevance = computeBaseRelevance();
8829
				relevance += computeRelevanceForResolution();
8830
				relevance += computeRelevanceForInterestingProposal();
8831
				relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
8832
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
8833
				relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
8834
				relevance += computeRelevanceForQualification(false);
8835
				relevance += R_TRUE_OR_FALSE;
9115
8836
9116
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
8837
				this.noProposal = false;
8838
				if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
8839
					InternalCompletionProposal proposal =  createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
8840
					proposal.setName(choices[i]);
8841
					proposal.setCompletion(choices[i]);
8842
					proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
8843
					proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
8844
					proposal.setRelevance(relevance);
8845
					this.requestor.accept(proposal);
8846
					if(DEBUG) {
8847
						this.printDebug(proposal);
8848
					}
8849
				}
8850
			}
8851
		}
8852
	}
9117
8853
9118
		int count = 0;
8854
	private void findTypeParameters(char[] token, Scope scope) {
9119
		next : for (int i = 0; i < favoriteReferences.length; i++) {
8855
		if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
9120
			String favoriteReference = favoriteReferences[i];
9121
8856
9122
			int length;
8857
		TypeParameter[] typeParameters = null;
9123
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
8858
		while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
8859
			typeParameters = null;
8860
			switch (scope.kind) {
8861
				case Scope.METHOD_SCOPE :
8862
					MethodScope methodScope = (MethodScope) scope;
8863
					if(methodScope.referenceContext instanceof MethodDeclaration) {
8864
						MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
8865
						typeParameters = methodDeclaration.typeParameters;
8866
					} else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
8867
						ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
8868
						typeParameters = methodDeclaration.typeParameters;
8869
					}
8870
					break;
8871
				case Scope.CLASS_SCOPE :
8872
					ClassScope classScope = (ClassScope) scope;
8873
					typeParameters = classScope.referenceContext.typeParameters;
8874
					break;
8875
				case Scope.COMPILATION_UNIT_SCOPE :
8876
					return;
8877
			}
8878
			if(typeParameters != null) {
8879
				for (int i = 0; i < typeParameters.length; i++) {
8880
					int typeLength = token.length;
8881
					TypeParameter typeParameter = typeParameters[i];
9124
8882
9125
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
8883
					if(typeParameter.binding == null) continue;
9126
8884
9127
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
8885
					if (typeLength > typeParameter.name.length) continue;
9128
			if (onDemand) {
9129
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
9130
			}
9131
8886
9132
			// remove duplicate and conflicting
8887
					if (!CharOperation.prefixEquals(token, typeParameter.name, false)
9133
			for (int j = 0; j < count; j++) {
8888
							&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
9134
				ImportReference f = resolvedImports[j].reference;
9135
8889
9136
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
8890
					int relevance = computeBaseRelevance();
8891
					relevance += computeRelevanceForResolution();
8892
					relevance += computeRelevanceForInterestingProposal();
8893
					relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
8894
					relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
8895
					relevance += computeRelevanceForQualification(false);
8896
					relevance += computeRelevanceForException(typeParameter.name);
8897
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
9137
8898
9138
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
8899
					this.noProposal = false;
9139
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
8900
					if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9140
						continue next;
8901
						createTypeParameterProposal(typeParameter, relevance);
8902
					}
9141
				}
8903
				}
9142
			}
8904
			}
8905
			scope = scope.parent;
8906
		}
8907
	}
9143
8908
9144
			boolean isStatic = true;
8909
	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
8910
9153
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
8911
		if (token == null)
8912
			return;
9154
8913
9155
			if (!importBinding.isValidBinding()) {
8914
		// do not propose type if completion token is empty
9156
				continue next;
8915
		boolean skip = false;
8916
		if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
8917
			if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
8918
				return;
9157
			}
8919
			}
8920
			skip = true;
8921
		}
9158
8922
9159
			if (importBinding instanceof PackageBinding) {
8923
		boolean proposeType =
9160
				continue next;
8924
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9161
			}
8925
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9162
8926
9163
			resolvedImports[count++] =
8927
		boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
9164
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
8928
8929
		if (!skip && proposeType && scope.enclosingSourceType() != null) {
8930
			
8931
			checkCancel();
8932
			
8933
			findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
8934
			if(!this.assistNodeIsInterface &&
8935
					!this.assistNodeIsConstructor &&
8936
					!this.assistNodeIsAnnotation &&
8937
					this.assistNodeInJavadoc == 0) {
8938
				
8939
				checkCancel();
8940
				
8941
				// don't propose type parameters if the completion is a constructor ('new |')
8942
				findTypeParameters(token, scope);
8943
			}
9165
		}
8944
		}
9166
8945
9167
		if (resolvedImports.length > count)
8946
		boolean isEmptyPrefix = token.length == 0;
9168
			System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
9169
8947
9170
		return this.favoriteReferenceBindings = resolvedImports;
8948
		if (!skip && proposeType && this.unitScope != null) {
9171
	}
8949
			
8950
			ReferenceBinding outerInvocationType = scope.enclosingSourceType();
8951
			if(outerInvocationType != null) {
8952
				ReferenceBinding temp = outerInvocationType.enclosingType();
8953
				while(temp != null) {
8954
					outerInvocationType = temp;
8955
					temp = temp.enclosingType();
8956
				}
8957
			}
9172
8958
9173
	public AssistParser getParser() {
8959
			int typeLength = token.length;
8960
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9174
8961
9175
		return this.parser;
8962
			next : for (int i = 0, length = types.length; i < length; i++) {
9176
	}
8963
				
8964
				checkCancel();
8965
				
8966
				SourceTypeBinding sourceType = types[i];
9177
8967
9178
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
8968
				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
8969
9189
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
8970
				if(proposeAllMemberTypes &&
9190
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
8971
					sourceType != outerInvocationType) {
9191
				    sig.append(Signature.C_GENERIC_START);
8972
					findSubMemberTypes(
9192
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
8973
							token,
9193
				        sig.append(typeVariables[i].genericTypeSignature());
8974
							sourceType,
9194
				    }
8975
							scope,
9195
				    sig.append(Signature.C_GENERIC_END);
8976
							scope.enclosingSourceType(),
8977
							false,
8978
							false,
8979
							false,
8980
							typesFound);
9196
				}
8981
				}
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
8982
9240
	private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
8983
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
9241
		char[] result = null;
8984
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
9242
		StringBuffer sig = new StringBuffer(10);
9243
8985
9244
		sig.append(typeBinding.signature());
8986
				if (typeLength > sourceType.sourceName.length) continue next;
9245
8987
9246
		int sigLength = sig.length();
8988
				if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
9247
		result = new char[sigLength];
8989
						&& !(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
8990
9253
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
8991
				if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
9254
		if (this.targetedElement == TagBits.AnnotationForPackage) {
8992
					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
				}
8993
				}
9274
			}
9275
		}
9276
		return true;
9277
	}
9278
8994
9279
	protected void reset() {
8995
				for (int j = typesFound.size; --j >= 0;) {
8996
					ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
9280
8997
9281
		super.reset(false);
8998
					if (sourceType == otherType) continue next;
9282
		this.knownPkgs = new HashtableOfObject(10);
8999
				}
9283
		this.knownTypes = new HashtableOfObject(10);
9284
	}
9285
9000
9286
	private void setSourceAndTokenRange(int start, int end) {
9001
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9287
		this.setSourceAndTokenRange(start, end, true);
9288
	}
9289
9002
9290
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
9003
				if(this.assistNodeIsClass) {
9291
		this.setSourceRange(start, end, emptyTokenAdjstment);
9004
					if(!sourceType.isClass()) continue next;
9292
		this.setTokenRange(start, end, emptyTokenAdjstment);
9005
				} else if(this.assistNodeIsInterface) {
9293
	}
9006
					if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
9007
				} else if (this.assistNodeIsAnnotation) {
9008
					if(!sourceType.isAnnotationType()) continue next;
9009
				} else if (isEmptyPrefix && this.assistNodeIsException) {
9010
					if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
9011
						continue next;
9012
					}
9013
				}
9294
9014
9295
	private void setSourceRange(int start, int end) {
9015
				int relevance = computeBaseRelevance();
9296
		this.setSourceRange(start, end, true);
9016
				relevance += computeRelevanceForResolution();
9297
	}
9017
				relevance += computeRelevanceForInterestingProposal();
9018
				relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
9019
				relevance += computeRelevanceForExpectingType(sourceType);
9020
				relevance += computeRelevanceForQualification(false);
9021
				relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
9298
9022
9299
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
9023
				if (sourceType.isAnnotationType()) {
9300
		this.startPosition = start;
9024
					relevance += computeRelevanceForAnnotation();
9301
		if(emptyTokenAdjstment) {
9025
					relevance += computeRelevanceForAnnotationTarget(sourceType);
9302
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
9026
				} else if (sourceType.isInterface()) {
9303
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
9027
					relevance += computeRelevanceForInterface();
9304
		} else {
9028
				} else if(sourceType.isClass()){
9305
			this.endPosition = end + 1;
9029
					relevance += computeRelevanceForClass();
9030
					relevance += computeRelevanceForException(sourceType.sourceName);
9031
				}
9032
				this.noProposal = false;
9033
				if(proposeType) {
9034
					char[] typeName = sourceType.sourceName();
9035
					createTypeProposal(
9036
							sourceType,
9037
							typeName,
9038
							IAccessRule.K_ACCESSIBLE,
9039
							typeName,
9040
							relevance,
9041
							null,
9042
							null,
9043
							null,
9044
							false);
9045
				}
9046
			}
9306
		}
9047
		}
9307
	}
9308
9048
9309
	private void setTokenRange(int start, int end) {
9049
		if(!skip && proposeType) {
9310
		this.setTokenRange(start, end, true);
9050
			
9311
	}
9051
			checkCancel();
9312
9052
			
9313
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
9053
			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
		}
9054
		}
9321
	}
9322
9055
9323
	private char[][] computeAlreadyDefinedName(
9056
		if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
9324
			BlockScope scope,
9057
			if(proposeType && this.expectedTypesPtr > -1) {
9325
			InvocationSite invocationSite) {
9058
				next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
9326
		ArrayList result = new ArrayList();
9059
					
9060
					checkCancel();
9061
					
9062
					if(this.expectedTypes[i] instanceof ReferenceBinding) {
9063
						ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
9327
9064
9328
		boolean staticsOnly = false;
9065
						if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
9066
							// don't propose type variable if the completion is a constructor ('new |')
9067
							continue next;
9068
						}
9069
						if (this.options.checkDeprecation &&
9070
								refBinding.isViewedAsDeprecated() &&
9071
								!scope.isDefinedInSameUnit(refBinding))
9072
							continue next;
9329
9073
9330
		Scope currentScope = scope;
9074
						int accessibility = IAccessRule.K_ACCESSIBLE;
9075
						if(refBinding.hasRestrictedAccess()) {
9076
							AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
9077
							if(accessRestriction != null) {
9078
								switch (accessRestriction.getProblemId()) {
9079
									case IProblem.ForbiddenReference:
9080
										if (this.options.checkForbiddenReference) {
9081
											continue next;
9082
										}
9083
										accessibility = IAccessRule.K_NON_ACCESSIBLE;
9084
										break;
9085
									case IProblem.DiscouragedReference:
9086
										if (this.options.checkDiscouragedReference) {
9087
											continue next;
9088
										}
9089
										accessibility = IAccessRule.K_DISCOURAGED;
9090
										break;
9091
								}
9092
							}
9093
						}
9331
9094
9332
		done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9095
						for (int j = 0; j < typesFound.size(); j++) {
9096
							ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
9097
							if (typeFound == refBinding) {
9098
								continue next;
9099
							}
9100
						}
9333
9101
9334
			switch (currentScope.kind) {
9102
						boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
9335
9103
9336
				case Scope.METHOD_SCOPE :
9104
						// top level types of the current unit are already proposed.
9337
					// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9105
						if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
9338
					MethodScope methodScope = (MethodScope) currentScope;
9106
							char[] packageName = refBinding.qualifiedPackageName();
9339
					staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9107
							char[] typeName = refBinding.sourceName();
9108
							char[] completionName = typeName;
9340
9109
9341
				//$FALL-THROUGH$
9110
							boolean isQualified = false;
9342
				case Scope.BLOCK_SCOPE :
9111
							if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
9343
					BlockScope blockScope = (BlockScope) currentScope;
9112
								if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
9113
									if (packageName == null || packageName.length == 0)
9114
										if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
9115
											continue next; // ignore types from the default package from outside it
9116
									completionName = CharOperation.concat(packageName, typeName, '.');
9117
									isQualified = true;
9118
								}
9119
							}
9344
9120
9345
					next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9121
							if(this.assistNodeIsClass) {
9346
						LocalVariableBinding local = blockScope.locals[i];
9122
								if(!refBinding.isClass()) continue next;
9123
							} else if(this.assistNodeIsInterface) {
9124
								if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
9125
							} else if (this.assistNodeIsAnnotation) {
9126
								if(!refBinding.isAnnotationType()) continue next;
9127
							}
9347
9128
9348
						if (local == null)
9129
							int relevance = computeBaseRelevance();
9349
							break next;
9130
							relevance += computeRelevanceForResolution();
9131
							relevance += computeRelevanceForInterestingProposal();
9132
							relevance += computeRelevanceForCaseMatching(token, typeName);
9133
							relevance += computeRelevanceForExpectingType(refBinding);
9134
							relevance += computeRelevanceForQualification(isQualified);
9135
							relevance += computeRelevanceForRestrictions(accessibility);
9350
9136
9351
						if (local.isSecret())
9137
							if(refBinding.isClass()) {
9352
							continue next;
9138
								relevance += computeRelevanceForClass();
9139
								relevance += computeRelevanceForException(typeName);
9140
							} else if(refBinding.isEnum()) {
9141
								relevance += computeRelevanceForEnum();
9142
							} else if(refBinding.isInterface()) {
9143
								relevance += computeRelevanceForInterface();
9144
							}
9353
9145
9354
						result.add(local.name);
9146
							this.noProposal = false;
9147
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9148
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9149
								proposal.setDeclarationSignature(packageName);
9150
								proposal.setSignature(getSignature(refBinding));
9151
								proposal.setPackageName(packageName);
9152
								proposal.setTypeName(typeName);
9153
								proposal.setCompletion(completionName);
9154
								proposal.setFlags(refBinding.modifiers);
9155
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9156
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9157
								proposal.setRelevance(relevance);
9158
								proposal.setAccessibility(accessibility);
9159
								this.requestor.accept(proposal);
9160
								if(DEBUG) {
9161
									this.printDebug(proposal);
9162
								}
9163
							}
9164
						}
9355
					}
9165
					}
9356
					break;
9166
				}
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
			}
9167
			}
9373
			currentScope = currentScope.parent;
9168
		} else {
9374
		}
9169
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
9375
9170
				if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
9376
		if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
9171
					if (proposeBaseTypes) {
9377
9172
						if (proposeVoidType) {
9378
		return (char[][])result.toArray(new char[result.size()][]);
9173
							findKeywords(token, BASE_TYPE_NAMES, false, false);
9379
	}
9174
						} else {
9380
9175
							findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
9381
	private void computeAlreadyDefinedName(
9176
						}
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
					}
9177
					}
9407
				}
9178
				}
9408
			}
9179
			}
9409
9180
			if(proposeType) {
9410
			FieldBinding[] fields = currentType.availableFields();
9181
				int l = typesFound.size();
9411
			if(fields != null && fields.length > 0) {
9182
				for (int i = 0; i < l; i++) {
9412
				computeAlreadyDefinedName(
9183
					ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
9413
					fields,
9184
					char[] fullyQualifiedTypeName =
9414
					scope,
9185
						CharOperation.concat(
9415
					onlyStaticFields,
9186
								typeFound.qualifiedPackageName(),
9416
					receiverType,
9187
								typeFound.qualifiedSourceName(),
9417
					invocationSite,
9188
								'.');
9418
					result);
9189
					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
				}
9190
				}
9436
9191
				int searchFor = IJavaSearchConstants.TYPE;
9437
				ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
9192
				if(this.assistNodeIsClass) {
9438
				if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
9193
					searchFor = IJavaSearchConstants.CLASS;
9439
					int itsLength = itsInterfaces.length;
9194
				} else if(this.assistNodeIsInterface) {
9440
					if (nextPosition + itsLength >= interfacesToVisit.length)
9195
					searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9441
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
9196
				} else if(this.assistNodeIsEnum) {
9442
					nextInterface : for (int a = 0; a < itsLength; a++) {
9197
					searchFor = IJavaSearchConstants.ENUM;
9443
						ReferenceBinding next = itsInterfaces[a];
9198
				} else if(this.assistNodeIsAnnotation) {
9444
						for (int b = 0; b < nextPosition; b++)
9199
					searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9445
							if (next == interfacesToVisit[b]) continue nextInterface;
9446
						interfacesToVisit[nextPosition++] = next;
9447
					}
9448
				}
9200
				}
9201
				
9202
				checkCancel();
9203
				
9204
				this.foundTypesCount = 0;
9205
				this.nameEnvironment.findTypes(
9206
						token,
9207
						proposeAllMemberTypes,
9208
						this.options.camelCaseMatch,
9209
						searchFor,
9210
						this);
9211
				acceptTypes(scope);
9212
			}
9213
			if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9214
				
9215
				checkCancel();
9216
				
9217
				this.nameEnvironment.findPackages(token, this);
9449
			}
9218
			}
9450
		}
9219
		}
9451
	}
9220
	}
9452
9221
9453
	private void computeAlreadyDefinedName(
9222
	private void findTypesAndSubpackages(
9454
			FieldBinding[] fields,
9223
		char[] token,
9455
			Scope scope,
9224
		PackageBinding packageBinding,
9456
			boolean onlyStaticFields,
9225
		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
9226
9466
			if (onlyStaticFields && !field.isStatic()) continue next;
9227
		boolean proposeType =
9228
			!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
9229
			((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
9467
9230
9468
			if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
9231
		char[] qualifiedName =
9232
			CharOperation.concatWith(packageBinding.compoundName, token, '.');
9469
9233
9470
			result.add(field.name);
9234
		if (token == null || token.length == 0) {
9235
			int length = qualifiedName.length;
9236
			System.arraycopy(
9237
				qualifiedName,
9238
				0,
9239
				qualifiedName = new char[length + 1],
9240
				0,
9241
				length);
9242
			qualifiedName[length] = '.';
9471
		}
9243
		}
9472
	}
9473
9244
9474
	int computeBaseRelevance(){
9245
		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
9246
9488
		// default filter
9247
		if (proposeType && this.unitScope != null) {
9489
		this.expectedTypesFilter = SUBTYPE;
9248
			int typeLength = qualifiedName.length;
9490
		this.hasJavaLangObjectAsExpectedType = false;
9249
			SourceTypeBinding[] types = this.unitScope.topLevelTypes;
9491
9250
9492
		// find types from parent
9251
			for (int i = 0, length = types.length; i < length; i++) {
9493
		if(parent instanceof AbstractVariableDeclaration) {
9252
				
9494
			AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
9253
				checkCancel();
9495
			TypeBinding binding = variable.type.resolvedType;
9254
				
9496
			if(binding != null) {
9255
				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
9256
9524
			if(messageSend.actualReceiverType instanceof ReferenceBinding) {
9257
				char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
9525
				ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
9526
				boolean isStatic = messageSend.receiver.isTypeReference();
9527
9258
9528
				while(binding != null) {
9259
				if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
9529
					computeExpectedTypesForMessageSend(
9260
				if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
9530
						binding,
9261
				if (typeLength > qualifiedSourceTypeName.length) continue;
9531
						messageSend.selector,
9262
				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
9263
9551
			ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
9264
				if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
9265
						&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName)))	continue;
9552
9266
9553
			if(binding != null) {
9267
				if (this.options.checkDeprecation &&
9554
				computeExpectedTypesForAllocationExpression(
9268
						sourceType.isViewedAsDeprecated() &&
9555
					binding,
9269
						!scope.isDefinedInSameUnit(sourceType))
9556
					allocationExpression.arguments,
9270
					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
9271
9272
				int accessibility = IAccessRule.K_ACCESSIBLE;
9273
				if(sourceType.hasRestrictedAccess()) {
9274
					AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
9275
					if(accessRestriction != null) {
9276
						switch (accessRestriction.getProblemId()) {
9277
							case IProblem.ForbiddenReference:
9278
								if (this.options.checkForbiddenReference) {
9279
									continue;
9280
								}
9281
								accessibility = IAccessRule.K_NON_ACCESSIBLE;
9282
								break;
9283
							case IProblem.DiscouragedReference:
9284
								if (this.options.checkDiscouragedReference) {
9285
									continue;
9286
								}
9287
								accessibility = IAccessRule.K_DISCOURAGED;
9288
								break;
9617
						}
9289
						}
9618
					}
9290
					}
9619
				}
9291
				}
9620
			} else if(parent instanceof UnaryExpression) {
9292
9621
				switch(operator) {
9293
				this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
9622
					case OperatorIds.NOT :
9294
9623
						addExpectedType(TypeBinding.BOOLEAN, scope);
9295
				int relevance = computeBaseRelevance();
9624
						break;
9296
				relevance += computeRelevanceForResolution();
9625
					case OperatorIds.TWIDDLE :
9297
				relevance += computeRelevanceForInterestingProposal();
9626
						addExpectedType(TypeBinding.SHORT, scope);
9298
				relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
9627
						addExpectedType(TypeBinding.INT, scope);
9299
				relevance += computeRelevanceForExpectingType(sourceType);
9628
						addExpectedType(TypeBinding.LONG, scope);
9300
				relevance += computeRelevanceForQualification(false);
9629
						addExpectedType(TypeBinding.CHAR, scope);
9301
				relevance += computeRelevanceForRestrictions(accessibility);
9630
						addExpectedType(TypeBinding.BYTE, scope);
9302
9631
						break;
9303
				if (sourceType.isAnnotationType()) {
9632
					case OperatorIds.PLUS :
9304
					relevance += computeRelevanceForAnnotation();
9633
					case OperatorIds.MINUS :
9305
				} else if (sourceType.isInterface()) {
9634
					case OperatorIds.PLUS_PLUS :
9306
					relevance += computeRelevanceForInterface();
9635
					case OperatorIds.MINUS_MINUS :
9307
				} else if (sourceType.isClass()) {
9636
						addExpectedType(TypeBinding.SHORT, scope);
9308
					relevance += computeRelevanceForClass();
9637
						addExpectedType(TypeBinding.INT, scope);
9309
					relevance += computeRelevanceForException(sourceType.sourceName);
9638
						addExpectedType(TypeBinding.LONG, scope);
9310
				}
9639
						addExpectedType(TypeBinding.FLOAT, scope);
9311
				this.noProposal = false;
9640
						addExpectedType(TypeBinding.DOUBLE, scope);
9312
				if(proposeType) {
9641
						addExpectedType(TypeBinding.CHAR, scope);
9313
					char[] typeName = sourceType.sourceName();
9642
						addExpectedType(TypeBinding.BYTE, scope);
9314
					createTypeProposal(
9643
						break;
9315
							sourceType,
9316
							typeName,
9317
							IAccessRule.K_ACCESSIBLE,
9318
							typeName,
9319
							relevance,
9320
							null,
9321
							null,
9322
							null,
9323
							false);
9644
				}
9324
				}
9645
			}
9325
			}
9646
		} else if(parent instanceof ArrayReference) {
9326
		}
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
9327
9658
				TypeBinding bound = typeVariables[index].firstBound;
9328
		if(proposeType) {
9659
				addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9329
			int searchFor = IJavaSearchConstants.TYPE;
9330
			if(this.assistNodeIsClass) {
9331
				searchFor = IJavaSearchConstants.CLASS;
9332
			} else if(this.assistNodeIsInterface) {
9333
				searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
9334
			} else if(this.assistNodeIsEnum) {
9335
				searchFor = IJavaSearchConstants.ENUM;
9336
			} else if(this.assistNodeIsAnnotation) {
9337
				searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
9660
			}
9338
			}
9661
		} else if(parent instanceof ParameterizedQualifiedTypeReference) {
9339
			
9662
			ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
9340
			checkCancel();
9663
			TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
9341
			
9664
			TypeReference[][] arguments = ref.typeArguments;
9342
			this.foundTypesCount = 0;
9665
			if(typeVariables != null) {
9343
			this.nameEnvironment.findTypes(
9666
				int iLength = arguments == null ? 0 : arguments.length;
9344
					qualifiedName,
9667
				done: for (int i = 0; i < iLength; i++) {
9345
					false,
9668
					int jLength = arguments[i] == null ? 0 : arguments[i].length;
9346
					this.options.camelCaseMatch,
9669
					for (int j = 0; j < jLength; j++) {
9347
					searchFor,
9670
						if(arguments[i][j] == node && typeVariables.length > j) {
9348
					this);
9671
							TypeBinding bound = typeVariables[j].firstBound;
9349
			acceptTypes(scope);
9672
							addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
9350
		}
9673
							break done;
9351
		if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
9352
			this.nameEnvironment.findPackages(qualifiedName, this);
9353
		}
9354
	}
9355
9356
	private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
9357
		ImportBinding[] importBindings = scope.compilationUnitScope().imports;
9358
		for (int i = 0; i < importBindings.length; i++) {
9359
			ImportBinding importBinding = importBindings[i];
9360
			if(importBinding.isValidBinding() && importBinding.isStatic()) {
9361
				Binding binding = importBinding.resolvedImport;
9362
				if(binding != null && binding.isValidBinding()) {
9363
					if(importBinding.onDemand) {
9364
						if((binding.kind() & Binding.TYPE) != 0) {
9365
							this.findMemberTypes(
9366
									token,
9367
									(ReferenceBinding) binding,
9368
									scope,
9369
									scope.enclosingSourceType(),
9370
									true,
9371
									false,
9372
									true,
9373
									true,
9374
									proposeAllMemberTypes,
9375
									null,
9376
									typesFound,
9377
									null,
9378
									null,
9379
									null,
9380
									false);
9674
						}
9381
						}
9675
					}
9382
					} else {
9676
				}
9383
						if ((binding.kind() & Binding.TYPE) != 0) {
9677
			}
9384
							ReferenceBinding typeBinding = (ReferenceBinding) binding;
9678
		} else if(parent instanceof MemberValuePair) {
9385
							int typeLength = token.length;
9679
			MemberValuePair memberValuePair = (MemberValuePair) parent;
9386
9680
			if(memberValuePair.binding != null) {
9387
							if (!typeBinding.isStatic()) continue;
9681
				addExpectedType(memberValuePair.binding.returnType, scope);
9388
9682
			}
9389
							if (typeLength > typeBinding.sourceName.length)	continue;
9683
		} else if (parent instanceof NormalAnnotation) {
9390
9684
			NormalAnnotation annotation = (NormalAnnotation) parent;
9391
							if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
9685
			MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
9392
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName)))	continue;
9686
			if(memberValuePairs == null || memberValuePairs.length == 0) {
9393
9687
				if(annotation.resolvedType instanceof ReferenceBinding) {
9394
							if (typesFound.contains(typeBinding))  continue;
9688
					MethodBinding[] methodBindings =
9395
9689
						((ReferenceBinding)annotation.resolvedType).availableMethods();
9396
							typesFound.add(typeBinding);
9690
					if (methodBindings != null &&
9397
9691
							methodBindings.length > 0 &&
9398
							if(this.assistNodeIsClass) {
9692
							CharOperation.equals(methodBindings[0].selector, VALUE)) {
9399
								if(!typeBinding.isClass()) continue;
9693
						boolean canBeSingleMemberAnnotation = true;
9400
							} else if(this.assistNodeIsInterface) {
9694
						done : for (int i = 1; i < methodBindings.length; i++) {
9401
								if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
9695
							if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
9402
							} else if (this.assistNodeIsAnnotation) {
9696
								canBeSingleMemberAnnotation = false;
9403
								if(!typeBinding.isAnnotationType()) continue;
9404
							}
9405
9406
							int relevance = computeBaseRelevance();
9407
							relevance += computeRelevanceForResolution();
9408
							relevance += computeRelevanceForInterestingProposal();
9409
							relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
9410
							relevance += computeRelevanceForExpectingType(typeBinding);
9411
							relevance += computeRelevanceForQualification(false);
9412
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
9413
9414
							if (typeBinding.isClass()) {
9415
								relevance += computeRelevanceForClass();
9416
								relevance += computeRelevanceForException(typeBinding.sourceName);
9417
							} else if(typeBinding.isEnum()) {
9418
								relevance += computeRelevanceForEnum();
9419
							} else if(typeBinding.isInterface()) {
9420
								relevance += computeRelevanceForInterface();
9421
							}
9422
9423
							this.noProposal = false;
9424
							if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
9425
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
9426
								proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
9427
								proposal.setSignature(getSignature(typeBinding));
9428
								proposal.setPackageName(typeBinding.qualifiedPackageName());
9429
								proposal.setTypeName(typeBinding.qualifiedSourceName());
9430
								proposal.setCompletion(typeBinding.sourceName());
9431
								proposal.setFlags(typeBinding.modifiers);
9432
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9433
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9434
								proposal.setRelevance(relevance);
9435
								this.requestor.accept(proposal);
9436
								if(DEBUG) {
9437
									this.printDebug(proposal);
9438
								}
9439
							}
9440
						}
9441
					}
9442
				}
9443
			}
9444
		}
9445
	}
9446
9447
	private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
9448
		char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
9449
		if (foundNames != null && foundNames.length > 1) {
9450
			int discouragedNamesLength = discouragedNames.length;
9451
			int foundNamesLength = foundNames.length;
9452
			int newLength = discouragedNamesLength + foundNamesLength;
9453
			System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
9454
			System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
9455
		}
9456
		findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
9457
	}
9458
9459
	private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
9460
		final ArrayList proposedNames = new ArrayList();
9461
9462
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9463
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9464
				public void acceptName(char[] name) {
9465
					CompletionEngine.this.acceptUnresolvedName(name);
9466
					proposedNames.add(name);
9467
				}
9468
			};
9469
9470
		ReferenceContext referenceContext = scope.referenceContext();
9471
		if (referenceContext instanceof AbstractMethodDeclaration) {
9472
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9473
9474
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9475
			nameFinder.findAfter(
9476
					this.completionToken,
9477
					md.scope,
9478
					md.scope.classScope(),
9479
					from,
9480
					md.bodyEnd,
9481
					discouragedNames,
9482
					nameRequestor);
9483
		} else if (referenceContext instanceof TypeDeclaration) {
9484
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9485
			FieldDeclaration[] fields = typeDeclaration.fields;
9486
			if (fields != null) {
9487
				done : for (int i = 0; i < fields.length; i++) {
9488
					if (fields[i] instanceof Initializer) {
9489
						Initializer initializer = (Initializer) fields[i];
9490
						if (initializer.block.sourceStart <= from &&
9491
								from < initializer.bodyEnd) {
9492
							UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9493
							nameFinder.findAfter(
9494
										this.completionToken,
9495
										typeDeclaration.scope,
9496
										typeDeclaration.scope,
9497
										from,
9498
										initializer.bodyEnd,
9499
										discouragedNames,
9500
										nameRequestor);
9501
							break done;
9502
						}
9503
					}
9504
				}
9505
			}
9506
		}
9507
9508
		int proposedNamesCount = proposedNames.size();
9509
		if (proposedNamesCount > 0) {
9510
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9511
		}
9512
9513
		return null;
9514
	}
9515
9516
	private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
9517
		final ArrayList proposedNames = new ArrayList();
9518
9519
		UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9520
			new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9521
				public void acceptName(char[] name) {
9522
					CompletionEngine.this.acceptUnresolvedName(name);
9523
					proposedNames.add(name);
9524
				}
9525
			};
9526
9527
		BlockScope upperScope = scope;
9528
		while (upperScope.enclosingMethodScope() != null) {
9529
			upperScope = upperScope.enclosingMethodScope();
9530
		}
9531
9532
		ReferenceContext referenceContext = upperScope.referenceContext();
9533
		if (referenceContext instanceof AbstractMethodDeclaration) {
9534
			AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9535
9536
			UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9537
			nameFinder.findBefore(
9538
					this.completionToken,
9539
					md.scope,
9540
					md.scope.classScope(),
9541
					md.bodyStart,
9542
					recordTo,
9543
					parseTo,
9544
					discouragedNames,
9545
					nameRequestor);
9546
		} else if (referenceContext instanceof TypeDeclaration) {
9547
			TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9548
9549
9550
			done : {
9551
				FieldDeclaration[] fields = typeDeclaration.fields;
9552
				if (fields != null) {
9553
					for (int i = 0; i < fields.length; i++) {
9554
						if (fields[i] instanceof Initializer) {
9555
							Initializer initializer = (Initializer) fields[i];
9556
							if (initializer.block.sourceStart <= recordTo &&
9557
									recordTo < initializer.bodyEnd) {
9558
9559
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9560
								nameFinder.findBefore(
9561
										this.completionToken,
9562
										typeDeclaration.scope,
9563
										typeDeclaration.scope,
9564
										initializer.block.sourceStart,
9565
										recordTo,
9566
										parseTo,
9567
										discouragedNames,
9568
										nameRequestor);
9697
								break done;
9569
								break done;
9698
							}
9570
							}
9699
						}
9571
						}
9700
						if (canBeSingleMemberAnnotation) {
9572
					}
9701
							this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
9573
				}
9702
							addExpectedType(methodBindings[0].returnType, scope);
9574
			}
9575
		}
9576
9577
		int proposedNamesCount = proposedNames.size();
9578
		if (proposedNamesCount > 0) {
9579
			return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9580
		}
9581
9582
		return null;
9583
	}
9584
9585
	private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
9586
		final TypeReference type = variable.type;
9587
		if(type != null &&
9588
				type.resolvedType != null &&
9589
				type.resolvedType.problemId() == ProblemReasons.NoError){
9590
9591
			final ArrayList proposedNames = new ArrayList();
9592
9593
			UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
9594
				new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
9595
					public void acceptName(char[] name) {
9596
						int relevance = computeBaseRelevance();
9597
						relevance += computeRelevanceForInterestingProposal();
9598
						relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
9599
						relevance += R_NAME_FIRST_PREFIX;
9600
						relevance += R_NAME_FIRST_SUFFIX;
9601
						relevance += R_NAME_LESS_NEW_CHARACTERS;
9602
						relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9603
9604
						// accept result
9605
						CompletionEngine.this.noProposal = false;
9606
						if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9607
							InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9608
							proposal.setSignature(getSignature(type.resolvedType));
9609
							proposal.setPackageName(type.resolvedType.qualifiedPackageName());
9610
							proposal.setTypeName(type.resolvedType.qualifiedSourceName());
9611
							proposal.setName(name);
9612
							proposal.setCompletion(name);
9613
							//proposal.setFlags(Flags.AccDefault);
9614
							proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9615
							proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9616
							proposal.setRelevance(relevance);
9617
							CompletionEngine.this.requestor.accept(proposal);
9618
							if(DEBUG) {
9619
								CompletionEngine.this.printDebug(proposal);
9620
							}
9621
						}
9622
						proposedNames.add(name);
9623
					}
9624
				};
9625
9626
			ReferenceContext referenceContext = scope.referenceContext();
9627
			if (referenceContext instanceof AbstractMethodDeclaration) {
9628
				AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
9629
9630
				UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9631
				nameFinder.find(
9632
						this.completionToken,
9633
						md,
9634
						variable.declarationSourceEnd + 1,
9635
						discouragedNames,
9636
						nameRequestor);
9637
			} else if (referenceContext instanceof TypeDeclaration) {
9638
				TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
9639
				FieldDeclaration[] fields = typeDeclaration.fields;
9640
				if (fields != null) {
9641
					done : for (int i = 0; i < fields.length; i++) {
9642
						if (fields[i] instanceof Initializer) {
9643
							Initializer initializer = (Initializer) fields[i];
9644
							if (initializer.bodyStart <= variable.sourceStart &&
9645
									variable.sourceStart < initializer.bodyEnd) {
9646
								UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
9647
								nameFinder.find(
9648
										this.completionToken,
9649
										initializer,
9650
										typeDeclaration.scope,
9651
										variable.declarationSourceEnd + 1,
9652
										discouragedNames,
9653
										nameRequestor);
9654
								break done;
9655
							}
9656
						}
9657
					}
9658
				}
9659
			}
9660
9661
			int proposedNamesCount = proposedNames.size();
9662
			if (proposedNamesCount > 0) {
9663
				return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
9664
			}
9665
		}
9666
9667
		return null;
9668
	}
9669
9670
	private void findVariableName(
9671
			char[] token,
9672
			char[] qualifiedPackageName,
9673
			char[] qualifiedSourceName,
9674
			char[] sourceName,
9675
			final TypeBinding typeBinding,
9676
			char[][] discouragedNames,
9677
			final char[][] forbiddenNames,
9678
			boolean forCollection,
9679
			int dim,
9680
			int kind,
9681
			int modifiers){
9682
9683
		if(sourceName == null || sourceName.length == 0)
9684
			return;
9685
9686
		// compute variable name for non base type
9687
		final char[] displayName;
9688
		if (!forCollection) {
9689
			if (dim > 0){
9690
				int l = qualifiedSourceName.length;
9691
				displayName = new char[l+(2*dim)];
9692
				System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
9693
				for(int i = 0; i < dim; i++){
9694
					displayName[l+(i*2)] = '[';
9695
					displayName[l+(i*2)+1] = ']';
9696
				}
9697
			} else {
9698
				displayName = qualifiedSourceName;
9699
			}
9700
		} else {
9701
			displayName = typeBinding.qualifiedSourceName();
9702
		}
9703
9704
		final char[] t = token;
9705
		final char[] q = qualifiedPackageName;
9706
		INamingRequestor namingRequestor = new INamingRequestor() {
9707
			void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
9708
				int l = forbiddenNames == null ? 0 : forbiddenNames.length;
9709
				for (int i = 0; i < l; i++) {
9710
					if (CharOperation.equals(forbiddenNames[i], name, false)) return;
9711
				}
9712
9713
				if (CharOperation.prefixEquals(t, name, false)) {
9714
					int relevance = computeBaseRelevance();
9715
					relevance += computeRelevanceForInterestingProposal();
9716
					relevance += computeRelevanceForCaseMatching(t, name);
9717
					relevance += prefixAndSuffixRelevance;
9718
					if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
9719
					relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
9720
9721
					// accept result
9722
					CompletionEngine.this.noProposal = false;
9723
					if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
9724
						InternalCompletionProposal proposal =  CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
9725
						proposal.setSignature(getSignature(typeBinding));
9726
						proposal.setPackageName(q);
9727
						proposal.setTypeName(displayName);
9728
						proposal.setName(name);
9729
						proposal.setCompletion(name);
9730
						//proposal.setFlags(Flags.AccDefault);
9731
						proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
9732
						proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
9733
						proposal.setRelevance(relevance);
9734
						CompletionEngine.this.requestor.accept(proposal);
9735
						if(DEBUG) {
9736
							CompletionEngine.this.printDebug(proposal);
9737
						}
9738
					}
9739
				}
9740
			}
9741
9742
			public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
9743
				accept(name, 0, reusedCharacters);
9744
			}
9745
9746
			public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
9747
				accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX :  R_NAME_PREFIX, reusedCharacters);
9748
			}
9749
9750
			public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
9751
				accept(
9752
						name,
9753
						(isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
9754
						reusedCharacters);
9755
			}
9756
			public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
9757
				accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
9758
			}
9759
		};
9760
9761
		switch (kind) {
9762
			case FIELD :
9763
				InternalNamingConventions.suggestFieldNames(
9764
					this.javaProject,
9765
					qualifiedPackageName,
9766
					qualifiedSourceName,
9767
					dim,
9768
					modifiers,
9769
					token,
9770
					discouragedNames,
9771
					namingRequestor);
9772
				break;
9773
			case LOCAL :
9774
				InternalNamingConventions.suggestLocalVariableNames(
9775
					this.javaProject,
9776
					qualifiedPackageName,
9777
					qualifiedSourceName,
9778
					dim,
9779
					token,
9780
					discouragedNames,
9781
					namingRequestor);
9782
				break;
9783
			case ARGUMENT :
9784
				InternalNamingConventions.suggestArgumentNames(
9785
					this.javaProject,
9786
					qualifiedPackageName,
9787
					qualifiedSourceName,
9788
					dim,
9789
					token,
9790
					discouragedNames,
9791
					namingRequestor);
9792
				break;
9793
		}
9794
	}
9795
9796
	// Helper method for private void findVariableNames(char[] name, TypeReference type )
9797
	private void findVariableName(
9798
			char[] token,
9799
			char[] qualifiedPackageName,
9800
			char[] qualifiedSourceName,
9801
			char[] sourceName,
9802
			final TypeBinding typeBinding,
9803
			char[][] discouragedNames,
9804
			final char[][] forbiddenNames,
9805
			int dim,
9806
			int kind,
9807
			int modifiers){
9808
		findVariableName(
9809
				token,
9810
				qualifiedPackageName,
9811
				qualifiedSourceName,
9812
				sourceName,
9813
				typeBinding,
9814
				discouragedNames,
9815
				forbiddenNames,
9816
				false,
9817
				dim,
9818
				kind,
9819
				modifiers);
9820
	}
9821
	private void findVariableNameForCollection(
9822
			char[] token,
9823
			char[] qualifiedPackageName,
9824
			char[] qualifiedSourceName,
9825
			char[] sourceName,
9826
			final TypeBinding typeBinding,
9827
			char[][] discouragedNames,
9828
			final char[][] forbiddenNames,
9829
			int kind,
9830
			int modifiers){
9831
9832
		findVariableName(
9833
				token,
9834
				qualifiedPackageName,
9835
				qualifiedSourceName,
9836
				sourceName,
9837
				typeBinding,
9838
				discouragedNames,
9839
				forbiddenNames,
9840
				false,
9841
				1,
9842
				kind,
9843
				modifiers);
9844
	}
9845
	private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
9846
		if(type != null &&
9847
			type.resolvedType != null) {
9848
			TypeBinding tb = type.resolvedType;
9849
9850
			if (tb.problemId() == ProblemReasons.NoError &&
9851
					tb != Scope.getBaseType(VOID)) {
9852
				findVariableName(
9853
					name,
9854
					tb.leafComponentType().qualifiedPackageName(),
9855
					tb.leafComponentType().qualifiedSourceName(),
9856
					tb.leafComponentType().sourceName(),
9857
					tb,
9858
					discouragedNames,
9859
					forbiddenNames,
9860
					type.dimensions(),
9861
					kind,
9862
					modifiers);
9863
				
9864
				if (tb.isParameterizedType() &&
9865
						tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
9866
					ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
9867
					TypeBinding[] arguments = ptb.arguments;
9868
					if (arguments != null && arguments.length == 1) {
9869
						TypeBinding argument = arguments[0];
9870
						findVariableNameForCollection(
9871
							name,
9872
							argument.leafComponentType().qualifiedPackageName(),
9873
							argument.leafComponentType().qualifiedSourceName(),
9874
							argument.leafComponentType().sourceName(),
9875
							tb,
9876
							discouragedNames,
9877
							forbiddenNames,
9878
							kind,
9879
							modifiers);
9880
					}
9881
				}
9882
			}
9883
		}
9884
9885
	}
9886
	private void findVariablesAndMethods(
9887
		char[] token,
9888
		Scope scope,
9889
		InvocationSite invocationSite,
9890
		Scope invocationScope,
9891
		boolean insideTypeAnnotation,
9892
		boolean insideAnnotationAttribute) {
9893
9894
		if (token == null)
9895
			return;
9896
9897
		// Should local variables hide fields from the receiver type or any of its enclosing types?
9898
		// we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
9899
9900
		boolean staticsOnly = false;
9901
		// need to know if we're in a static context (or inside a constructor)
9902
		int tokenLength = token.length;
9903
9904
		ObjectVector localsFound = new ObjectVector();
9905
		ObjectVector fieldsFound = new ObjectVector();
9906
		ObjectVector methodsFound = new ObjectVector();
9907
9908
		Scope currentScope = scope;
9909
9910
		if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9911
			done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9912
9913
				switch (currentScope.kind) {
9914
9915
					case Scope.METHOD_SCOPE :
9916
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
9917
						MethodScope methodScope = (MethodScope) currentScope;
9918
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
9919
9920
					//$FALL-THROUGH$
9921
					case Scope.BLOCK_SCOPE :
9922
						BlockScope blockScope = (BlockScope) currentScope;
9923
9924
						next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
9925
							LocalVariableBinding local = blockScope.locals[i];
9926
9927
							if (local == null)
9928
								break next;
9929
9930
							if (tokenLength > local.name.length)
9931
								continue next;
9932
9933
							if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
9934
									&& !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
9935
								continue next;
9936
9937
							if (local.isSecret())
9938
								continue next;
9939
9940
							for (int f = 0; f < localsFound.size; f++) {
9941
								LocalVariableBinding otherLocal =
9942
									(LocalVariableBinding) localsFound.elementAt(f);
9943
								if (CharOperation.equals(otherLocal.name, local.name, true))
9944
									continue next;
9945
							}
9946
							localsFound.add(local);
9947
9948
							int relevance = computeBaseRelevance();
9949
							relevance += computeRelevanceForResolution();
9950
							relevance += computeRelevanceForInterestingProposal(local);
9951
							relevance += computeRelevanceForCaseMatching(token, local.name);
9952
							relevance += computeRelevanceForExpectingType(local.type);
9953
							relevance += computeRelevanceForEnumConstant(local.type);
9954
							relevance += computeRelevanceForQualification(false);
9955
							relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
9956
							this.noProposal = false;
9957
							if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
9958
								InternalCompletionProposal proposal =  createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
9959
								proposal.setSignature(
9960
									local.type == null
9961
									? createTypeSignature(
9962
											CharOperation.NO_CHAR,
9963
											local.declaration.type.toString().toCharArray())
9964
									: getSignature(local.type));
9965
								if(local.type == null) {
9966
									//proposal.setPackageName(null);
9967
									proposal.setTypeName(local.declaration.type.toString().toCharArray());
9968
								} else {
9969
									proposal.setPackageName(local.type.qualifiedPackageName());
9970
									proposal.setTypeName(local.type.qualifiedSourceName());
9971
								}
9972
								proposal.setName(local.name);
9973
								proposal.setCompletion(local.name);
9974
								proposal.setFlags(local.modifiers);
9975
								proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
9976
								proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
9977
								proposal.setRelevance(relevance);
9978
								this.requestor.accept(proposal);
9979
								if(DEBUG) {
9980
									this.printDebug(proposal);
9981
								}
9982
							}
9703
						}
9983
						}
9704
					}
9984
						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
9985
9733
		// Expected types for javadoc
9986
					case Scope.COMPILATION_UNIT_SCOPE :
9734
		} else if (parent instanceof Javadoc) {
9987
						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
				}
9988
				}
9989
				currentScope = currentScope.parent;
9746
			}
9990
			}
9747
		}
9991
		}
9992
		
9993
		checkCancel();
9748
9994
9749
		if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
9995
		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);
9996
		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
9997
9768
			if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
9998
		staticsOnly = false;
9999
		currentScope = scope;
9769
10000
9770
			TypeBinding[] parameters = method.parameters;
10001
		if(proposeField || proposeMethod) {
9771
			if(parameters.length < arguments.length)
10002
			done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
9772
				continue nextMethod;
9773
10003
9774
			int length = arguments.length - 1;
10004
				switch (currentScope.kind) {
10005
					case Scope.METHOD_SCOPE :
10006
						// handle the error case inside an explicit constructor call (see MethodScope>>findField)
10007
						MethodScope methodScope = (MethodScope) currentScope;
10008
						staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
10009
						break;
10010
					case Scope.CLASS_SCOPE :
10011
						ClassScope classScope = (ClassScope) currentScope;
10012
						SourceTypeBinding enclosingType = classScope.referenceContext.binding;
10013
						/*				if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
10014
											findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
10015
											findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
10016
											break done;
10017
										} else { */
10018
						if(!insideTypeAnnotation) {
10019
							if(proposeField) {
10020
								findFields(
10021
									token,
10022
									enclosingType,
10023
									classScope,
10024
									fieldsFound,
10025
									localsFound,
10026
									staticsOnly,
10027
									invocationSite,
10028
									invocationScope,
10029
									true,
10030
									true,
10031
									null,
10032
									null,
10033
									null,
10034
									false,
10035
									null,
10036
									-1,
10037
									-1);
10038
							}
10039
							if(proposeMethod && !insideAnnotationAttribute) {
10040
								findMethods(
10041
									token,
10042
									null,
10043
									null,
10044
									enclosingType,
10045
									classScope,
10046
									methodsFound,
10047
									staticsOnly,
10048
									false,
10049
									invocationSite,
10050
									invocationScope,
10051
									true,
10052
									false,
10053
									true,
10054
									null,
10055
									null,
10056
									null,
10057
									false,
10058
									null,
10059
									-1,
10060
									-1);
10061
							}
10062
						}
10063
						staticsOnly |= enclosingType.isStatic();
10064
						insideTypeAnnotation = false;
10065
						//				}
10066
						break;
9775
10067
9776
			for (int j = 0; j < length; j++) {
10068
					case Scope.COMPILATION_UNIT_SCOPE :
9777
				Expression argument = arguments[j];
10069
						break done2;
9778
				TypeBinding argType = argument.resolvedType;
10070
				}
9779
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
10071
				currentScope = currentScope.parent;
9780
					continue nextMethod;
9781
			}
10072
			}
10073
			
10074
			checkCancel();
10075
			
10076
			findFieldsAndMethodsFromStaticImports(
10077
					token,
10078
					scope,
10079
					invocationSite,
10080
					invocationScope,
10081
					false,
10082
					insideAnnotationAttribute,
10083
					localsFound,
10084
					fieldsFound,
10085
					methodsFound,
10086
					proposeField,
10087
					proposeMethod);
9782
10088
9783
			TypeBinding expectedType = method.parameters[arguments.length - 1];
10089
			if (this.assistNodeInJavadoc == 0) {
9784
			if(expectedType != null) {
10090
				
9785
				addExpectedType(expectedType, scope);
10091
				checkCancel();
10092
				
10093
				// search in favorites import
10094
				findFieldsAndMethodsFromFavorites(
10095
						token,
10096
						scope,
10097
						invocationSite,
10098
						invocationScope,
10099
						localsFound,
10100
						fieldsFound,
10101
						methodsFound);
9786
			}
10102
			}
10103
			
10104
			checkCancel();
10105
			
10106
			findEnumConstantsFromExpectedTypes(
10107
					token,
10108
					invocationScope,
10109
					fieldsFound);
9787
		}
10110
		}
9788
	}
10111
	}
9789
10112
9790
	private void computeExpectedTypesForMessageSendForInterface(
10113
	private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
9791
		ReferenceBinding binding,
10114
		char[] result = null;
9792
		char[] selector,
10115
		StringBuffer sig = new StringBuffer(10);
9793
		Expression[] arguments,
10116
		if (!referenceBinding.isMemberType()) {
9794
		ReferenceBinding receiverType,
10117
			char[] typeSig = referenceBinding.genericTypeSignature();
9795
		Scope scope,
10118
			sig.append(typeSig, 0, typeSig.length);
9796
		InvocationSite invocationSite,
10119
		} else if (!this.insideQualifiedReference) {
9797
		boolean isStatic) {
10120
			if (referenceBinding.isStatic()) {
10121
				char[] typeSig = referenceBinding.signature();
10122
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9798
10123
9799
		ReferenceBinding[] itsInterfaces = binding.superInterfaces();
10124
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9800
		if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
10125
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9801
			ReferenceBinding[] interfacesToVisit = itsInterfaces;
10126
				    sig.append(Signature.C_GENERIC_START);
9802
			int nextPosition = interfacesToVisit.length;
10127
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
10128
				        sig.append(typeVariables[i].genericTypeSignature());
10129
				    }
10130
				    sig.append(Signature.C_GENERIC_END);
10131
				}
10132
				sig.append(Signature.C_SEMICOLON);
10133
			} else {
10134
				char[] typeSig = referenceBinding.genericTypeSignature();
10135
				sig.append(typeSig, 0, typeSig.length);
10136
			}
10137
		} else {
10138
			ReferenceBinding enclosingType = referenceBinding.enclosingType();
10139
			if (enclosingType.isParameterizedType()) {
10140
				char[] typeSig = referenceBinding.genericTypeSignature();
10141
				sig.append(typeSig, 0, typeSig.length-1);
9803
10142
9804
			for (int i = 0; i < nextPosition; i++) {
10143
				TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9805
				ReferenceBinding currentType = interfacesToVisit[i];
10144
				if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9806
				computeExpectedTypesForMessageSend(
10145
				    sig.append(Signature.C_GENERIC_START);
9807
					currentType,
10146
				    for (int i = 0, length = typeVariables.length; i < length; i++) {
9808
					selector,
10147
				        sig.append(typeVariables[i].genericTypeSignature());
9809
					arguments,
10148
				    }
9810
					receiverType,
10149
				    sig.append(Signature.C_GENERIC_END);
9811
					scope,
10150
				}
9812
					invocationSite,
10151
			} else {
9813
					isStatic);
10152
				char[] typeSig = referenceBinding.signature();
10153
				sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
9814
10154
9815
				if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
10155
				if (referenceBinding.isStatic()) {
9816
					int itsLength = itsInterfaces.length;
10156
					TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
9817
					if (nextPosition + itsLength >= interfacesToVisit.length)
10157
					if (typeVariables != Binding.NO_TYPE_VARIABLES) {
9818
						System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
10158
					    sig.append(Signature.C_GENERIC_START);
9819
					nextInterface : for (int a = 0; a < itsLength; a++) {
10159
					    for (int i = 0, length = typeVariables.length; i < length; i++) {
9820
						ReferenceBinding next = itsInterfaces[a];
10160
					        sig.append(typeVariables[i].genericTypeSignature());
9821
						for (int b = 0; b < nextPosition; b++)
10161
					    }
9822
							if (next == interfacesToVisit[b]) continue nextInterface;
10162
					    sig.append(Signature.C_GENERIC_END);
9823
						interfacesToVisit[nextPosition++] = next;
9824
					}
10163
					}
9825
				}
10164
				}
9826
			}
10165
			}
10166
			sig.append(Signature.C_SEMICOLON);
9827
		}
10167
		}
10168
		int sigLength = sig.length();
10169
		result = new char[sigLength];
10170
		sig.getChars(0, sigLength, result, 0);
10171
		result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
10172
		return result;
9828
	}
10173
	}
9829
10174
9830
	private void computeExpectedTypesForMessageSend(
10175
	private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
9831
		ReferenceBinding binding,
10176
		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
10177
9839
		MethodBinding[] methods = binding.availableMethods();
10178
		String[] favoriteReferences = this.requestor.getFavoriteReferences();
9840
		nextMethod : for (int i = 0; i < methods.length; i++) {
9841
			MethodBinding method = methods[i];
9842
10179
9843
			if (method.isSynthetic()) continue nextMethod;
10180
		if (favoriteReferences == null || favoriteReferences.length == 0) return null;
9844
10181
9845
			if (method.isDefaultAbstract())	continue nextMethod;
10182
		ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
9846
10183
9847
			if (method.isConstructor()) continue nextMethod;
10184
		int count = 0;
10185
		next : for (int i = 0; i < favoriteReferences.length; i++) {
10186
			String favoriteReference = favoriteReferences[i];
9848
10187
9849
			if (isStatic && !method.isStatic()) continue nextMethod;
10188
			int length;
10189
			if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
9850
10190
9851
			if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
10191
			boolean onDemand = favoriteReference.charAt(length - 1) == '*';
9852
10192
9853
			if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
10193
			char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
10194
			if (onDemand) {
10195
				compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
10196
			}
9854
10197
9855
			TypeBinding[] parameters = method.parameters;
10198
			// remove duplicate and conflicting
9856
			if(parameters.length < arguments.length)
10199
			for (int j = 0; j < count; j++) {
9857
				continue nextMethod;
10200
				ImportReference f = resolvedImports[j].reference;
9858
10201
9859
			int length = arguments.length - 1;
10202
				if (CharOperation.equals(f.tokens, compoundName)) continue next;
9860
10203
9861
			for (int j = 0; j < length; j++) {
10204
				if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
9862
				Expression argument = arguments[j];
10205
					if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
9863
				TypeBinding argType = argument.resolvedType;
10206
						continue next;
9864
				if(argType != null && !argType.isCompatibleWith(parameters[j]))
10207
				}
9865
					continue nextMethod;
9866
			}
10208
			}
9867
10209
9868
			TypeBinding expectedType = method.parameters[arguments.length - 1];
10210
			boolean isStatic = true;
9869
			if(expectedType != null) {
10211
9870
				addExpectedType(expectedType, scope);
10212
			ImportReference importReference =
10213
				new ImportReference(
10214
						compoundName,
10215
						new long[compoundName.length],
10216
						onDemand,
10217
						isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
10218
10219
			Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
10220
10221
			if (!importBinding.isValidBinding()) {
10222
				continue next;
9871
			}
10223
			}
9872
		}
9873
	}
9874
	private void addExpectedType(TypeBinding type, Scope scope){
9875
		if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
9876
10224
9877
		// do not add twice the same type
10225
			if (importBinding instanceof PackageBinding) {
9878
		for (int i = 0; i <= this.expectedTypesPtr; i++) {
10226
				continue next;
9879
			if (this.expectedTypes[i] == type) return;
10227
			}
10228
10229
			resolvedImports[count++] =
10230
				new ImportBinding(compoundName, onDemand, importBinding, importReference);
9880
		}
10231
		}
9881
10232
9882
		int length = this.expectedTypes.length;
10233
		if (resolvedImports.length > count)
9883
		if (++this.expectedTypesPtr >= length)
10234
			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
10235
9887
		if(type == scope.getJavaLangObject()) {
10236
		return this.favoriteReferenceBindings = resolvedImports;
9888
			this.hasJavaLangObjectAsExpectedType = true;
9889
		}
9890
	}
10237
	}
9891
	private void addForbiddenBindings(Binding binding){
9892
		if (binding == null) return;
9893
10238
9894
		int length = this.forbbidenBindings.length;
10239
	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
10240
9902
		int length = this.uninterestingBindings.length;
10241
		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
	}
10242
	}
9907
10243
	protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
9908
	private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
10244
		if (this.targetedElement == TagBits.AnnotationForPackage) {
9909
		this.forbbidenBindingsFilter = NONE;
10245
			long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9910
		if(scope instanceof ClassScope) {
10246
			if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
9911
			TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
10247
				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
			}
10248
			}
9924
		} else {
10249
		} else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
9925
			if (astNodeParent != null && astNodeParent instanceof TryStatement) {
10250
			if (scope.parent != null &&
9926
				boolean isException = false;
10251
					scope.parent.parent != null &&
9927
				if (astNode instanceof CompletionOnSingleTypeReference) {
10252
					scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
9928
					isException = ((CompletionOnSingleTypeReference)astNode).isException();
10253
					scope.parent.parent instanceof CompilationUnitScope) {
9929
				} else if (astNode instanceof CompletionOnQualifiedTypeReference) {
10254
				long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
9930
					isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
10255
				if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
9931
				} else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
10256
					if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
9932
					isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
10257
						return false;
9933
				}
10258
					}
9934
				if (isException) {
10259
				} else {
9935
					Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
10260
					if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
9936
					int length = catchArguments == null ? 0 : catchArguments.length;
10261
						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
					}
10262
					}
9944
					this.forbbidenBindingsFilter = SUBTYPE;
9945
				}
10263
				}
9946
			}
10264
			}
9947
		}
10265
		}
9948
//		else if(scope instanceof MethodScope) {
10266
		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
	}
10267
	}
9985
10268
	/**
9986
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10269
	 * Returns completion string inserted inside a specified inline tag.
9987
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10270
	 * @param completionName
9988
			int relevance = computeBaseRelevance();
10271
	 * @return char[] Completion text inclunding specified inline tag
9989
			relevance += computeRelevanceForResolution();
10272
	 */
9990
			relevance += computeRelevanceForInterestingProposal();
10273
	private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
9991
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
10274
		int tagLength= inlineTag.length;
9992
10275
		int completionLength = completionName.length;
9993
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10276
		int inlineLength = 2+tagLength+1+completionLength+1;
9994
			proposal.setDeclarationSignature(getSignature(reference));
10277
		char[] inlineCompletion = new char[inlineLength];
9995
			proposal.setSignature(
10278
		inlineCompletion[0] = '{';
9996
					createMethodSignature(
10279
		inlineCompletion[1] = '@';
9997
							CharOperation.NO_CHAR_CHAR,
10280
		System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
9998
							CharOperation.NO_CHAR_CHAR,
10281
		inlineCompletion[tagLength+2] = ' ';
9999
							CharOperation.NO_CHAR,
10282
		System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
10000
							VOID));
10283
		// 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());
10284
		//inlineCompletion[inlineLength-2] = ' ';
10002
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10285
		inlineCompletion[inlineLength-1] = '}';
10003
10286
		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
	}
10287
	}
10021
	private boolean isForbidden(Binding binding) {
10288
	private boolean isForbidden(Binding binding) {
10022
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
10289
		for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
Lines 10033-10038 Link Here
10033
		}
10300
		}
10034
		return false;
10301
		return false;
10035
	}
10302
	}
10303
10304
	private boolean isIgnored(int kind) {
10305
		return this.requestor.isIgnored(kind);
10306
	}
10307
	private boolean isIgnored(int kind, boolean missingTypes) {
10308
		return this.requestor.isIgnored(kind) ||
10309
			(missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
10310
	}
10311
10312
	private boolean isIgnored(int kind, int requiredProposalKind) {
10313
		return this.requestor.isIgnored(kind) ||
10314
			!this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
10315
	}
10036
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10316
	private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
10037
10317
10038
		if(parent instanceof ParameterizedSingleTypeReference) {
10318
		if(parent instanceof ParameterizedSingleTypeReference) {
Lines 10112-10371 Link Here
10112
		}
10392
		}
10113
		return true;
10393
		return true;
10114
	}
10394
	}
10115
	public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
10395
	private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
10116
		return Signature.createCharArrayTypeSignature(
10396
		StringBuffer prefix = new StringBuffer();
10117
				CharOperation.concat(
10397
		prefix.append("public class FakeType {\n "); //$NON-NLS-1$
10118
						qualifiedPackageName,
10398
		if(isStatic) {
10119
						CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
10399
			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
		}
10400
		}
10280
10401
		prefix.append("{\n"); //$NON-NLS-1$
10281
		// Create javadoc text proposal if necessary
10402
		for (int i = 0; i < localVariableTypeNames.length; i++) {
10282
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10403
			ASTNode.printModifiers(localVariableModifiers[i], prefix);
10283
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10404
			prefix.append(' ');
10284
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10405
			prefix.append(localVariableTypeNames[i]);
10285
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10406
			prefix.append(' ');
10286
			proposal.completionEngine = this;
10407
			prefix.append(localVariableNames[i]);
10287
			proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
10408
			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
		}
10409
		}
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
10410
10310
		// Create standard type proposal
10411
		char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
10311
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10412
		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
10413
10328
		// Create javadoc text proposal if necessary
10414
		String encoding = this.compilerOptions.defaultEncoding;
10329
		if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
10415
		BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
10330
			char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
10416
			fakeSource,
10331
			InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
10417
			null,
10332
			proposal.nameLookup = this.nameEnvironment.nameLookup;
10418
			"FakeType.java", //$NON-NLS-1$
10333
			proposal.completionEngine = this;
10419
			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
10420
10348
	/**
10421
		this.actualCompletionPosition = prefix.length() + position - 1;
10349
	 * Returns completion string inserted inside a specified inline tag.
10422
10350
	 * @param completionName
10423
		CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
10351
	 * @return char[] Completion text inclunding specified inline tag
10424
		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
10425
10426
		parseBlockStatements(fakeAST, this.actualCompletionPosition);
10427
10428
		return (Initializer)fakeAST.types[0].fields[0];
10429
	}
10369
	protected void printDebug(CategorizedProblem error) {
10430
	protected void printDebug(CategorizedProblem error) {
10370
		if(CompletionEngine.DEBUG) {
10431
		if(CompletionEngine.DEBUG) {
10371
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
10432
			System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
Lines 10373-10390 Link Here
10373
			System.out.println(")"); //$NON-NLS-1$
10434
			System.out.println(")"); //$NON-NLS-1$
10374
		}
10435
		}
10375
	}
10436
	}
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){
10437
	protected void printDebug(CompletionProposal proposal){
10384
		StringBuffer buffer = new StringBuffer();
10438
		StringBuffer buffer = new StringBuffer();
10385
		printDebug(proposal, 0, buffer);
10439
		printDebug(proposal, 0, buffer);
10386
		System.out.println(buffer.toString());
10440
		System.out.println(buffer.toString());
10387
	}
10441
	}
10442
10388
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10443
	private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
10389
		printDebugTab(tab, buffer);
10444
		printDebugTab(tab, buffer);
10390
		buffer.append("COMPLETION - "); //$NON-NLS-1$
10445
		buffer.append("COMPLETION - "); //$NON-NLS-1$
Lines 10509-10550 Link Here
10509
		buffer.append("}\n");//$NON-NLS-1$
10564
		buffer.append("}\n");//$NON-NLS-1$
10510
	}
10565
	}
10511
10566
10512
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10567
	private void printDebugTab(int tab, StringBuffer buffer) {
10513
		char[][] substituedParameterNames = new char[typeVariables.length][];
10568
		for (int i = 0; i < tab; i++) {
10569
			buffer.append('\t');
10570
		}
10571
	}
10514
10572
10515
		for (int i = 0; i < substituedParameterNames.length; i++) {
10573
	private void proposeNewMethod(char[] token, ReferenceBinding reference) {
10516
			substituedParameterNames[i] = typeVariables[i].sourceName;
10574
		if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
10575
			int relevance = computeBaseRelevance();
10576
			relevance += computeRelevanceForResolution();
10577
			relevance += computeRelevanceForInterestingProposal();
10578
			relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
10579
10580
			InternalCompletionProposal proposal =  createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
10581
			proposal.setDeclarationSignature(getSignature(reference));
10582
			proposal.setSignature(
10583
					createMethodSignature(
10584
							CharOperation.NO_CHAR_CHAR,
10585
							CharOperation.NO_CHAR_CHAR,
10586
							CharOperation.NO_CHAR,
10587
							VOID));
10588
			proposal.setDeclarationPackageName(reference.qualifiedPackageName());
10589
			proposal.setDeclarationTypeName(reference.qualifiedSourceName());
10590
10591
			//proposal.setPackageName(null);
10592
			proposal.setTypeName(VOID);
10593
			proposal.setName(token);
10594
			//proposal.setParameterPackageNames(null);
10595
			//proposal.setParameterTypeNames(null);
10596
			//proposal.setPackageName(null);
10597
			proposal.setCompletion(token);
10598
			proposal.setFlags(Flags.AccPublic);
10599
			proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
10600
			proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
10601
			proposal.setRelevance(relevance);
10602
			this.requestor.accept(proposal);
10603
			if(DEBUG) {
10604
				this.printDebug(proposal);
10605
			}
10517
		}
10606
		}
10607
	}
10518
10608
10519
		boolean foundConflicts = false;
10609
	private void proposeType(
10610
			char[] packageName,
10611
			char[] simpleTypeName,
10612
			int modifiers,
10613
			int accessibility,
10614
			char[] typeName,
10615
			char[] fullyQualifiedName,
10616
			boolean isQualified,
10617
			Scope scope) {
10618
		char[] completionName = fullyQualifiedName;
10619
		if(isQualified) {
10620
			if (packageName == null || packageName.length == 0)
10621
				if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
10622
					return; // ignore types from the default package from outside it
10623
		} else {
10624
			completionName = simpleTypeName;
10625
		}
10520
10626
10521
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10627
		TypeBinding guessedType = null;
10522
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10628
		if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
10523
			char[] methodParameterName = typeVariableBinding.sourceName;
10629
				this.assistNodeIsAnnotation &&
10630
				(this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
10631
			char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
10524
10632
10525
			for (int j = 0; j < excludedNames.length; j++) {
10633
			TypeReference ref;
10526
				char[] typeParameterName = excludedNames[j];
10634
			if (cn.length == 1) {
10527
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10635
				ref = new SingleTypeReference(simpleTypeName, 0);
10528
					char[] substitution;
10636
			} else {
10529
					if(methodParameterName.length == 1) {
10637
				ref = new QualifiedTypeReference(cn,new long[cn.length]);
10530
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10638
			}
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
10639
10540
					foundConflicts = true;
10640
			switch (scope.kind) {
10541
					continue nextTypeParameter;
10641
				case Scope.METHOD_SCOPE :
10542
				}
10642
				case Scope.BLOCK_SCOPE :
10643
					guessedType = ref.resolveType((BlockScope)scope);
10644
					break;
10645
				case Scope.CLASS_SCOPE :
10646
					guessedType = ref.resolveType((ClassScope)scope);
10647
					break;
10543
			}
10648
			}
10649
10650
			if (guessedType == null || !guessedType.isValidBinding()) return;
10651
10652
			if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
10544
		}
10653
		}
10545
10654
10546
		if(foundConflicts) return substituedParameterNames;
10655
		int relevance = computeBaseRelevance();
10547
		return null;
10656
		relevance += computeRelevanceForResolution();
10657
		relevance += computeRelevanceForInterestingProposal();
10658
		relevance += computeRelevanceForRestrictions(accessibility);
10659
		relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
10660
		relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
10661
		relevance += computeRelevanceForQualification(isQualified);
10662
10663
		int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
10664
		switch (kind) {
10665
			case ClassFileConstants.AccAnnotation:
10666
			case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
10667
				relevance += computeRelevanceForAnnotation();
10668
				if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
10669
				relevance += computeRelevanceForInterface();
10670
				break;
10671
			case ClassFileConstants.AccEnum:
10672
				relevance += computeRelevanceForEnum();
10673
				break;
10674
			case ClassFileConstants.AccInterface:
10675
				relevance += computeRelevanceForInterface();
10676
				break;
10677
			default:
10678
				relevance += computeRelevanceForClass();
10679
				relevance += computeRelevanceForException(simpleTypeName);
10680
				break;
10681
		}
10682
10683
		this.noProposal = false;
10684
		if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
10685
			createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
10686
		}
10687
	}
10688
10689
	protected void reset() {
10690
10691
		super.reset(false);
10692
		this.knownPkgs = new HashtableOfObject(10);
10693
		this.knownTypes = new HashtableOfObject(10);
10694
	}
10695
10696
	private void setSourceAndTokenRange(int start, int end) {
10697
		this.setSourceAndTokenRange(start, end, true);
10698
	}
10699
10700
	private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10701
		this.setSourceRange(start, end, emptyTokenAdjstment);
10702
		this.setTokenRange(start, end, emptyTokenAdjstment);
10703
	}
10704
10705
	private void setSourceRange(int start, int end) {
10706
		this.setSourceRange(start, end, true);
10707
	}
10708
10709
	private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
10710
		this.startPosition = start;
10711
		if(emptyTokenAdjstment) {
10712
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10713
			this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10714
		} else {
10715
			this.endPosition = end + 1;
10716
		}
10717
	}
10718
10719
	private void setTokenRange(int start, int end) {
10720
		this.setTokenRange(start, end, true);
10721
	}
10722
	private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
10723
		this.tokenStart = start;
10724
		if(emptyTokenAdjstment) {
10725
			int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
10726
			this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
10727
		} else {
10728
			this.tokenEnd = end + 1;
10729
		}
10548
	}
10730
	}
10549
10731
10550
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
10732
	private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
Lines 10596-10599 Link Here
10596
		}
10778
		}
10597
		return name;
10779
		return name;
10598
	}
10780
	}
10781
10782
	private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
10783
		char[][] substituedParameterNames = new char[typeVariables.length][];
10784
10785
		for (int i = 0; i < substituedParameterNames.length; i++) {
10786
			substituedParameterNames[i] = typeVariables[i].sourceName;
10787
		}
10788
10789
		boolean foundConflicts = false;
10790
10791
		nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
10792
			TypeVariableBinding typeVariableBinding = typeVariables[i];
10793
			char[] methodParameterName = typeVariableBinding.sourceName;
10794
10795
			for (int j = 0; j < excludedNames.length; j++) {
10796
				char[] typeParameterName = excludedNames[j];
10797
				if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
10798
					char[] substitution;
10799
					if(methodParameterName.length == 1) {
10800
						if(ScannerHelper.isUpperCase(methodParameterName[0])) {
10801
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
10802
						} else {
10803
							substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
10804
						}
10805
					} else {
10806
						substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
10807
					}
10808
					substituedParameterNames[i] = substitution;
10809
10810
					foundConflicts = true;
10811
					continue nextTypeParameter;
10812
				}
10813
			}
10814
		}
10815
10816
		if(foundConflicts) return substituedParameterNames;
10817
		return null;
10818
	}
10599
}
10819
}
(-)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=247433
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=247433
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