### Eclipse Workspace Patch 1.0
#P org.eclipse.jdt.core.tests.model
Index: src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java,v
retrieving revision 1.31
diff -u -r1.31 CompletionTestsRequestor2.java
--- src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java 23 Jul 2008 13:25:31 -0000 1.31
+++ src/org/eclipse/jdt/core/tests/model/CompletionTestsRequestor2.java 29 Sep 2008 09:48:13 -0000
@@ -38,10 +38,13 @@
private boolean shortContext;
private boolean showMissingTypes;
private boolean showModifiers;
+ private boolean showAddionnalFlags;
private boolean computeVisibleElements;
private boolean computeEnclosingElement;
private String assignableType;
+
+ private boolean canceled;
public boolean debug = false;
@@ -89,6 +92,9 @@
public void acceptContext(CompletionContext cc) {
this.context = cc;
}
+ public void aborting() {
+ this.canceled = true;
+ }
public void accept(CompletionProposal proposal) {
int length = this.proposals.length;
if (++this.proposalsPtr== length) {
@@ -298,6 +304,9 @@
return strings;
}
+ public boolean isCanceled() {
+ return this.canceled;
+ }
protected StringBuffer printProposal(CompletionProposal proposal) {
StringBuffer buffer = new StringBuffer();
return printProposal(proposal, 0, buffer);
@@ -466,6 +475,11 @@
buffer.append(" deprecated"); //$NON-NLS-1$
}
}
+ if(this.showAddionnalFlags) {
+ int additionalFlags = proposal.getAdditionalFlags();
+ buffer.append(", ");
+ buffer.append(Flags.toString(additionalFlags));
+ }
buffer.append(", ");
buffer.append(proposal.getRelevance());
buffer.append('}');
@@ -590,4 +604,7 @@
public void setComputeEnclosingElement(boolean computeEnclosingElement) {
this.computeEnclosingElement = computeEnclosingElement;
}
+ public void setShowAdditionnalFlags(boolean show) {
+ this.showAddionnalFlags = show;
+ }
}
Index: src/org/eclipse/jdt/core/tests/model/CompletionTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java,v
retrieving revision 1.188
diff -u -r1.188 CompletionTests.java
--- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 9 Sep 2008 12:43:37 -0000 1.188
+++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 29 Sep 2008 09:48:13 -0000
@@ -55,6 +55,58 @@
char[] varClassName = ((EvaluationContextWrapper)context).getVarClassName();
return Signature.createTypeSignature(varClassName, true);
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247433
+public void testAbortCompletion1() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/CompletionBasicType1.java",
+ "public class CompletionBasicType1 {\n"+
+ " void foo() {\n"+
+ " Objec\n"+
+ " }\n"+
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+ requestor.setShowAdditionnalFlags(true);
+ requestor.setThreshold(-1);
+
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "Objec";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+ assertTrue("Completion abort", !requestor.isCanceled());
+ assertResults(
+ "Object[TYPE_REF]{Object, java.lang, Ljava.lang.Object;, null, , " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
+ requestor.getResults());
+}
+
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=247433
+public void testAbortCompletion2() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/CompletionBasicType1.java",
+ "public class CompletionBasicType1 {\n"+
+ " void foo() {\n"+
+ " Objec\n"+
+ " }\n"+
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2();
+ requestor.setShowAdditionnalFlags(true);
+ requestor.setThreshold(0); // force completion to abort
+
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "Objec";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+
+ assertTrue("Completion did not abort", requestor.isCanceled());
+ assertResults(
+ "",
+ requestor.getResults());
+}
+
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=164311
public void testBug164311() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
#P org.eclipse.jdt.core
Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java,v
retrieving revision 1.198
diff -u -r1.198 CompletionParser.java
--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 23 Jul 2008 09:48:45 -0000 1.198
+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 29 Sep 2008 09:48:16 -0000
@@ -1554,9 +1554,9 @@
System.arraycopy(labels, 0, labels = new char[labelCount][], 0, labelCount);
long position = this.identifierPositionStack[this.identifierPtr];
- CompletionOnBrankStatementLabel statementLabel =
- new CompletionOnBrankStatementLabel(
- kind == K_INSIDE_BREAK_STATEMENT ? CompletionOnBrankStatementLabel.BREAK : CompletionOnBrankStatementLabel.CONTINUE,
+ CompletionOnBranchStatementLabel statementLabel =
+ new CompletionOnBranchStatementLabel(
+ kind == K_INSIDE_BREAK_STATEMENT ? CompletionOnBranchStatementLabel.BREAK : CompletionOnBranchStatementLabel.CONTINUE,
this.identifierStack[this.identifierPtr--],
(int) (position >>> 32),
(int)position,
Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBrankStatementLabel.java
===================================================================
RCS file: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBrankStatementLabel.java
diff -N codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBrankStatementLabel.java
--- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBrankStatementLabel.java 27 Jun 2008 16:03:59 -0000 1.4
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,52 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.codeassist.complete;
-
-import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
-import org.eclipse.jdt.internal.compiler.flow.FlowContext;
-import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
-import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
-
-public class CompletionOnBrankStatementLabel extends BranchStatement {
- public static final int BREAK = 1;
- public static final int CONTINUE = 2;
-
- private int kind;
- public char[][] possibleLabels;
-
- public CompletionOnBrankStatementLabel(int kind, char[] l, int s, int e, char[][] possibleLabels) {
- super(l, s, e);
- this.kind = kind;
- this.possibleLabels = possibleLabels;
- }
-
- public FlowInfo analyseCode(BlockScope currentScope,
- FlowContext flowContext, FlowInfo flowInfo) {
- // Is never called
- return null;
- }
-
- public void resolve(BlockScope scope) {
- throw new CompletionNodeFound(this, scope);
- }
- public StringBuffer printStatement(int indent, StringBuffer output) {
- printIndent(indent, output);
- if(this.kind == CONTINUE) {
- output.append("continue "); //$NON-NLS-1$
- } else {
- output.append("break "); //$NON-NLS-1$
- }
- output.append(";"); //$NON-NLS-1$
- }
-
-}
Index: model/org/eclipse/jdt/core/CompletionRequestor.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionRequestor.java,v
retrieving revision 1.18
diff -u -r1.18 CompletionRequestor.java
--- model/org/eclipse/jdt/core/CompletionRequestor.java 27 Jun 2008 16:04:01 -0000 1.18
+++ model/org/eclipse/jdt/core/CompletionRequestor.java 29 Sep 2008 09:48:17 -0000
@@ -43,6 +43,20 @@
* endReporting
calls are always made as well as
* acceptContext
call.
*
+ *
+ * Since 3.5 the completion can abort before reporting all the possible proposals.
+ * This event is notified by a call to {@link #aborting()}.
+ * Proposals proposed after this notification are not guarantee to be optimum (see {@link #aborting()}).
+ * In this case, the sequence of calls is:
+ *
+ * requestor.beginReporting();
+ * requestor.acceptContext(context);
+ * requestor.accept(proposal_1);
+ * requestor.accept(proposal_2);
+ * requestor.aborting();
+ * requestor.accept(proposal_3);
+ * requestor.endReporting();
+ *
*
* The class was introduced in 3.0 as a more evolvable replacement
* for the ICompletionRequestor
interface.
@@ -70,6 +84,8 @@
private int requiredProposalAllowSet[] = null;
private boolean requireExtendedContext = false;
+
+ private long threshold = -1;
/**
* Creates a new completion requestor.
@@ -241,6 +257,19 @@
public String[] getFavoriteReferences() {
return this.favoriteReferences;
}
+
+
+ /**
+ * Returns the threshold in milliseconds beyond which the completion must abort as soon as possible.
+ * Returns -1
when there is no time limit to finish the completion process.
+ *
+ * When this threshold is reached a notification will be sent to the requestor by calling {@link #aborting()}
+ *
+ * @since 3.5
+ */
+ public long getThreshold() {
+ return this.threshold;
+ }
/**
* Set the favorite references which will be used to compute some completion proposals.
@@ -293,6 +322,23 @@
public void completionFailure(IProblem problem) {
// default behavior is to ignore
}
+
+ /**
+ * Notify that the completion will abort as soon as possible.
+ *
+ * Proposals proposed after this notification are not guaranteed to be optimum:
+ *
+ * - Type references can be qualified even if it's not necessary.
+ *
+ * The default implementation of this method does nothing.
+ * Clients may override.
+ *
+ *
+ * @since 3.5
+ */
+ public void aborting() {
+ // do nothing
+ }
/**
* Proposes a completion. Has no effect if the kind of proposal
@@ -355,4 +401,16 @@
public void setRequireExtendedContext(boolean require) {
this.requireExtendedContext = require;
}
+
+ /**
+ * Sets the threshold in milliseconds beyond which the completion must abort as soon as possible,
+ * or -1
if there is no time limit to finish the completion process;
+ *
+ * @param threshold the threshold in milliseconds
+ *
+ * @since 3.5
+ */
+ public void setThreshold(long threshold) {
+ this.threshold = threshold;
+ }
}
Index: model/org/eclipse/jdt/core/CompletionFlags.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/CompletionFlags.java,v
retrieving revision 1.2
diff -u -r1.2 CompletionFlags.java
--- model/org/eclipse/jdt/core/CompletionFlags.java 27 Jun 2008 16:04:01 -0000 1.2
+++ model/org/eclipse/jdt/core/CompletionFlags.java 29 Sep 2008 09:48:17 -0000
@@ -31,6 +31,12 @@
* Constant representing a static import
*/
public static final int StaticImport = 0x0001;
+
+ /**
+ * Constant representing a non optimal proposal.
+ * eg. the proposal contains a qualified type reference which could be unqualified.
+ */
+ public static final int NotOptimum = 0x0002;
/**
* Not instantiable.
@@ -48,4 +54,29 @@
public static boolean isStaticImport(int flags) {
return (flags & StaticImport) != 0;
}
+
+ /**
+ * Returns whether the given integer includes the {@link #NotOptimum} flag.
+ *
+ * @param flags the flags
+ * @return true
if the {@link #NotOptimum} flag is included
+ */
+ public static boolean isNotOptimum(int flags) {
+ return (flags & NotOptimum) != 0;
+ }
+
+ public static String toString(int flags) {
+ StringBuffer sb = new StringBuffer();
+
+ if (isStaticImport(flags))
+ sb.append("StaticImport "); //$NON-NLS-1$
+ if (isNotOptimum(flags))
+ sb.append("NotOptimum "); //$NON-NLS-1$
+
+ int len = sb.length();
+ if (len == 0)
+ return ""; //$NON-NLS-1$
+ sb.setLength(len - 1);
+ return sb.toString();
+ }
}
Index: codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java,v
retrieving revision 1.377
diff -u -r1.377 CompletionEngine.java
--- codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 25 Sep 2008 23:10:30 -0000 1.377
+++ codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java 29 Sep 2008 09:48:15 -0000
@@ -74,6 +74,46 @@
extends Engine
implements ISearchRequestor, TypeConstants , TerminalTokens , RelevanceConstants, SuffixConstants {
+ static class AbortCompletion extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+ }
+
+ private static class AcceptedType {
+ public char[] packageName;
+ public char[] simpleTypeName;
+ public char[][] enclosingTypeNames;
+ public int modifiers;
+ public int accessibility;
+ public boolean mustBeQualified = false;
+
+ public char[] fullyQualifiedName = null;
+ public char[] qualifiedTypeName = null;
+ public AcceptedType(
+ char[] packageName,
+ char[] simpleTypeName,
+ char[][] enclosingTypeNames,
+ int modifiers,
+ int accessibility) {
+ this.packageName = packageName;
+ this.simpleTypeName = simpleTypeName;
+ this.enclosingTypeNames = enclosingTypeNames;
+ this.modifiers = modifiers;
+ this.accessibility = accessibility;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('{');
+ buffer.append(this.packageName);
+ buffer.append(',');
+ buffer.append(this.simpleTypeName);
+ buffer.append(',');
+ buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
+ buffer.append('}');
+ return buffer.toString();
+ }
+ }
+
public class CompletionProblemFactory extends DefaultProblemFactory {
private int lastErrorStart;
@@ -133,6 +173,7 @@
char[] originatingFileName,
int problemId,
String[] problemArguments,
+ int elaborationId,
String[] messageArguments,
int severity,
int start,
@@ -144,6 +185,7 @@
originatingFileName,
problemId,
problemArguments,
+ elaborationId,
messageArguments,
severity,
start,
@@ -156,7 +198,6 @@
char[] originatingFileName,
int problemId,
String[] problemArguments,
- int elaborationId,
String[] messageArguments,
int severity,
int start,
@@ -168,7 +209,6 @@
originatingFileName,
problemId,
problemArguments,
- elaborationId,
messageArguments,
severity,
start,
@@ -188,67 +228,105 @@
}
}
- private static class AcceptedType {
- public AcceptedType(
- char[] packageName,
- char[] simpleTypeName,
- char[][] enclosingTypeNames,
- int modifiers,
- int accessibility) {
- this.packageName = packageName;
- this.simpleTypeName = simpleTypeName;
- this.enclosingTypeNames = enclosingTypeNames;
- this.modifiers = modifiers;
- this.accessibility = accessibility;
+ public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
+ char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
+ for (int i = 0; i < parameterTypeSignature.length; i++) {
+ parameterTypeSignature[i] =
+ Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ parameterPackageNames[i],
+ CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
}
- public char[] packageName;
- public char[] simpleTypeName;
- public char[][] enclosingTypeNames;
- public int modifiers;
- public int accessibility;
- public boolean mustBeQualified = false;
- public char[] fullyQualifiedName = null;
- public char[] qualifiedTypeName = null;
+ return Signature.createMethodSignature(
+ parameterTypeSignature,
+ returnTypeSignature);
+ }
- public String toString() {
- StringBuffer buffer = new StringBuffer();
- buffer.append('{');
- buffer.append(this.packageName);
- buffer.append(',');
- buffer.append(this.simpleTypeName);
- buffer.append(',');
- buffer.append(CharOperation.concatWith(this.enclosingTypeNames, '.'));
- buffer.append('}');
- return buffer.toString();
+ public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
+ char[] returnTypeSignature =
+ returnTypeName == null || returnTypeName.length == 0
+ ? Signature.createCharArrayTypeSignature(VOID, true)
+ : Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ returnPackagename,
+ CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
+
+ return createMethodSignature(
+ parameterPackageNames,
+ parameterTypeNames,
+ returnTypeSignature);
+ }
+ public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+ return Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ qualifiedPackageName,
+ CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
+ }
+
+ public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
+ char[] name = new char[qualifiedTypeName.length];
+ System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
+
+ int depth = 0;
+ int length = name.length;
+ for (int i = length -1; i >= 0; i--) {
+ switch (name[i]) {
+ case '.':
+ if (depth == 0 && name[i - 1] != '>') {
+ name[i] = '$';
+ }
+ break;
+ case '<':
+ depth--;
+ break;
+ case '>':
+ depth++;
+ break;
+ }
}
+ return Signature.createCharArrayTypeSignature(
+ CharOperation.concat(
+ qualifiedPackageName,
+ name, '.'), true);
}
- public HashtableOfObject typeCache;
+ private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
+ char[] result = null;
+ StringBuffer sig = new StringBuffer(10);
+
+ sig.append(typeBinding.signature());
+ int sigLength = sig.length();
+ result = new char[sigLength];
+ sig.getChars(0, sigLength, result, 0);
+ result = CharOperation.replaceOnCopy(result, '/', '.');
+ return result;
+ }
+ public HashtableOfObject typeCache;
public static boolean DEBUG = false;
- public static boolean PERF = false;
+ public static boolean PERF = false;
// temporary constants to quickly disabled polish features if necessary
public final static boolean NO_TYPE_COMPLETION_ON_EMPTY_TOKEN = false;
-
private final static char[] ERROR_PATTERN = "*error*".toCharArray(); //$NON-NLS-1$
private final static char[] EXCEPTION_PATTERN = "*exception*".toCharArray(); //$NON-NLS-1$
private final static char[] SEMICOLON = new char[] { ';' };
-
private final static char[] CLASS = "Class".toCharArray(); //$NON-NLS-1$
private final static char[] VOID = "void".toCharArray(); //$NON-NLS-1$
+
private final static char[] INT = "int".toCharArray(); //$NON-NLS-1$
+
private final static char[] INT_SIGNATURE = new char[]{Signature.C_INT};
+
private final static char[] VALUE = "value".toCharArray(); //$NON-NLS-1$
private final static char[] EXTENDS = "extends".toCharArray(); //$NON-NLS-1$
private final static char[] SUPER = "super".toCharArray(); //$NON-NLS-1$
-
private final static char[] DOT = ".".toCharArray(); //$NON-NLS-1$
private final static char[] VARARGS = "...".toCharArray(); //$NON-NLS-1$
-
private final static char[] IMPORT = "import".toCharArray(); //$NON-NLS-1$
+
private final static char[] STATIC = "static".toCharArray(); //$NON-NLS-1$
private final static char[] ON_DEMAND = ".*".toCharArray(); //$NON-NLS-1$
private final static char[] IMPORT_END = ";\n".toCharArray(); //$NON-NLS-1$
@@ -257,39 +335,37 @@
createTypeSignature(CharOperation.concatWith(JAVA_LANG, '.'), OBJECT);
private final static char[] JAVA_LANG_NAME =
CharOperation.concatWith(JAVA_LANG, '.');
-
private final static int NONE = 0;
+
private final static int SUPERTYPE = 1;
private final static int SUBTYPE = 2;
-
private final static int FIELD = 0;
private final static int LOCAL = 1;
private final static int ARGUMENT = 2;
-
int expectedTypesPtr = -1;
TypeBinding[] expectedTypes = new TypeBinding[1];
int expectedTypesFilter;
boolean hasJavaLangObjectAsExpectedType = false;
+
int uninterestingBindingsPtr = -1;
+
Binding[] uninterestingBindings = new Binding[1];
int forbbidenBindingsPtr = -1;
Binding[] forbbidenBindings = new Binding[1];
int forbbidenBindingsFilter;
-
ImportBinding[] favoriteReferenceBindings;
-
boolean assistNodeIsClass;
boolean assistNodeIsEnum;
boolean assistNodeIsException;
boolean assistNodeIsInterface;
+
boolean assistNodeIsAnnotation;
+
boolean assistNodeIsConstructor;
boolean assistNodeIsSuperType;
int assistNodeInJavadoc = 0;
boolean assistNodeCanBeSingleMemberAnnotation = false;
-
long targetedElement;
-
WorkingCopyOwner owner;
IJavaProject javaProject;
ITypeRoot typeRoot;
@@ -307,13 +383,18 @@
CategorizedProblem problem = null;
char[] fileName = null;
int startPosition, actualCompletionPosition, endPosition, offset;
+
int tokenStart, tokenEnd;
+
int javadocTagPosition; // Position of previous tag while completing in javadoc
HashtableOfObject knownPkgs = new HashtableOfObject(10);
HashtableOfObject knownTypes = new HashtableOfObject(10);
Scanner nameScanner;
-
- /*
+
+ long timeStart;
+ boolean timeoutExceeded;
+
+ /*
static final char[][] mainDeclarations =
new char[][] {
"package".toCharArray(),
@@ -349,23 +430,19 @@
TypeBinding.SHORT,
TypeBinding.VOID
};
+
static final int BASE_TYPES_LENGTH = BASE_TYPES.length;
static final char[][] BASE_TYPE_NAMES = new char[BASE_TYPES_LENGTH][];
static final int BASE_TYPES_WITHOUT_VOID_LENGTH = BASE_TYPES.length - 1;
static final char[][] BASE_TYPE_NAMES_WITHOUT_VOID = new char[BASE_TYPES_WITHOUT_VOID_LENGTH][];
- static {
- for (int i=0; i= ClassFileConstants.JDK1_4 && packageName.length == 0) {
- continue next; // import of default package is forbidden when compliance is 1.4 or higher
+
+ try {
+ next : for (int i = 0; i < length; i++) {
+
+ checkTimeout();
+
+ AcceptedType acceptedType = (AcceptedType)this.acceptedTypes.elementAt(i);
+ char[] packageName = acceptedType.packageName;
+ char[] simpleTypeName = acceptedType.simpleTypeName;
+ char[][] enclosingTypeNames = acceptedType.enclosingTypeNames;
+ int modifiers = acceptedType.modifiers;
+ int accessibility = acceptedType.accessibility;
+
+ char[] typeName;
+ char[] flatEnclosingTypeNames;
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ flatEnclosingTypeNames = null;
+ typeName = simpleTypeName;
+ } else {
+ flatEnclosingTypeNames = CharOperation.concatWith(acceptedType.enclosingTypeNames, '.');
+ typeName = CharOperation.concat(flatEnclosingTypeNames, simpleTypeName, '.');
}
-
- char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
-
- if(this.resolvingStaticImports) {
- if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
- completionName = CharOperation.concat(completionName, new char[] { '.' });
- } else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
- continue next;
+ char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+
+ if (this.knownTypes.containsKey(fullyQualifiedName)) continue next;
+
+ this.knownTypes.put(fullyQualifiedName, this);
+
+ if (this.resolvingImports) {
+ if(this.compilerOptions.complianceLevel >= ClassFileConstants.JDK1_4 && packageName.length == 0) {
+ continue next; // import of default package is forbidden when compliance is 1.4 or higher
+ }
+
+ char[] completionName = this.insideQualifiedReference ? simpleTypeName : fullyQualifiedName;
+
+ if(this.resolvingStaticImports) {
+ if(enclosingTypeNames == null || enclosingTypeNames.length == 0) {
+ completionName = CharOperation.concat(completionName, new char[] { '.' });
+ } else if ((modifiers & ClassFileConstants.AccStatic) == 0) {
+ continue next;
+ } else {
+ completionName = CharOperation.concat(completionName, new char[] { ';' });
+ }
} else {
completionName = CharOperation.concat(completionName, new char[] { ';' });
}
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(accessibility);
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance, false);
+ }
} else {
- completionName = CharOperation.concat(completionName, new char[] { ';' });
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(accessibility);
- relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
- }
- } else {
- if(!this.importCachesInitialized) {
- initializeImportCaches();
- }
-
- for (int j = 0; j < this.importCacheCount; j++) {
- char[][] importName = this.importsCache[j];
- if(CharOperation.equals(typeName, importName[0])) {
+ if(!this.importCachesInitialized) {
+ initializeImportCaches();
+ }
+
+ for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(typeName, importName[0])) {
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ !CharOperation.equals(fullyQualifiedName, importName[1]),
+ false,
+ scope);
+ continue next;
+ }
+ }
+
+
+ if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
proposeType(
packageName,
simpleTypeName,
@@ -557,50 +717,44 @@
accessibility,
typeName,
fullyQualifiedName,
- !CharOperation.equals(fullyQualifiedName, importName[1]),
+ false,
+ false,
scope);
continue next;
- }
- }
-
-
- if ((enclosingTypeNames == null || enclosingTypeNames.length == 0 ) && CharOperation.equals(this.currentPackageName, packageName)) {
- proposeType(
- packageName,
- simpleTypeName,
- modifiers,
- accessibility,
- typeName,
- fullyQualifiedName,
- false,
- scope);
- continue next;
- } else {
- char[] fullyQualifiedEnclosingTypeOrPackageName = null;
-
- AcceptedType foundType = null;
- if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
- for (int j = 0; j < this.onDemandImportCacheCount; j++) {
- ImportBinding importBinding = this.onDemandImportsCache[j];
-
- char[][] importName = importBinding.compoundName;
- char[] importFlatName = CharOperation.concatWith(importName, '.');
-
- if(fullyQualifiedEnclosingTypeOrPackageName == null) {
- if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
- fullyQualifiedEnclosingTypeOrPackageName =
- CharOperation.concat(
- packageName,
- flatEnclosingTypeNames,
- '.');
- } else {
- fullyQualifiedEnclosingTypeOrPackageName =
- packageName;
+ } else {
+ char[] fullyQualifiedEnclosingTypeOrPackageName = null;
+
+ AcceptedType foundType = null;
+ if((foundType = (AcceptedType)onDemandFound.get(simpleTypeName)) == null) {
+ for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ CharOperation.concat(
+ packageName,
+ flatEnclosingTypeNames,
+ '.');
+ } else {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ packageName;
+ }
}
- }
- if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
- if(importBinding.isStatic()) {
- if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ acceptedType.qualifiedTypeName = typeName;
+ acceptedType.fullyQualifiedName = fullyQualifiedName;
+ onDemandFound.put(
+ simpleTypeName,
+ acceptedType);
+ continue next;
+ }
+ } else {
acceptedType.qualifiedTypeName = typeName;
acceptedType.fullyQualifiedName = fullyQualifiedName;
onDemandFound.put(
@@ -608,82 +762,103 @@
acceptedType);
continue next;
}
- } else {
- acceptedType.qualifiedTypeName = typeName;
- acceptedType.fullyQualifiedName = fullyQualifiedName;
- onDemandFound.put(
- simpleTypeName,
- acceptedType);
- continue next;
}
}
- }
- } else if(!foundType.mustBeQualified){
- done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
- ImportBinding importBinding = this.onDemandImportsCache[j];
-
- char[][] importName = importBinding.compoundName;
- char[] importFlatName = CharOperation.concatWith(importName, '.');
-
- if(fullyQualifiedEnclosingTypeOrPackageName == null) {
- if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
- fullyQualifiedEnclosingTypeOrPackageName =
- CharOperation.concat(
- packageName,
- flatEnclosingTypeNames,
- '.');
- } else {
- fullyQualifiedEnclosingTypeOrPackageName =
- packageName;
+ } else if(!foundType.mustBeQualified){
+ done : for (int j = 0; j < this.onDemandImportCacheCount; j++) {
+ ImportBinding importBinding = this.onDemandImportsCache[j];
+
+ char[][] importName = importBinding.compoundName;
+ char[] importFlatName = CharOperation.concatWith(importName, '.');
+
+ if(fullyQualifiedEnclosingTypeOrPackageName == null) {
+ if(enclosingTypeNames != null && enclosingTypeNames.length != 0) {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ CharOperation.concat(
+ packageName,
+ flatEnclosingTypeNames,
+ '.');
+ } else {
+ fullyQualifiedEnclosingTypeOrPackageName =
+ packageName;
+ }
}
- }
- if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
- if(importBinding.isStatic()) {
- if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ if(CharOperation.equals(fullyQualifiedEnclosingTypeOrPackageName, importFlatName)) {
+ if(importBinding.isStatic()) {
+ if((modifiers & ClassFileConstants.AccStatic) != 0) {
+ foundType.mustBeQualified = true;
+ break done;
+ }
+ } else {
foundType.mustBeQualified = true;
break done;
}
- } else {
- foundType.mustBeQualified = true;
- break done;
}
}
}
+ proposeType(
+ packageName,
+ simpleTypeName,
+ modifiers,
+ accessibility,
+ typeName,
+ fullyQualifiedName,
+ true,
+ false,
+ scope);
}
- proposeType(
- packageName,
- simpleTypeName,
- modifiers,
- accessibility,
- typeName,
- fullyQualifiedName,
- true,
- scope);
}
}
- }
- char[][] keys = onDemandFound.keyTable;
- Object[] values = onDemandFound.valueTable;
- int max = keys.length;
- for (int i = 0; i < max; i++) {
- if(keys[i] != null) {
- AcceptedType value = (AcceptedType) values[i];
- if(value != null) {
- proposeType(
- value.packageName,
- value.simpleTypeName,
- value.modifiers,
- value.accessibility,
- value.qualifiedTypeName,
- value.fullyQualifiedName,
- value.mustBeQualified,
- scope);
+
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+ if(keys[i] != null) {
+ AcceptedType value = (AcceptedType) values[i];
+ if(value != null) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.modifiers,
+ value.accessibility,
+ value.qualifiedTypeName,
+ value.fullyQualifiedName,
+ value.mustBeQualified,
+ false,
+ scope);
+ }
+ }
+ }
+ } catch (AbortCompletion e) {
+ char[][] keys = onDemandFound.keyTable;
+ Object[] values = onDemandFound.valueTable;
+ int max = keys.length;
+ for (int i = 0; i < max; i++) {
+ if(keys[i] != null) {
+ AcceptedType value = (AcceptedType) values[i];
+ if(value != null) {
+ proposeType(
+ value.packageName,
+ value.simpleTypeName,
+ value.modifiers,
+ value.accessibility,
+ value.qualifiedTypeName,
+ value.fullyQualifiedName,
+ true, // the qualification requirement is unknown then the proposal will be qualified to avoid potential compilation problem
+ true, // qualification could be useless then the proposal is non optimal
+ scope);
+ }
}
}
+ throw e;
+ } finally {
+ this.acceptedTypes = null; // reset
}
- this.acceptedTypes = null; // reset
+
+
}
-
+
public void acceptUnresolvedName(char[] name) {
int relevance = computeBaseRelevance();
relevance += computeRelevanceForResolution(false);
@@ -709,6 +884,41 @@
}
}
}
+ private void addExpectedType(TypeBinding type, Scope scope){
+ if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
+
+ // do not add twice the same type
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (this.expectedTypes[i] == type) return;
+ }
+
+ int length = this.expectedTypes.length;
+ if (++this.expectedTypesPtr >= length)
+ System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
+ this.expectedTypes[this.expectedTypesPtr] = type;
+
+ if(type == scope.getJavaLangObject()) {
+ this.hasJavaLangObjectAsExpectedType = true;
+ }
+ }
+
+ private void addForbiddenBindings(Binding binding){
+ if (binding == null) return;
+
+ int length = this.forbbidenBindings.length;
+ if (++this.forbbidenBindingsPtr >= length)
+ System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
+ this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
+ }
+
+ private void addUninterestingBindings(Binding binding){
+ if (binding == null) return;
+
+ int length = this.uninterestingBindings.length;
+ if (++this.uninterestingBindingsPtr >= length)
+ System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
+ this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
+ }
// this code is derived from MethodBinding#areParametersCompatibleWith(TypeBinding[])
private final boolean areParametersCompatibleWith(TypeBinding[] parameters, TypeBinding[] arguments, boolean isVarargs) {
@@ -741,193 +951,72 @@
return true;
}
- private void proposeType(char[] packageName, char[] simpleTypeName, int modifiers, int accessibility, char[] typeName, char[] fullyQualifiedName, boolean isQualified, Scope scope) {
- char[] completionName = fullyQualifiedName;
- if(isQualified) {
- if (packageName == null || packageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- return; // ignore types from the default package from outside it
- } else {
- completionName = simpleTypeName;
+ private void buildContext(
+ ASTNode astNode,
+ ASTNode astNodeParent,
+ CompilationUnitDeclaration compilationUnitDeclaration,
+ Binding qualifiedBinding,
+ Scope scope) {
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) {
+ context.setExtendedData(
+ this.typeRoot,
+ compilationUnitDeclaration,
+ this.lookupEnvironment,
+ scope,
+ astNode,
+ this.owner,
+ this.parser);
}
- TypeBinding guessedType = null;
- if ((modifiers & ClassFileConstants.AccAnnotation) != 0 &&
- this.assistNodeIsAnnotation &&
- (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
- char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
-
- TypeReference ref;
- if (cn.length == 1) {
- ref = new SingleTypeReference(simpleTypeName, 0);
- } else {
- ref = new QualifiedTypeReference(cn,new long[cn.length]);
- }
-
- switch (scope.kind) {
- case Scope.METHOD_SCOPE :
- case Scope.BLOCK_SCOPE :
- guessedType = ref.resolveType((BlockScope)scope);
- break;
- case Scope.CLASS_SCOPE :
- guessedType = ref.resolveType((ClassScope)scope);
- break;
+ // build expected types context
+ if (this.expectedTypesPtr > -1) {
+ int length = this.expectedTypesPtr + 1;
+ char[][] expTypes = new char[length][];
+ char[][] expKeys = new char[length][];
+ for (int i = 0; i < length; i++) {
+ expTypes[i] = getSignature(this.expectedTypes[i]);
+ expKeys[i] = this.expectedTypes[i].computeUniqueKey();
}
+ context.setExpectedTypesSignatures(expTypes);
+ context.setExpectedTypesKeys(expKeys);
+ }
- if (guessedType == null || !guessedType.isValidBinding()) return;
+ context.setOffset(this.actualCompletionPosition + 1 - this.offset);
- if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
+ // Set javadoc info
+ if (astNode instanceof CompletionOnJavadoc) {
+ this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
+ context.setJavadoc(this.assistNodeInJavadoc);
}
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(accessibility);
- relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
- relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
- relevance += computeRelevanceForQualification(isQualified);
-
- int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
- switch (kind) {
- case ClassFileConstants.AccAnnotation:
- case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
- relevance += computeRelevanceForAnnotation();
- if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
- relevance += computeRelevanceForInterface();
- break;
- case ClassFileConstants.AccEnum:
- relevance += computeRelevanceForEnum();
- break;
- case ClassFileConstants.AccInterface:
- relevance += computeRelevanceForInterface();
- break;
- default:
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(simpleTypeName);
- break;
+ if (!(astNode instanceof CompletionOnJavadoc)) {
+ CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
+ context.setToken(scanner.completionIdentifier);
+ context.setTokenRange(
+ scanner.completedIdentifierStart - this.offset,
+ scanner.completedIdentifierEnd - this.offset,
+ scanner.endOfEmptyToken - this.offset);
+ } else if(astNode instanceof CompletionOnJavadocTag) {
+ CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+ context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
+ context.setTokenRange(
+ javadocTag.tagSourceStart - this.offset,
+ javadocTag.tagSourceEnd - this.offset,
+ ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
+ } else {
+ CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
+ context.setToken(scanner.completionIdentifier);
+ context.setTokenRange(
+ scanner.completedIdentifierStart - this.offset,
+ scanner.completedIdentifierEnd - this.offset,
+ scanner.endOfEmptyToken - this.offset);
}
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance);
- }
- }
-
- /**
- * One result of the search consists of a new package.
- *
- * NOTE - All package names are presented in their readable form:
- * Package names are in the form "a.b.c".
- * The default package is represented by an empty array.
- */
- public void acceptPackage(char[] packageName) {
-
- if (this.knownPkgs.containsKey(packageName)) return;
-
- this.knownPkgs.put(packageName, this);
-
- char[] completion;
- if(this.resolvingImports) {
- if(this.resolvingStaticImports) {
- completion = CharOperation.concat(packageName, new char[] { '.' });
- } else {
- completion = CharOperation.concat(packageName, new char[] { '.', '*', ';' });
- }
- } else {
- completion = packageName;
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(this.qualifiedCompletionToken == null ? this.completionToken : this.qualifiedCompletionToken, packageName);
- if(!this.resolvingImports) {
- relevance += computeRelevanceForQualification(true);
- }
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(packageName);
- proposal.setPackageName(packageName);
- proposal.setCompletion(completion);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
-
- private void buildContext(
- ASTNode astNode,
- ASTNode astNodeParent,
- CompilationUnitDeclaration compilationUnitDeclaration,
- Binding qualifiedBinding,
- Scope scope) {
- InternalCompletionContext context = new InternalCompletionContext();
- if (this.requestor.isExtendedContextRequired()) {
- context.setExtendedData(
- this.typeRoot,
- compilationUnitDeclaration,
- this.lookupEnvironment,
- scope,
- astNode,
- this.owner,
- this.parser);
- }
-
- // build expected types context
- if (this.expectedTypesPtr > -1) {
- int length = this.expectedTypesPtr + 1;
- char[][] expTypes = new char[length][];
- char[][] expKeys = new char[length][];
- for (int i = 0; i < length; i++) {
- expTypes[i] = getSignature(this.expectedTypes[i]);
- expKeys[i] = this.expectedTypes[i].computeUniqueKey();
- }
- context.setExpectedTypesSignatures(expTypes);
- context.setExpectedTypesKeys(expKeys);
- }
-
- context.setOffset(this.actualCompletionPosition + 1 - this.offset);
-
- // Set javadoc info
- if (astNode instanceof CompletionOnJavadoc) {
- this.assistNodeInJavadoc = ((CompletionOnJavadoc)astNode).getCompletionFlags();
- context.setJavadoc(this.assistNodeInJavadoc);
- }
-
- if (!(astNode instanceof CompletionOnJavadoc)) {
- CompletionScanner scanner = (CompletionScanner)this.parser.scanner;
- context.setToken(scanner.completionIdentifier);
- context.setTokenRange(
- scanner.completedIdentifierStart - this.offset,
- scanner.completedIdentifierEnd - this.offset,
- scanner.endOfEmptyToken - this.offset);
- } else if(astNode instanceof CompletionOnJavadocTag) {
- CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
- context.setToken(CharOperation.concat(new char[]{'@'}, javadocTag.token));
- context.setTokenRange(
- javadocTag.tagSourceStart - this.offset,
- javadocTag.tagSourceEnd - this.offset,
- ((CompletionScanner)this.parser.javadocParser.scanner).endOfEmptyToken - this.offset);
- } else {
- CompletionScanner scanner = (CompletionScanner)this.parser.javadocParser.scanner;
- context.setToken(scanner.completionIdentifier);
- context.setTokenRange(
- scanner.completedIdentifierStart - this.offset,
- scanner.completedIdentifierEnd - this.offset,
- scanner.endOfEmptyToken - this.offset);
- }
-
- if(astNode instanceof CompletionOnStringLiteral) {
- context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
- } else {
- context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
+ if(astNode instanceof CompletionOnStringLiteral) {
+ context.setTokenKind(CompletionContext.TOKEN_KIND_STRING_LITERAL);
+ } else {
+ context.setTokenKind(CompletionContext.TOKEN_KIND_NAME);
}
buildTokenLocationContext(context, scope, astNode, astNodeParent);
@@ -991,6 +1080,18 @@
}
}
+ private void checkTimeout() {
+ if (!this.timeoutExceeded) {
+ long threshold = this.requestor.getThreshold();
+ if (threshold > -1 &&
+ System.currentTimeMillis() >= this.timeStart + threshold) {
+ this.requestor.aborting();
+ this.timeoutExceeded = true;
+ throw new AbortCompletion();
+ }
+ }
+ }
+
private boolean complete(
ASTNode astNode,
ASTNode astNodeParent,
@@ -1012,971 +1113,1071 @@
buildContext(astNode, astNodeParent, compilationUnitDeclaration, qualifiedBinding, scope);
if (astNode instanceof CompletionOnFieldType) {
+ completionOnFieldType(astNode, scope);
+ } else if (astNode instanceof CompletionOnMethodReturnType) {
+ completionOnMethodReturnType(astNode, scope);
+ } else if (astNode instanceof CompletionOnSingleNameReference) {
+ completionOnSingleNameReference(astNode, astNodeParent, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnSingleTypeReference) {
+ completionOnSingleTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnQualifiedNameReference) {
+ completionOnQualifiedNameReference(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+ completionOnQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMemberAccess) {
+ completionOnMemberAccess(astNode, enclosingNode, qualifiedBinding, scope, insideTypeAnnotation);
+ } else if (astNode instanceof CompletionOnMessageSend) {
+ completionOnMessageSend(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnExplicitConstructorCall) {
+ completionOnExplicitConstructorCall(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
+ completionOnQualifiedAllocationExpression(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnClassLiteralAccess) {
+ completionOnClassLiteralAccess(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMethodName) {
+ completionOnMethodName(astNode, scope);
+ } else if (astNode instanceof CompletionOnFieldName) {
+ completionOnFieldName(astNode, scope);
+ } else if (astNode instanceof CompletionOnLocalName) {
+ completionOnLocalOrArgumentName(astNode, scope);
+ } else if (astNode instanceof CompletionOnArgumentName) {
+ completionOnLocalOrArgumentName(astNode, scope);
+ } else if (astNode instanceof CompletionOnKeyword) {
+ completionOnKeyword(astNode);
+ } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ completionOnParameterizedQualifiedTypeReference(astNode, astNodeParent, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMarkerAnnotationName) {
+ completionOnMarkerAnnotationName(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnMemberValueName) {
+ completionOnMemberValueName(astNode, astNodeParent, scope, insideTypeAnnotation);
+ } else if(astNode instanceof CompletionOnBranchStatementLabel) {
+ completionOnBranchStatementLabel(astNode);
+ } else if(astNode instanceof CompletionOnMessageSendName) {
+ completionOnMessageSendName(astNode, qualifiedBinding, scope);
+ // Completion on Javadoc nodes
+ } else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
+ if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
+ completionOnJavadocSingleTypeReference(astNode, scope);
+ } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+ completionOnJavadocQualifiedTypeReference(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocFieldReference) {
+ completionOnJavadocFieldReference(astNode, scope);
+ } else if (astNode instanceof CompletionOnJavadocMessageSend) {
+ completionOnJavadocMessageSend(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
+ completionOnJavadocAllocationExpression(astNode, qualifiedBinding, scope);
+ } else if (astNode instanceof CompletionOnJavadocParamNameReference) {
+ completionOnJavadocParamNameReference(astNode);
+ } else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
+ completionOnJavadocTypeParamReference(astNode);
+ } else if (astNode instanceof CompletionOnJavadocTag) {
+ completionOnJavadocTag(astNode);
+ }
+ }
+ return true;
+ }
- CompletionOnFieldType field = (CompletionOnFieldType) astNode;
- CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
- this.completionToken = type.token;
- setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+ /**
+ * Ask the engine to compute a completion at the specified position
+ * of the given compilation unit.
+ *
+ * No return
+ * completion results are answered through a requestor.
+ *
+ * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
+ * the source of the current compilation unit.
+ *
+ * @param completionPosition int
+ * a position in the source where the completion is taking place.
+ * This position is relative to the source provided.
+ */
+ public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
- findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- findKeywordsForMember(this.completionToken, field.modifiers);
- }
+ if(DEBUG) {
+ System.out.print("COMPLETION IN "); //$NON-NLS-1$
+ System.out.print(sourceUnit.getFileName());
+ System.out.print(" AT POSITION "); //$NON-NLS-1$
+ System.out.println(completionPosition);
+ System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
+ System.out.println(sourceUnit.getContents());
+ }
+ this.requestor.beginReporting();
+ boolean contextAccepted = false;
+ try {
+ this.fileName = sourceUnit.getFileName();
+ this.actualCompletionPosition = completionPosition - 1;
+ this.offset = pos;
+ this.typeRoot = root;
+ // for now until we can change the UI.
+ CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+ CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
- if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
- SourceTypeBinding enclosingType = scope.enclosingSourceType();
- if (!enclosingType.isAnnotationType()) {
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
- findMethods(
- this.completionToken,
- null,
- null,
- enclosingType,
- scope,
- new ObjectVector(),
- false,
- false,
- true,
- null,
- null,
- false,
- false,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
- proposeNewMethod(this.completionToken, enclosingType);
- }
+ // boolean completionNodeFound = false;
+ if (parsedUnit != null) {
+ if(DEBUG) {
+ System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
+ System.out.println(parsedUnit.toString());
}
- }
- } else if (astNode instanceof CompletionOnMethodReturnType) {
- CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
- SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
- this.completionToken = type.token;
- setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
- findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- findKeywordsForMember(this.completionToken, method.modifiers);
- }
-
- if (method.modifiers == ClassFileConstants.AccDefault) {
- SourceTypeBinding enclosingType = scope.enclosingSourceType();
- if (!enclosingType.isAnnotationType()) {
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
- findMethods(
- this.completionToken,
- null,null,
- scope.enclosingSourceType(),
- scope,
- new ObjectVector(),
- false,
- false,
- true,
- null,
- null,
- false,
- false,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
+ // scan the package & import statements first
+ if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
+ contextAccepted = true;
+ buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
+ if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+ findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
}
- if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
- proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
}
+ return;
}
- }
- } else if (astNode instanceof CompletionOnSingleNameReference) {
- CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
- this.completionToken = singleNameReference.token;
- SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
- if (switchStatement != null
- && switchStatement.expression.resolvedType != null
- && switchStatement.expression.resolvedType.isEnum()) {
- if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- this.assistNodeIsEnum = true;
- findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
- }
- } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
- findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
- } else {
- if (this.expectedTypesPtr > -1) {
- this.assistNodeIsEnum = true;
- done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if (!this.expectedTypes[i].isEnum()) {
- this.assistNodeIsEnum = false;
- break done;
- }
- }
-
- }
- if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
- char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
-
- findUnresolvedReference(
- singleNameReference.sourceStart,
- singleNameReference.sourceEnd,
- (BlockScope)scope,
- alreadyDefinedName);
- }
- findVariablesAndMethods(
- this.completionToken,
- scope,
- singleNameReference,
- scope,
- insideTypeAnnotation,
- singleNameReference.isInsideAnnotationAttribute);
- // can be the start of a qualified type name
- findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- if (this.completionToken != null && this.completionToken.length != 0) {
- findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
- } else {
- findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
- }
- }
- if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
- if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
- ReferenceBinding ref = scope.enclosingSourceType();
- findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
- } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
- ReferenceBinding ref = scope.enclosingSourceType();
- findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
- }
- }
- }
-
- } else if (astNode instanceof CompletionOnSingleTypeReference) {
-
- CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
+ ImportReference[] imports = parsedUnit.imports;
+ if (imports != null) {
+ for (int i = 0, length = imports.length; i < length; i++) {
+ ImportReference importReference = imports[i];
+ if (importReference instanceof CompletionOnImportReference) {
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ contextAccepted = true;
+ buildContext(importReference, null, parsedUnit, null, null);
- this.completionToken = singleRef.token;
+ long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
+ setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
- this.assistNodeIsClass = singleRef.isClass();
- this.assistNodeIsException = singleRef.isException();
- this.assistNodeIsInterface = singleRef.isInterface();
- this.assistNodeIsConstructor = singleRef.isConstructorType;
- this.assistNodeIsSuperType = singleRef.isSuperType();
+ char[][] oldTokens = importReference.tokens;
+ int tokenCount = oldTokens.length;
+ if (tokenCount == 1) {
+ findImports((CompletionOnImportReference)importReference, true);
+ } else if(tokenCount > 1){
+ this.insideQualifiedReference = true;
- // can be the start of a qualified type name
- if (qualifiedBinding == null) {
- if (this.completionToken.length == 0 &&
- (astNodeParent instanceof ParameterizedSingleTypeReference ||
- astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
- this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
+ char[] lastToken = oldTokens[tokenCount - 1];
+ char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
- findParameterizedType((TypeReference)astNodeParent, scope);
- } else {
- ObjectVector typesFound = new ObjectVector();
- if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
- findExceptionFromTryStatement(
- this.completionToken,
- null,
- scope.enclosingSourceType(),
- (BlockScope)scope,
- typesFound);
- }
- findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
- }
- } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- false,
- false,
- !this.assistNodeIsConstructor,
- null,
- new ObjectVector(),
- null,
- null,
- null,
- false);
- }
- } else if (astNode instanceof CompletionOnQualifiedNameReference) {
+ Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
+ if(binding != null) {
+ if(binding instanceof PackageBinding) {
+ findImports((CompletionOnImportReference)importReference, false);
+ } else {
+ ReferenceBinding ref = (ReferenceBinding) binding;
- this.insideQualifiedReference = true;
- CompletionOnQualifiedNameReference ref =
- (CompletionOnQualifiedNameReference) astNode;
- this.completionToken = ref.completionIdentifier;
- long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
+ }
+ if(importReference.isStatic()) {
- if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- // complete field members with missing fields type
- // class X {
- // Missing f;
- // void foo() {
- // f.|
- // }
- // }
- if (this.assistNodeInJavadoc == 0 &&
- (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
- this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
- this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
- if(ref.tokens.length == 1) {
- boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ findImportsOfStaticFields(lastToken, ref);
+ }
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+ findImportsOfStaticMethods(lastToken, ref);
+ }
+ }
+ }
+ }
+ }
- if (!foundSomeFields) {
- findMembersFromMissingType(
- ref.tokens[0],
- ref.sourcePositions[0],
- null,
- scope,
- ref,
- ref.isInsideAnnotationAttribute);
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ }
+ return;
+ } else if(importReference instanceof CompletionOnKeyword) {
+ contextAccepted = true;
+ buildContext(importReference, null, parsedUnit, null, null);
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
+ CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
+ }
+ if(this.noProposal && this.problem != null) {
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
+ }
+ }
+ return;
}
}
}
- } else if (qualifiedBinding instanceof VariableBinding) {
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
- if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
- ObjectVector fieldsFound = new ObjectVector();
- ObjectVector methodsFound = new ObjectVector();
-
- findFieldsAndMethods(
- this.completionToken,
- receiverType.capture(scope, ref.sourceEnd),
- scope,
- fieldsFound,
- methodsFound,
- ref,
- scope,
- false,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- findFieldsAndMethodsFromCastedReceiver(
- enclosingNode,
- qualifiedBinding,
- scope,
- fieldsFound,
- methodsFound,
- ref,
- scope,
- ref);
+ if (parsedUnit.types != null) {
+ try {
+ this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
- } else if (this.assistNodeInJavadoc == 0 &&
- (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
- this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
- boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
- boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
- if (proposeField || proposeMethod) {
- if(ref.tokens.length == 1) {
- if (qualifiedBinding instanceof LocalVariableBinding) {
- // complete local variable members with missing variables type
- // class X {
- // void foo() {
- // Missing f;
- // f.|
- // }
- // }
- LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
- findFieldsAndMethodsFromMissingType(
- localVariableBinding.declaration.type,
- localVariableBinding.declaringScope,
- ref,
- scope);
- } else {
- // complete field members with missing fields type
- // class X {
- // Missing f;
- // void foo() {
- // f.|
- // }
- // }
- findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+ if ((this.unitScope = parsedUnit.scope) != null) {
+ this.source = sourceUnit.getContents();
+ this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
+ parsedUnit.scope.faultInTypes();
+ parseBlockStatements(parsedUnit, this.actualCompletionPosition);
+ if(DEBUG) {
+ System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
+ System.out.println(parsedUnit.toString());
}
-
+ parsedUnit.resolve();
+ }
+ } catch (CompletionNodeFound e) {
+ // completionNodeFound = true;
+ if (e.astNode != null) {
+ // if null then we found a problem in the completion node
+ if(DEBUG) {
+ System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
+ System.out.println(e.astNode.toString());
+ if(this.parser.assistNodeParent != null) {
+ System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$
+ System.out.println(this.parser.assistNodeParent);
+ }
+ }
+ this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
+ contextAccepted =
+ complete(
+ e.astNode,
+ this.parser.assistNodeParent,
+ this.parser.enclosingNode,
+ parsedUnit,
+ e.qualifiedBinding,
+ e.scope,
+ e.insideTypeAnnotation);
}
}
}
-
- } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
- boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
- ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- findMembers(
- this.completionToken,
- receiverType,
- scope,
- ref,
- isInsideAnnotationAttribute,
- null,
- null,
- null,
- false);
-
- } else if (qualifiedBinding instanceof PackageBinding) {
-
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- // replace to the end of the completion identifier
- findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
}
- } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
-
- this.insideQualifiedReference = true;
-
- CompletionOnQualifiedTypeReference ref =
- (CompletionOnQualifiedTypeReference) astNode;
-
- this.assistNodeIsClass = ref.isClass();
- this.assistNodeIsException = ref.isException();
- this.assistNodeIsInterface = ref.isInterface();
- this.assistNodeIsSuperType = ref.isSuperType();
-
- this.completionToken = ref.completionIdentifier;
- long completionPosition = ref.sourcePositions[ref.tokens.length];
- // get the source positions of the completion identifier
- if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- if (this.assistNodeInJavadoc == 0 &&
- (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
- if(ref.tokens.length == 1) {
- findMemberTypesFromMissingType(
- ref.tokens[0],
- ref.sourcePositions[0],
- scope);
- }
+ if(this.noProposal && this.problem != null) {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ context.setOffset(completionPosition - this.offset);
+ context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
}
- } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
- if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- ObjectVector typesFound = new ObjectVector();
-
- if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
- findExceptionFromTryStatement(
- this.completionToken,
- (ReferenceBinding)qualifiedBinding,
- scope.enclosingSourceType(),
- (BlockScope)scope,
- typesFound);
- }
-
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- typesFound,
- null,
- null,
- null,
- false);
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
}
- } else if (qualifiedBinding instanceof PackageBinding) {
-
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- // replace to the end of the completion identifier
- findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
}
- } else if (astNode instanceof CompletionOnMemberAccess) {
- this.insideQualifiedReference = true;
- CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
- long completionPosition = access.nameSourcePosition;
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
-
- this.completionToken = access.token;
-
- if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
- // complete method members with missing return type
- // class X {
- // Missing f() {return null;}
- // void foo() {
- // f().|
- // }
- // }
- if (this.assistNodeInJavadoc == 0 &&
- (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
- this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
- ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
- findFieldsAndMethodsFromMissingReturnType(
- problemMethodBinding.selector,
- problemMethodBinding.parameters,
- scope,
- access,
- insideTypeAnnotation);
- }
- } else {
- if (!access.isInsideAnnotation) {
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
- }
-
- ObjectVector fieldsFound = new ObjectVector();
- ObjectVector methodsFound = new ObjectVector();
-
- boolean superCall = access.receiver instanceof SuperReference;
-
- findFieldsAndMethods(
- this.completionToken,
- ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
- scope,
- fieldsFound,
- methodsFound,
- access,
- scope,
- false,
- superCall,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
-
- if (!superCall) {
- findFieldsAndMethodsFromCastedReceiver(
- enclosingNode,
- qualifiedBinding,
- scope,
- fieldsFound,
- methodsFound,
- access,
- scope,
- access.receiver);
+ /* Ignore package, import, class & interface keywords for now...
+ if (!completionNodeFound) {
+ if (parsedUnit == null || parsedUnit.types == null) {
+ // this is not good enough... can still be trying to define a second type
+ CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
+ setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
+ findKeywords(scanner.completionIdentifier, mainDeclarations, null);
+ }
+ // currently have no way to know if extends/implements are possible keywords
}
- }
+ */
+ } catch (AbortCompletion e) {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+ context.setOffset(completionPosition - this.offset);
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
}
-
- } else if (astNode instanceof CompletionOnMessageSend) {
- setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
-
- CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
- TypeBinding[] argTypes = computeTypes(messageSend.arguments);
- this.completionToken = messageSend.selector;
- if (qualifiedBinding == null) {
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- ObjectVector methodsFound = new ObjectVector();
-
- findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
-
- findLocalMethodsFromStaticImports(
- this.completionToken,
- scope,
- messageSend,
- scope,
- true,
- methodsFound,
- true);
- }
- } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- findMethods(
- this.completionToken,
- null,
- argTypes,
- (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
- scope,
- new ObjectVector(),
- false,
- true,
- false,
- messageSend,
- scope,
- false,
- messageSend.receiver instanceof SuperReference,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
+ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
}
- } else if (astNode instanceof CompletionOnExplicitConstructorCall) {
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
-
- CompletionOnExplicitConstructorCall constructorCall =
- (CompletionOnExplicitConstructorCall) astNode;
- TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
- findConstructors(
- (ReferenceBinding) qualifiedBinding,
- argTypes,
- scope,
- constructorCall,
- false);
- }
- } else if (astNode instanceof CompletionOnQualifiedAllocationExpression) {
- setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
-
- CompletionOnQualifiedAllocationExpression allocExpression =
- (CompletionOnQualifiedAllocationExpression) astNode;
- TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
-
- ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
- && ref.isClass()
- && !ref.isAbstract()) {
- findConstructors(
- ref,
- argTypes,
- scope,
- allocExpression,
- false);
+ } catch (InvalidCursorLocation e) { // may eventually report a usefull error
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
}
- if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
- && !ref.isFinal()
- && !ref.isEnum()){
- findAnonymousType(
- ref,
- argTypes,
- scope,
- allocExpression);
+ } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
}
- } else if (astNode instanceof CompletionOnClassLiteralAccess) {
- if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
- setSourceAndTokenRange(access.classStart, access.sourceEnd);
-
- this.completionToken = access.completionIdentifier;
-
- findClassField(
- this.completionToken,
- (TypeBinding) qualifiedBinding,
- scope,
- null,
- null,
- null,
- false);
+ } catch (CompletionNodeFound e){ // internal failure - bugs 5618
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
}
- } else if (astNode instanceof CompletionOnMethodName) {
- if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
- CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+ } finally {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
+ context.setOffset(completionPosition - this.offset);
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ this.requestor.endReporting();
+ reset();
+ }
+ }
- setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
+ public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
+ if(this.requestor != null){
+ this.requestor.beginReporting();
+ }
+ boolean contextAccepted = false;
+ IType topLevelType = type;
+ while(topLevelType.getDeclaringType() != null) {
+ topLevelType = topLevelType.getDeclaringType();
+ }
- FieldBinding[] fields = scope.enclosingSourceType().fields();
- char[][] excludeNames = new char[fields.length][];
- for(int i = 0 ; i < fields.length ; i++){
- excludeNames[i] = fields[i].name;
- }
+ this.fileName = topLevelType.getParent().getElementName().toCharArray();
+ CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
- this.completionToken = method.selector;
+ CompilationUnitDeclaration compilationUnit = null;
- findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
+ try {
+ // TypeConverter is used instead of SourceTypeConverter because the type
+ // to convert can be a binary type or a source type
+ TypeDeclaration typeDeclaration = null;
+ if (type instanceof SourceType) {
+ SourceType sourceType = (SourceType) type;
+ ISourceType info = (ISourceType) sourceType.getElementInfo();
+ compilationUnit = SourceTypeConverter.buildCompilationUnit(
+ new ISourceType[] {info},//sourceTypes[0] is always toplevel here
+ SourceTypeConverter.FIELD_AND_METHOD // need field and methods
+ | SourceTypeConverter.MEMBER_TYPE, // need member types
+ // no need for field initialization
+ this.problemReporter,
+ compilationResult);
+ if (compilationUnit.types != null)
+ typeDeclaration = compilationUnit.types[0];
+ } else {
+ compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
+ typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
}
- } else if (astNode instanceof CompletionOnFieldName) {
- if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
- CompletionOnFieldName field = (CompletionOnFieldName) astNode;
-
- FieldBinding[] fields = scope.enclosingSourceType().fields();
- char[][] excludeNames = new char[fields.length][];
- for(int i = 0 ; i < fields.length ; i++){
- excludeNames[i] = fields[i].name;
- }
-
- this.completionToken = field.realName;
- findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
- }
- } else if (astNode instanceof CompletionOnLocalName || astNode instanceof CompletionOnArgumentName) {
- if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
- LocalDeclaration variable = (LocalDeclaration) astNode;
+ if(typeDeclaration != null) {
+ // build AST from snippet
+ Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
- int kind;
- if (variable instanceof CompletionOnLocalName){
- this.completionToken = ((CompletionOnLocalName) variable).realName;
- kind = LOCAL;
+ // merge AST
+ FieldDeclaration[] oldFields = typeDeclaration.fields;
+ FieldDeclaration[] newFields = null;
+ if (oldFields != null) {
+ newFields = new FieldDeclaration[oldFields.length + 1];
+ System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
+ newFields[oldFields.length] = fakeInitializer;
} else {
- CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
- this.completionToken = arg.realName;
- kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
+ newFields = new FieldDeclaration[] {fakeInitializer};
}
+ typeDeclaration.fields = newFields;
- char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
-
- char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
-
- LocalVariableBinding[] locals = ((BlockScope)scope).locals;
- char[][] discouragedNames = new char[locals.length][];
- int localCount = 0;
- for(int i = 0 ; i < locals.length ; i++){
- if (locals[i] != null) {
- discouragedNames[localCount++] = locals[i].name;
- }
+ if(DEBUG) {
+ System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
+ System.out.println(compilationUnit.toString());
}
- System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
-
- findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
- }
- } else if (astNode instanceof CompletionOnKeyword) {
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
- findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
- }
- } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
- if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
-
- this.insideQualifiedReference = true;
-
- this.assistNodeIsClass = ref.isClass();
- this.assistNodeIsException = ref.isException();
- this.assistNodeIsInterface = ref.isInterface();
- this.assistNodeIsSuperType = ref.isSuperType();
-
- this.completionToken = ref.completionIdentifier;
- long completionPosition = ref.sourcePositions[ref.tokens.length];
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ if (compilationUnit.types != null) {
+ try {
+ this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
- if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
- (((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
- if (this.assistNodeInJavadoc == 0 &&
- (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
- if(ref.tokens.length == 1) {
- findMemberTypesFromMissingType(
- ref,
- ref.sourcePositions[0],
- scope);
+ if ((this.unitScope = compilationUnit.scope) != null) {
+ this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
+ compilationUnit.scope.faultInTypes();
+ compilationUnit.resolve();
+ }
+ } catch (CompletionNodeFound e) {
+ // completionNodeFound = true;
+ if (e.astNode != null) {
+ // if null then we found a problem in the completion node
+ contextAccepted =
+ complete(
+ e.astNode,
+ this.parser.assistNodeParent,
+ this.parser.enclosingNode,
+ compilationUnit,
+ e.qualifiedBinding,
+ e.scope,
+ e.insideTypeAnnotation);
}
}
- } else {
- ObjectVector typesFound = new ObjectVector();
- if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
- findExceptionFromTryStatement(
- this.completionToken,
- (ReferenceBinding)qualifiedBinding,
- scope.enclosingSourceType(),
- (BlockScope)scope,
- typesFound);
+ }
+ if(this.noProposal && this.problem != null) {
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ this.requestor.completionFailure(this.problem);
+ if(DEBUG) {
+ this.printDebug(this.problem);
}
-
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- typesFound,
- null,
- null,
- null,
- false);
}
}
- } else if (astNode instanceof CompletionOnMarkerAnnotationName) {
- CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
-
- CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
- if (fakeType.annotations[0] == annot) {
- // When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
- // So 'targetedElement' is not computed in this case.
- if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
- this.targetedElement = computeTargetedElement(fakeType);
- }
-
+ } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
}
+ } catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
+ if(DEBUG) {
+ System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
+ e.printStackTrace(System.out);
+ }
+ } catch(JavaModelException e) {
+ // Do nothing
+ }
+ if(!contextAccepted) {
+ contextAccepted = true;
+ InternalCompletionContext context = new InternalCompletionContext();
+ if (this.requestor.isExtendedContextRequired()) context.setExtended();
+ this.requestor.acceptContext(context);
+ }
+ if(this.requestor != null){
+ this.requestor.endReporting();
+ }
+ }
+
+ private void completionOnBranchStatementLabel(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
+ CompletionOnBranchStatementLabel label = (CompletionOnBranchStatementLabel) astNode;
+ this.completionToken = label.label;
+ findLabels(this.completionToken, label.possibleLabels);
+ }
+ }
+
+ private void completionOnClassLiteralAccess(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ CompletionOnClassLiteralAccess access = (CompletionOnClassLiteralAccess) astNode;
+ setSourceAndTokenRange(access.classStart, access.sourceEnd);
+ this.completionToken = access.completionIdentifier;
+ findClassField(
+ this.completionToken,
+ (TypeBinding) qualifiedBinding,
+ scope,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+
+ private void completionOnExplicitConstructorCall(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+ CompletionOnExplicitConstructorCall constructorCall = (CompletionOnExplicitConstructorCall) astNode;
+ TypeBinding[] argTypes = computeTypes(constructorCall.arguments);
+ findConstructors(
+ (ReferenceBinding) qualifiedBinding,
+ argTypes,
+ scope,
+ constructorCall,
+ false);
+ }
+ }
+
+ private void completionOnFieldName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ CompletionOnFieldName field = (CompletionOnFieldName) astNode;
- this.assistNodeIsAnnotation = true;
- if (annot.type instanceof CompletionOnSingleTypeReference) {
- CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
- this.completionToken = type.token;
- setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
-
- if (scope.parent.parent != null &&
- !(scope.parent.parent instanceof MethodScope) &&
- !fakeType.isParameter) {
-
- if (this.completionToken.length <= Keywords.INTERFACE.length
- && CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
- )){
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
- relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
- proposal.setName(Keywords.INTERFACE);
- proposal.setCompletion(Keywords.INTERFACE);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- }
+ FieldBinding[] fields = scope.enclosingSourceType().fields();
+ char[][] excludeNames = new char[fields.length][];
+ for(int i = 0 ; i < fields.length ; i++){
+ excludeNames[i] = fields[i].name;
+ }
- findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
- } else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
- this.insideQualifiedReference = true;
-
- CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
- this.completionToken = type.completionIdentifier;
- long completionPosition = type.sourcePositions[type.tokens.length];
- if (qualifiedBinding instanceof PackageBinding) {
-
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- // replace to the end of the completion identifier
- findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
- } else {
- setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ this.completionToken = field.realName;
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- new ObjectVector(),
- null,
- null,
- null,
- false);
+ findVariableNames(field.realName, field.type, excludeNames, null, FIELD, field.modifiers);
+ }
+ }
+
+ private void completionOnFieldType(ASTNode astNode, Scope scope) {
+ CompletionOnFieldType field = (CompletionOnFieldType) astNode;
+ CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) field.type;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+
+ findTypesAndPackages(this.completionToken, scope, true, true, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywordsForMember(this.completionToken, field.modifiers);
+ }
+
+ if (!field.isLocalVariable && field.modifiers == ClassFileConstants.AccDefault) {
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ if (!enclosingType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+ findMethodDeclarations(
+ this.completionToken,
+ enclosingType,
+ scope,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+ proposeNewMethod(this.completionToken, enclosingType);
}
}
- } else if (astNode instanceof CompletionOnMemberValueName) {
- CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
- Annotation annotation = (Annotation) astNodeParent;
-
- this.completionToken = memberValuePair.name;
+ }
+ }
+ //TODO
+ private void completionOnJavadocAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ // setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
+ this.javadocTagPosition = allocExpression.tagSourceStart;
+ int rangeStart = astNode.sourceStart;
+ if (allocExpression.type.isThis()) {
+ if (allocExpression.completeInText()) {
+ rangeStart = allocExpression.separatorPosition;
+ }
+ } else if (allocExpression.completeInText()) {
+ rangeStart = allocExpression.type.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+ TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
- ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
+ ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
+ findConstructors(ref, argTypes, scope, allocExpression, false);
+ }
+ }
+ //TODO
+ private void completionOnJavadocFieldReference(ASTNode astNode, Scope scope) {
+ this.insideQualifiedReference = true;
+ CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
+ this.completionToken = fieldRef.token;
+ long completionPosition = fieldRef.nameSourcePosition;
+ this.javadocTagPosition = fieldRef.tagSourceStart;
- if (annotationType != null && annotationType.isAnnotationType()) {
- if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
- findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
+ if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
+ ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
+ int rangeStart = (int) (completionPosition >>> 32);
+ if (fieldRef.receiver.isThis()) {
+ if (fieldRef.completeInText()) {
+ rangeStart = fieldRef.separatorPosition;
}
- if (this.assistNodeCanBeSingleMemberAnnotation) {
- if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
- findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
- } else {
- if (this.expectedTypesPtr > -1) {
- this.assistNodeIsEnum = true;
- done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if (!this.expectedTypes[i].isEnum()) {
- this.assistNodeIsEnum = false;
- break done;
- }
- }
+ } else if (fieldRef.completeInText()) {
+ rangeStart = fieldRef.receiver.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, (int) completionPosition);
- }
- if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
- char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
+ || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
+ findFields(this.completionToken,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ new ObjectVector(),
+ false, /*not only static */
+ fieldRef,
+ scope,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
- findUnresolvedReference(
- memberValuePair.sourceStart,
- memberValuePair.sourceEnd,
- (BlockScope)scope,
- alreadyDefinedName);
- }
- findVariablesAndMethods(
- this.completionToken,
- scope,
- FakeInvocationSite,
- scope,
- insideTypeAnnotation,
- true);
- // can be the start of a qualified type name
- findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+ || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ null,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ false, /*not only static */
+ false,
+ fieldRef,
+ scope,
+ false,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
+ ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
+ if (this.completionToken == null
+ || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
+ || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
+ findConstructors(refBinding, null, scope, fieldRef, false);
}
}
}
- } else if(astNode instanceof CompletionOnBrankStatementLabel) {
- if (!this.requestor.isIgnored(CompletionProposal.LABEL_REF)) {
- CompletionOnBrankStatementLabel label = (CompletionOnBrankStatementLabel) astNode;
-
- this.completionToken = label.label;
+ }
+ }
+ //TODO
+ private void completionOnJavadocMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
+ TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
+ this.completionToken = messageSend.selector;
+ this.javadocTagPosition = messageSend.tagSourceStart;
- findLabels(this.completionToken, label.possibleLabels);
+ // Set source range
+ int rangeStart = astNode.sourceStart;
+ if (messageSend.receiver.isThis()) {
+ if (messageSend.completeInText()) {
+ rangeStart = messageSend.separatorPosition;
}
- } else if(astNode instanceof CompletionOnMessageSendName) {
+ } else if (messageSend.completeInText()) {
+ rangeStart = messageSend.receiver.sourceStart;
+ }
+ setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
+
+ if (qualifiedBinding == null) {
if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
+ findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
+ }
+ } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ argTypes,
+ (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+ scope,
+ new ObjectVector(),
+ false,
+ false/* prefix match */,
+ messageSend,
+ scope,
+ false,
+ messageSend.receiver instanceof SuperReference,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+ //TODO
+ private void completionOnJavadocParamNameReference(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+ CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
+ setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+ findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
+ findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
+ }
+ }
+ //TODO
+ private void completionOnJavadocQualifiedTypeReference(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ this.insideQualifiedReference = true;
+
+ CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
+ this.completionToken = typeRef.completionIdentifier;
+ long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
+ this.javadocTagPosition = typeRef.tagSourceStart;
+
+ // get the source positions of the completion identifier
+ if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+ ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
+ int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+ setSourceAndTokenRange(rangeStart, (int) completionPosition);
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ } else if (qualifiedBinding instanceof PackageBinding) {
- this.insideQualifiedReference = true;
- this.completionToken = messageSend.selector;
- boolean onlyStatic = false;
- if (messageSend.receiver instanceof NameReference) {
- onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
- } else if (!(messageSend.receiver instanceof MessageSend) &&
- !(messageSend.receiver instanceof FieldReference) &&
- !(messageSend.receiver.isThis())) {
- onlyStatic = true;
- }
-
- TypeBinding receiverType = (TypeBinding)qualifiedBinding;
-
- if(receiverType != null && receiverType instanceof ReferenceBinding) {
- TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
- if(typeArgTypes != null) {
- findMethods(
- this.completionToken,
- typeArgTypes,
- null,
- (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
- scope,
- new ObjectVector(),
- onlyStatic,
- false,
- false,
- messageSend,
- scope,
- false,
- false,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
+ setTokenRange(rangeStart, (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ }
+ }
+ //TODO
+ private void completionOnJavadocSingleTypeReference(ASTNode astNode, Scope scope) {
+ CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
+ this.completionToken = typeRef.token;
+ this.javadocTagPosition = typeRef.tagSourceStart;
+ setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
+ findTypesAndPackages(
+ this.completionToken,
+ scope,
+ (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
+ false,
+ new ObjectVector());
+ }
+ //TODO
+ private void completionOnJavadocTag(ASTNode astNode) {
+ CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
+ setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
+ findJavadocBlockTags(javadocTag);
+ findJavadocInlineTags(javadocTag);
+ }
+ //TODO
+ private void completionOnJavadocTypeParamReference(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
+ CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
+ setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
+ findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
+ }
+ }
+
+ private void completionOnKeyword(ASTNode astNode) {
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ CompletionOnKeyword keyword = (CompletionOnKeyword)astNode;
+ findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), keyword.canCompleteEmptyToken(), false);
+ }
+ }
+
+ private void completionOnLocalOrArgumentName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ LocalDeclaration variable = (LocalDeclaration) astNode;
+
+ int kind;
+ if (variable instanceof CompletionOnLocalName){
+ this.completionToken = ((CompletionOnLocalName) variable).realName;
+ kind = LOCAL;
+ } else {
+ CompletionOnArgumentName arg = (CompletionOnArgumentName) variable;
+ this.completionToken = arg.realName;
+ kind = arg.isCatchArgument ? LOCAL : ARGUMENT;
+ }
+
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, variable);
+
+ char[][] forbiddenNames = findVariableFromUnresolvedReference(variable, (BlockScope)scope, alreadyDefinedName);
+
+ LocalVariableBinding[] locals = ((BlockScope)scope).locals;
+ char[][] discouragedNames = new char[locals.length][];
+ int localCount = 0;
+ for(int i = 0 ; i < locals.length ; i++){
+ if (locals[i] != null) {
+ discouragedNames[localCount++] = locals[i].name;
}
}
- // Completion on Javadoc nodes
- } else if ((astNode.bits & ASTNode.InsideJavadoc) != 0) {
- if (astNode instanceof CompletionOnJavadocSingleTypeReference) {
- CompletionOnJavadocSingleTypeReference typeRef = (CompletionOnJavadocSingleTypeReference) astNode;
- this.completionToken = typeRef.token;
- this.javadocTagPosition = typeRef.tagSourceStart;
- setSourceAndTokenRange(typeRef.sourceStart, typeRef.sourceEnd);
- findTypesAndPackages(
- this.completionToken,
- scope,
- (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0,
- false,
- new ObjectVector());
+ System.arraycopy(discouragedNames, 0, discouragedNames = new char[localCount][], 0, localCount);
- } else if (astNode instanceof CompletionOnJavadocQualifiedTypeReference) {
+ findVariableNames(this.completionToken, variable.type, discouragedNames, forbiddenNames, kind, variable.modifiers);
+ }
+ }
+
+ private void completionOnMarkerAnnotationName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ CompletionOnMarkerAnnotationName annot = (CompletionOnMarkerAnnotationName) astNode;
- this.insideQualifiedReference = true;
+ CompletionOnAnnotationOfType fakeType = (CompletionOnAnnotationOfType)scope.parent.referenceContext();
+ if (fakeType.annotations[0] == annot) {
+ // When the completion is inside a method body the annotation cannot be accuratly attached to the correct node by completion recovery.
+ // So 'targetedElement' is not computed in this case.
+ if (scope.parent.parent == null || !(scope.parent.parent instanceof MethodScope)) {
+ this.targetedElement = computeTargetedElement(fakeType);
+ }
- CompletionOnJavadocQualifiedTypeReference typeRef = (CompletionOnJavadocQualifiedTypeReference) astNode;
- this.completionToken = typeRef.completionIdentifier;
- long completionPosition = typeRef.sourcePositions[typeRef.tokens.length];
- this.javadocTagPosition = typeRef.tagSourceStart;
-
- // get the source positions of the completion identifier
- if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
- if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
- ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF))) {
- int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
- setSourceAndTokenRange(rangeStart, (int) completionPosition);
- findMemberTypes(
- this.completionToken,
- (ReferenceBinding) qualifiedBinding,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- new ObjectVector(),
- null,
- null,
- null,
- false);
- }
- } else if (qualifiedBinding instanceof PackageBinding) {
+ }
- setSourceRange(astNode.sourceStart, (int) completionPosition);
- int rangeStart = typeRef.completeInText() ? typeRef.sourceStart : (int) (completionPosition >>> 32);
- setTokenRange(rangeStart, (int) completionPosition);
- // replace to the end of the completion identifier
- findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
- }
- } else if (astNode instanceof CompletionOnJavadocFieldReference) {
+ this.assistNodeIsAnnotation = true;
+ if (annot.type instanceof CompletionOnSingleTypeReference) {
+ CompletionOnSingleTypeReference type = (CompletionOnSingleTypeReference) annot.type;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
- this.insideQualifiedReference = true;
- CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) astNode;
- this.completionToken = fieldRef.token;
- long completionPosition = fieldRef.nameSourcePosition;
- this.javadocTagPosition = fieldRef.tagSourceStart;
-
- if (fieldRef.actualReceiverType != null && fieldRef.actualReceiverType.isValidBinding()) {
- ReferenceBinding receiverType = (ReferenceBinding) fieldRef.actualReceiverType;
- int rangeStart = (int) (completionPosition >>> 32);
- if (fieldRef.receiver.isThis()) {
- if (fieldRef.completeInText()) {
- rangeStart = fieldRef.separatorPosition;
+ if (scope.parent.parent != null &&
+ !(scope.parent.parent instanceof MethodScope) &&
+ !fakeType.isParameter) {
+
+ if (this.completionToken.length <= Keywords.INTERFACE.length
+ && CharOperation.prefixEquals(this.completionToken, Keywords.INTERFACE, false /* ignore case */
+ )){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.INTERFACE);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+ relevance += R_ANNOTATION; // this proposal is most relevant than annotation proposals
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ CompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+ proposal.setName(Keywords.INTERFACE);
+ proposal.setCompletion(Keywords.INTERFACE);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
- } else if (fieldRef.completeInText()) {
- rangeStart = fieldRef.receiver.sourceStart;
}
- setSourceAndTokenRange(rangeStart, (int) completionPosition);
-
- if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)
- || !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
- findFields(this.completionToken,
- receiverType,
+ }
+ }
+
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else if (annot.type instanceof CompletionOnQualifiedTypeReference) {
+ this.insideQualifiedReference = true;
+
+ CompletionOnQualifiedTypeReference type = (CompletionOnQualifiedTypeReference) annot.type;
+ this.completionToken = type.completionIdentifier;
+ long completionPosition = type.sourcePositions[type.tokens.length];
+ if (qualifiedBinding instanceof PackageBinding) {
+
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
+ } else {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+
+ private void completionOnMemberAccess(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+ Scope scope, boolean insideTypeAnnotation) {
+ this.insideQualifiedReference = true;
+ CompletionOnMemberAccess access = (CompletionOnMemberAccess) astNode;
+ long completionPosition = access.nameSourcePosition;
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ this.completionToken = access.token;
+
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ // complete method members with missing return type
+ // class X {
+ // Missing f() {return null;}
+ // void foo() {
+ // f().|
+ // }
+ // }
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+ ProblemMethodBinding problemMethodBinding = (ProblemMethodBinding) qualifiedBinding;
+ findFieldsAndMethodsFromMissingReturnType(
+ problemMethodBinding.selector,
+ problemMethodBinding.parameters,
+ scope,
+ access,
+ insideTypeAnnotation);
+ }
+ } else {
+ if (!access.isInsideAnnotation) {
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywords(this.completionToken, new char[][]{Keywords.NEW}, false, false);
+ }
+
+ ObjectVector fieldsFound = new ObjectVector();
+ ObjectVector methodsFound = new ObjectVector();
+
+ boolean superCall = access.receiver instanceof SuperReference;
+
+ findFieldsAndMethods(
+ this.completionToken,
+ ((TypeBinding) qualifiedBinding).capture(scope, access.receiver.sourceEnd),
+ scope,
+ fieldsFound,
+ methodsFound,
+ access,
+ scope,
+ false,
+ superCall,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+
+ if (!superCall) {
+
+ checkTimeout();
+
+ findFieldsAndMethodsFromCastedReceiver(
+ enclosingNode,
+ qualifiedBinding,
scope,
- new ObjectVector(),
- new ObjectVector(),
- false, /*not only static */
- fieldRef,
+ fieldsFound,
+ methodsFound,
+ access,
scope,
- false,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
+ access.receiver);
+ }
+ }
+ }
+ }
+
+ private void completionOnMemberValueName(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+ boolean insideTypeAnnotation) {
+ CompletionOnMemberValueName memberValuePair = (CompletionOnMemberValueName) astNode;
+ Annotation annotation = (Annotation) astNodeParent;
+
+ this.completionToken = memberValuePair.name;
+
+ ReferenceBinding annotationType = (ReferenceBinding)annotation.resolvedType;
+
+ if (annotationType != null && annotationType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+ findAnnotationAttributes(this.completionToken, annotation.memberValuePairs(), annotationType);
+ }
+ if (this.assistNodeCanBeSingleMemberAnnotation) {
+ if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else {
+ if (this.expectedTypesPtr > -1) {
+ this.assistNodeIsEnum = true;
+ done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (!this.expectedTypes[i].isEnum()) {
+ this.assistNodeIsEnum = false;
+ break done;
+ }
+ }
+
}
+ if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, FakeInvocationSite);
+
+ findUnresolvedReference(
+ memberValuePair.sourceStart,
+ memberValuePair.sourceEnd,
+ (BlockScope)scope,
+ alreadyDefinedName);
+ }
+ findVariablesAndMethods(
+ this.completionToken,
+ scope,
+ FakeInvocationSite,
+ scope,
+ insideTypeAnnotation,
+ true);
+ // can be the start of a qualified type name
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ }
+ }
+ }
+ }
+
+ private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnMessageSend messageSend = (CompletionOnMessageSend) astNode;
+ TypeBinding[] argTypes = computeTypes(messageSend.arguments);
+ this.completionToken = messageSend.selector;
+ if (qualifiedBinding == null) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ ObjectVector methodsFound = new ObjectVector();
+
+ findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, methodsFound);
+
+ checkTimeout();
+
+ findLocalMethodsFromStaticImports(
+ this.completionToken,
+ scope,
+ messageSend,
+ scope,
+ true,
+ methodsFound,
+ true);
+ }
+ } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findMethods(
+ this.completionToken,
+ null,
+ argTypes,
+ (ReferenceBinding)((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+ scope,
+ new ObjectVector(),
+ false,
+ true,
+ messageSend,
+ scope,
+ false,
+ messageSend.receiver instanceof SuperReference,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+
+ private void completionOnMessageSendName(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ CompletionOnMessageSendName messageSend = (CompletionOnMessageSendName) astNode;
+
+ this.insideQualifiedReference = true;
+ this.completionToken = messageSend.selector;
+ boolean onlyStatic = false;
+ if (messageSend.receiver instanceof NameReference) {
+ onlyStatic = ((NameReference)messageSend.receiver).isTypeReference();
+ } else if (!(messageSend.receiver instanceof MessageSend) &&
+ !(messageSend.receiver instanceof FieldReference) &&
+ !(messageSend.receiver.isThis())) {
+ onlyStatic = true;
+ }
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
- || !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
- findMethods(
+ TypeBinding receiverType = (TypeBinding)qualifiedBinding;
+
+ if(receiverType != null && receiverType instanceof ReferenceBinding) {
+ TypeBinding[] typeArgTypes = computeTypesIfCorrect(messageSend.typeArguments);
+ if(typeArgTypes != null) {
+ findMethods(
this.completionToken,
+ typeArgTypes,
null,
- null,
- receiverType,
+ (ReferenceBinding)receiverType.capture(scope, messageSend.receiver.sourceEnd),
scope,
new ObjectVector(),
- false, /*not only static */
+ onlyStatic,
false,
- false,
- fieldRef,
+ messageSend,
scope,
false,
false,
- true,
+ false,
null,
null,
null,
@@ -1984,54 +2185,202 @@
null,
-1,
-1);
- if (fieldRef.actualReceiverType instanceof ReferenceBinding) {
- ReferenceBinding refBinding = (ReferenceBinding)fieldRef.actualReceiverType;
- if (this.completionToken == null
- || CharOperation.prefixEquals(this.completionToken, refBinding.sourceName)
- || (this.options.camelCaseMatch && CharOperation.camelCaseMatch(this.completionToken, refBinding.sourceName))) {
- findConstructors(refBinding, null, scope, fieldRef, false);
- }
- }
+ }
+ }
+ }
+ }
+
+ private void completionOnMethodName(ASTNode astNode, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ CompletionOnMethodName method = (CompletionOnMethodName) astNode;
+
+ setSourceAndTokenRange(method.sourceStart, method.selectorEnd);
+
+ FieldBinding[] fields = scope.enclosingSourceType().fields();
+ char[][] excludeNames = new char[fields.length][];
+ for(int i = 0 ; i < fields.length ; i++){
+ excludeNames[i] = fields[i].name;
+ }
+
+ this.completionToken = method.selector;
+
+ findVariableNames(this.completionToken, method.returnType, excludeNames, null, FIELD, method.modifiers);
+ }
+ }
+
+ private void completionOnMethodReturnType(ASTNode astNode, Scope scope) {
+ CompletionOnMethodReturnType method = (CompletionOnMethodReturnType) astNode;
+ SingleTypeReference type = (CompletionOnSingleTypeReference) method.returnType;
+ this.completionToken = type.token;
+ setSourceAndTokenRange(type.sourceStart, type.sourceEnd);
+ findTypesAndPackages(this.completionToken, scope.parent, true, true, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ findKeywordsForMember(this.completionToken, method.modifiers);
+ }
+
+ if (method.modifiers == ClassFileConstants.AccDefault) {
+ SourceTypeBinding enclosingType = scope.enclosingSourceType();
+ if (!enclosingType.isAnnotationType()) {
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_DECLARATION)) {
+ findMethodDeclarations(
+ this.completionToken,
+ scope.enclosingSourceType(),
+ scope,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+ proposeNewMethod(this.completionToken, scope.enclosingSourceType());
+ }
+ }
+ }
+ }
+
+ private void completionOnParameterizedQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ CompletionOnParameterizedQualifiedTypeReference ref = (CompletionOnParameterizedQualifiedTypeReference) astNode;
+
+ this.insideQualifiedReference = true;
+
+ this.assistNodeIsClass = ref.isClass();
+ this.assistNodeIsException = ref.isException();
+ this.assistNodeIsInterface = ref.isInterface();
+ this.assistNodeIsSuperType = ref.isSuperType();
+
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.tokens.length];
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound ||
+ (((ReferenceBinding)qualifiedBinding).tagBits & TagBits.HasMissingType) != 0) {
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ findMemberTypesFromMissingType(
+ ref,
+ ref.sourcePositions[0],
+ scope);
}
}
- } else if (astNode instanceof CompletionOnJavadocMessageSend) {
+ } else {
+ ObjectVector typesFound = new ObjectVector();
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ (ReferenceBinding)qualifiedBinding,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkTimeout();
+
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+
+ private void completionOnQualifiedAllocationExpression(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
+ setSourceAndTokenRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ CompletionOnQualifiedAllocationExpression allocExpression =
+ (CompletionOnQualifiedAllocationExpression) astNode;
+ TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
+
+ ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
+ if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)
+ && ref.isClass()
+ && !ref.isAbstract()) {
+ findConstructors(
+ ref,
+ argTypes,
+ scope,
+ allocExpression,
+ false);
+ }
+
+ checkTimeout();
+
+ if (!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)
+ && !ref.isFinal()
+ && !ref.isEnum()){
+ findAnonymousType(
+ ref,
+ argTypes,
+ scope,
+ allocExpression);
+ }
+ }
+
+ private void completionOnQualifiedNameReference(ASTNode astNode, ASTNode enclosingNode, Binding qualifiedBinding,
+ Scope scope, boolean insideTypeAnnotation) {
+ this.insideQualifiedReference = true;
+ CompletionOnQualifiedNameReference ref =
+ (CompletionOnQualifiedNameReference) astNode;
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.sourcePositions.length - 1];
- CompletionOnJavadocMessageSend messageSend = (CompletionOnJavadocMessageSend) astNode;
- TypeBinding[] argTypes = null; //computeTypes(messageSend.arguments);
- this.completionToken = messageSend.selector;
- this.javadocTagPosition = messageSend.tagSourceStart;
-
- // Set source range
- int rangeStart = astNode.sourceStart;
- if (messageSend.receiver.isThis()) {
- if (messageSend.completeInText()) {
- rangeStart = messageSend.separatorPosition;
- }
- } else if (messageSend.completeInText()) {
- rangeStart = messageSend.receiver.sourceStart;
- }
- setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
-
- if (qualifiedBinding == null) {
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- findImplicitMessageSends(this.completionToken, argTypes, scope, messageSend, scope, new ObjectVector());
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // complete field members with missing fields type
+ // class X {
+ // Missing f;
+ // void foo() {
+ // f.|
+ // }
+ // }
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ boolean foundSomeFields = findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+
+ if (!foundSomeFields) {
+
+ checkTimeout();
+
+ findMembersFromMissingType(
+ ref.tokens[0],
+ ref.sourcePositions[0],
+ null,
+ scope,
+ ref,
+ ref.isInsideAnnotationAttribute);
}
- } else if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- findMethods(
+ }
+ }
+ } else if (qualifiedBinding instanceof VariableBinding) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ TypeBinding receiverType = ((VariableBinding) qualifiedBinding).type;
+ if (receiverType != null && (receiverType.tagBits & TagBits.HasMissingType) == 0) {
+ ObjectVector fieldsFound = new ObjectVector();
+ ObjectVector methodsFound = new ObjectVector();
+
+ findFieldsAndMethods(
this.completionToken,
- null,
- argTypes,
- (ReferenceBinding) ((ReferenceBinding) qualifiedBinding).capture(scope, messageSend.receiver.sourceEnd),
+ receiverType.capture(scope, ref.sourceEnd),
scope,
- new ObjectVector(),
- false,
- false/* prefix match */,
- false,
- messageSend,
+ fieldsFound,
+ methodsFound,
+ ref,
scope,
false,
- messageSend.receiver instanceof SuperReference,
- true,
+ false,
null,
null,
null,
@@ -2039,3034 +2388,2685 @@
null,
-1,
-1);
- }
- } else if (astNode instanceof CompletionOnJavadocAllocationExpression) {
-// setSourceRange(astNode.sourceStart, astNode.sourceEnd, false);
+
+ checkTimeout();
- CompletionOnJavadocAllocationExpression allocExpression = (CompletionOnJavadocAllocationExpression) astNode;
- this.javadocTagPosition = allocExpression.tagSourceStart;
- int rangeStart = astNode.sourceStart;
- if (allocExpression.type.isThis()) {
- if (allocExpression.completeInText()) {
- rangeStart = allocExpression.separatorPosition;
- }
- } else if (allocExpression.completeInText()) {
- rangeStart = allocExpression.type.sourceStart;
- }
- setSourceAndTokenRange(rangeStart, astNode.sourceEnd, false);
- TypeBinding[] argTypes = computeTypes(allocExpression.arguments);
-
- ReferenceBinding ref = (ReferenceBinding) qualifiedBinding;
- if (!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && ref.isClass()) {
- findConstructors(ref, argTypes, scope, allocExpression, false);
- }
- } else if (astNode instanceof CompletionOnJavadocParamNameReference) {
- if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
- CompletionOnJavadocParamNameReference paramRef = (CompletionOnJavadocParamNameReference) astNode;
- setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
- findJavadocParamNames(paramRef.token, paramRef.missingParams, false);
- findJavadocParamNames(paramRef.token, paramRef.missingTypeParams, true);
- }
- } else if (astNode instanceof CompletionOnJavadocTypeParamReference) {
- if (!this.requestor.isIgnored(CompletionProposal.JAVADOC_PARAM_REF)) {
- CompletionOnJavadocTypeParamReference paramRef = (CompletionOnJavadocTypeParamReference) astNode;
- setSourceAndTokenRange(paramRef.tagSourceStart, paramRef.tagSourceEnd);
- findJavadocParamNames(paramRef.token, paramRef.missingParams, true);
- }
- } else if (astNode instanceof CompletionOnJavadocTag) {
- CompletionOnJavadocTag javadocTag = (CompletionOnJavadocTag) astNode;
- setSourceAndTokenRange(javadocTag.tagSourceStart, javadocTag.sourceEnd);
- findJavadocBlockTags(javadocTag);
- findJavadocInlineTags(javadocTag);
- }
- }
- return true;
- }
-
- private void findFieldsAndMethodsFromCastedReceiver(
- ASTNode enclosingNode,
- Binding qualifiedBinding,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector methodsFound,
- InvocationSite invocationSite,
- Scope invocationScope,
- Expression receiver) {
-
- if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
-
- IfStatement ifStatement = (IfStatement)enclosingNode;
-
- if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
-
- InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
-
- TypeReference instanceOfType = instanceOfExpression.type;
-
- if (instanceOfType.resolvedType == null) return;
-
- boolean findFromAnotherReceiver = false;
-
- char[][] receiverName = null;
- int receiverStart = -1;
- int receiverEnd = -1;
-
- if (receiver instanceof QualifiedNameReference) {
- QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
-
- receiverName = qualifiedNameReference.tokens;
-
- if (receiverName.length != 1) return;
-
- receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
- receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
-
- // if (local instanceof X) local.|
- // if (field instanceof X) field.|
- if (instanceOfExpression.expression instanceof SingleNameReference &&
- ((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
- (qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
- findFromAnotherReceiver = true;
- }
+ findFieldsAndMethodsFromCastedReceiver(
+ enclosingNode,
+ qualifiedBinding,
+ scope,
+ fieldsFound,
+ methodsFound,
+ ref,
+ scope,
+ ref);
- // if (this.field instanceof X) field.|
- if (instanceOfExpression.expression instanceof FieldReference) {
- FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
+ } else if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_REF) ||
+ this.requestor.isAllowingRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_REF))) {
+ boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+ boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
+ if (proposeField || proposeMethod) {
+ if(ref.tokens.length == 1) {
+ if (qualifiedBinding instanceof LocalVariableBinding) {
+ // complete local variable members with missing variables type
+ // class X {
+ // void foo() {
+ // Missing f;
+ // f.|
+ // }
+ // }
+ LocalVariableBinding localVariableBinding = (LocalVariableBinding) qualifiedBinding;
+ findFieldsAndMethodsFromMissingType(
+ localVariableBinding.declaration.type,
+ localVariableBinding.declaringScope,
+ ref,
+ scope);
+ } else {
+ // complete field members with missing fields type
+ // class X {
+ // Missing f;
+ // void foo() {
+ // f.|
+ // }
+ // }
+ findFieldsAndMethodsFromMissingFieldType(ref.tokens[0], scope, ref, insideTypeAnnotation);
+ }
- if (fieldReference.receiver instanceof ThisReference &&
- qualifiedBinding instanceof FieldBinding &&
- fieldReference.binding == qualifiedBinding) {
- findFromAnotherReceiver = true;
+ }
}
}
- } else if (receiver instanceof FieldReference) {
- FieldReference fieldReference1 = (FieldReference) receiver;
- receiverStart = fieldReference1.sourceStart;
- receiverEnd = fieldReference1.sourceEnd + 1;
-
- if (fieldReference1.receiver instanceof ThisReference) {
+ } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ boolean isInsideAnnotationAttribute = ref.isInsideAnnotationAttribute;
+ ReferenceBinding receiverType = (ReferenceBinding) qualifiedBinding;
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- receiverName = new char[][] {THIS, fieldReference1.token};
+ findMembers(
+ this.completionToken,
+ receiverType,
+ scope,
+ ref,
+ isInsideAnnotationAttribute,
+ null,
+ null,
+ null,
+ false);
- // if (field instanceof X) this.field.|
- if (instanceOfExpression.expression instanceof SingleNameReference &&
- ((SingleNameReference)instanceOfExpression.expression).binding == fieldReference1.binding) {
- findFromAnotherReceiver = true;
- }
+ } else if (qualifiedBinding instanceof PackageBinding) {
- // if (this.field instanceof X) this.field.|
- if (instanceOfExpression.expression instanceof FieldReference) {
- FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- if (fieldReference2.receiver instanceof ThisReference &&
- fieldReference2.binding == fieldReference1.binding) {
- findFromAnotherReceiver = true;
- }
- }
- }
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
}
+ }
+
+ private void completionOnQualifiedTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding,
+ Scope scope) {
+ this.insideQualifiedReference = true;
- if (findFromAnotherReceiver) {
- TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
- char[] castedReceiver = null;
+ CompletionOnQualifiedTypeReference ref =
+ (CompletionOnQualifiedTypeReference) astNode;
- char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
- if(this.source != null) {
- int memberRefStart = this.startPosition;
+ this.assistNodeIsClass = ref.isClass();
+ this.assistNodeIsException = ref.isException();
+ this.assistNodeIsInterface = ref.isInterface();
+ this.assistNodeIsSuperType = ref.isSuperType();
- char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
- char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
+ this.completionToken = ref.completionIdentifier;
+ long completionPosition = ref.sourcePositions[ref.tokens.length];
- castedReceiver =
- CharOperation.concat(
- CharOperation.concat(
- '(',
- CharOperation.concat(
- CharOperation.concat('(', castedTypeChars, ')'),
- receiverChars),
- ')'),
- dotChars);
- } else {
- castedReceiver =
- CharOperation.concat(
- CharOperation.concat(
- '(',
- CharOperation.concat(
- CharOperation.concat('(', castedTypeChars, ')'),
- CharOperation.concatWith(receiverName, '.')),
- ')'),
- DOT);
+ // get the source positions of the completion identifier
+ if (qualifiedBinding.problemId() == ProblemReasons.NotFound) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ if (this.assistNodeInJavadoc == 0 &&
+ (this.requestor.isAllowingRequiredProposals(CompletionProposal.TYPE_REF, CompletionProposal.TYPE_REF))) {
+ if(ref.tokens.length == 1) {
+ findMemberTypesFromMissingType(
+ ref.tokens[0],
+ ref.sourcePositions[0],
+ scope);
+ }
}
+ } else if (qualifiedBinding instanceof ReferenceBinding && !(qualifiedBinding instanceof TypeVariableBinding)) {
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ setSourceAndTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- if (castedReceiver == null) return;
+ ObjectVector typesFound = new ObjectVector();
- int oldStartPosition = this.startPosition;
- this.startPosition = receiverStart;
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ (ReferenceBinding)qualifiedBinding,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkTimeout();
- findFieldsAndMethods(
+ findMemberTypes(
this.completionToken,
- receiverTypeBinding,
+ (ReferenceBinding) qualifiedBinding,
scope,
- fieldsFound,
- methodsFound,
- invocationSite,
- invocationScope,
+ scope.enclosingSourceType(),
false,
false,
+ typesFound,
null,
null,
null,
- false,
- castedReceiver,
- receiverStart,
- receiverEnd);
+ false);
+ }
+ } else if (qualifiedBinding instanceof PackageBinding) {
- this.startPosition = oldStartPosition;
+ setSourceRange(astNode.sourceStart, (int) completionPosition);
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ // replace to the end of the completion identifier
+ findTypesAndSubpackages(this.completionToken, (PackageBinding) qualifiedBinding, scope);
}
}
+
+ private void completionOnSingleNameReference(ASTNode astNode, ASTNode astNodeParent, Scope scope,
+ boolean insideTypeAnnotation) {
+ CompletionOnSingleNameReference singleNameReference = (CompletionOnSingleNameReference) astNode;
+ this.completionToken = singleNameReference.token;
+ SwitchStatement switchStatement = astNodeParent instanceof SwitchStatement ? (SwitchStatement) astNodeParent : null;
+ if (switchStatement != null
+ && switchStatement.expression.resolvedType != null
+ && switchStatement.expression.resolvedType.isEnum()) {
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ this.assistNodeIsEnum = true;
+ findEnumConstantsFromSwithStatement(this.completionToken, (SwitchStatement) astNodeParent);
+ }
+ } else if (this.expectedTypesPtr > -1 && this.expectedTypes[0].isAnnotationType()) {
+ findTypesAndPackages(this.completionToken, scope, false, false, new ObjectVector());
+ } else {
+ if (this.expectedTypesPtr > -1) {
+ this.assistNodeIsEnum = true;
+ done : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (!this.expectedTypes[i].isEnum()) {
+ this.assistNodeIsEnum = false;
+ break done;
+ }
+ }
- public void complete(IType type, char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
- if(this.requestor != null){
- this.requestor.beginReporting();
- }
- boolean contextAccepted = false;
- IType topLevelType = type;
- while(topLevelType.getDeclaringType() != null) {
- topLevelType = topLevelType.getDeclaringType();
+ }
+ if (scope instanceof BlockScope && !this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ char[][] alreadyDefinedName = computeAlreadyDefinedName((BlockScope)scope, singleNameReference);
+
+ findUnresolvedReference(
+ singleNameReference.sourceStart,
+ singleNameReference.sourceEnd,
+ (BlockScope)scope,
+ alreadyDefinedName);
+ }
+
+ checkTimeout();
+
+ findVariablesAndMethods(
+ this.completionToken,
+ scope,
+ singleNameReference,
+ scope,
+ insideTypeAnnotation,
+ singleNameReference.isInsideAnnotationAttribute);
+
+ checkTimeout();
+
+ // can be the start of a qualified type name
+ findTypesAndPackages(this.completionToken, scope, true, false, new ObjectVector());
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ if (this.completionToken != null && this.completionToken.length != 0) {
+ findKeywords(this.completionToken, singleNameReference.possibleKeywords, false, false);
+ } else {
+ findTrueOrFalseKeywords(singleNameReference.possibleKeywords);
+ }
+ }
+ if (singleNameReference.canBeExplicitConstructor && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)){
+ if (CharOperation.prefixEquals(this.completionToken, Keywords.THIS, false)) {
+ ReferenceBinding ref = scope.enclosingSourceType();
+ findExplicitConstructors(Keywords.THIS, ref, (MethodScope)scope, singleNameReference);
+ } else if (CharOperation.prefixEquals(this.completionToken, Keywords.SUPER, false)) {
+ ReferenceBinding ref = scope.enclosingSourceType();
+ findExplicitConstructors(Keywords.SUPER, ref.superclass(), (MethodScope)scope, singleNameReference);
+ }
+ }
}
+ }
+
+ private void completionOnSingleTypeReference(ASTNode astNode, ASTNode astNodeParent, Binding qualifiedBinding, Scope scope) {
+ CompletionOnSingleTypeReference singleRef = (CompletionOnSingleTypeReference) astNode;
- this.fileName = topLevelType.getParent().getElementName().toCharArray();
- CompilationResult compilationResult = new CompilationResult(this.fileName, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+ this.completionToken = singleRef.token;
- CompilationUnitDeclaration compilationUnit = null;
+ this.assistNodeIsClass = singleRef.isClass();
+ this.assistNodeIsException = singleRef.isException();
+ this.assistNodeIsInterface = singleRef.isInterface();
+ this.assistNodeIsConstructor = singleRef.isConstructorType;
+ this.assistNodeIsSuperType = singleRef.isSuperType();
+
+ // can be the start of a qualified type name
+ if (qualifiedBinding == null) {
+ if (this.completionToken.length == 0 &&
+ (astNodeParent instanceof ParameterizedSingleTypeReference ||
+ astNodeParent instanceof ParameterizedQualifiedTypeReference)) {
+ this.setSourceAndTokenRange(astNode.sourceStart, astNode.sourceStart - 1, false);
- try {
- // TypeConverter is used instead of SourceTypeConverter because the type
- // to convert can be a binary type or a source type
- TypeDeclaration typeDeclaration = null;
- if (type instanceof SourceType) {
- SourceType sourceType = (SourceType) type;
- ISourceType info = (ISourceType) sourceType.getElementInfo();
- compilationUnit = SourceTypeConverter.buildCompilationUnit(
- new ISourceType[] {info},//sourceTypes[0] is always toplevel here
- SourceTypeConverter.FIELD_AND_METHOD // need field and methods
- | SourceTypeConverter.MEMBER_TYPE, // need member types
- // no need for field initialization
- this.problemReporter,
- compilationResult);
- if (compilationUnit.types != null)
- typeDeclaration = compilationUnit.types[0];
+ findParameterizedType((TypeReference)astNodeParent, scope);
} else {
- compilationUnit = new CompilationUnitDeclaration(this.problemReporter, compilationResult, 0);
- typeDeclaration = new BinaryTypeConverter(this.parser.problemReporter(), compilationResult, null/*no need to remember type names*/).buildTypeDeclaration(type, compilationUnit);
+ ObjectVector typesFound = new ObjectVector();
+ if (this.assistNodeIsException && astNodeParent instanceof TryStatement) {
+ findExceptionFromTryStatement(
+ this.completionToken,
+ null,
+ scope.enclosingSourceType(),
+ (BlockScope)scope,
+ typesFound);
+ }
+
+ checkTimeout();
+
+ findTypesAndPackages(this.completionToken, scope, this.assistNodeIsConstructor, false, typesFound);
}
+ } else if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findMemberTypes(
+ this.completionToken,
+ (ReferenceBinding) qualifiedBinding,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ false,
+ false,
+ !this.assistNodeIsConstructor,
+ null,
+ new ObjectVector(),
+ null,
+ null,
+ null,
+ false);
+ }
+ }
- if(typeDeclaration != null) {
- // build AST from snippet
- Initializer fakeInitializer = parseSnippeInitializer(snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic);
+ private char[][] computeAlreadyDefinedName(
+ BlockScope scope,
+ InvocationSite invocationSite) {
+ ArrayList result = new ArrayList();
- // merge AST
- FieldDeclaration[] oldFields = typeDeclaration.fields;
- FieldDeclaration[] newFields = null;
- if (oldFields != null) {
- newFields = new FieldDeclaration[oldFields.length + 1];
- System.arraycopy(oldFields, 0, newFields, 0, oldFields.length);
- newFields[oldFields.length] = fakeInitializer;
- } else {
- newFields = new FieldDeclaration[] {fakeInitializer};
- }
- typeDeclaration.fields = newFields;
+ boolean staticsOnly = false;
- if(DEBUG) {
- System.out.println("SNIPPET COMPLETION AST :"); //$NON-NLS-1$
- System.out.println(compilationUnit.toString());
- }
-
- if (compilationUnit.types != null) {
- try {
- this.lookupEnvironment.buildTypeBindings(compilationUnit, null /*no access restriction*/);
+ Scope currentScope = scope;
- if ((this.unitScope = compilationUnit.scope) != null) {
- this.lookupEnvironment.completeTypeBindings(compilationUnit, true);
- compilationUnit.scope.faultInTypes();
- compilationUnit.resolve();
- }
- } catch (CompletionNodeFound e) {
- // completionNodeFound = true;
- if (e.astNode != null) {
- // if null then we found a problem in the completion node
- contextAccepted =
- complete(
- e.astNode,
- this.parser.assistNodeParent,
- this.parser.enclosingNode,
- compilationUnit,
- e.qualifiedBinding,
- e.scope,
- e.insideTypeAnnotation);
- }
- }
- }
- if(this.noProposal && this.problem != null) {
- if(!contextAccepted) {
- contextAccepted = true;
- InternalCompletionContext context = new InternalCompletionContext();
- if (this.requestor.isExtendedContextRequired()) context.setExtended();
- this.requestor.acceptContext(context);
- }
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
- }
- }
- }
- } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D (added with fix of 99629)
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch (InvalidCursorLocation e) { // may eventually report a usefull error (added to fix 99629)
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object (added with fix of 99629)
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch (CompletionNodeFound e){ // internal failure - bugs 5618 (added with fix of 99629)
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch(JavaModelException e) {
- // Do nothing
- }
- if(!contextAccepted) {
- contextAccepted = true;
- InternalCompletionContext context = new InternalCompletionContext();
- if (this.requestor.isExtendedContextRequired()) context.setExtended();
- this.requestor.acceptContext(context);
- }
- if(this.requestor != null){
- this.requestor.endReporting();
- }
- }
+ done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
- StringBuffer prefix = new StringBuffer();
- prefix.append("public class FakeType {\n "); //$NON-NLS-1$
- if(isStatic) {
- prefix.append("static "); //$NON-NLS-1$
- }
- prefix.append("{\n"); //$NON-NLS-1$
- for (int i = 0; i < localVariableTypeNames.length; i++) {
- ASTNode.printModifiers(localVariableModifiers[i], prefix);
- prefix.append(' ');
- prefix.append(localVariableTypeNames[i]);
- prefix.append(' ');
- prefix.append(localVariableNames[i]);
- prefix.append(';');
- }
+ switch (currentScope.kind) {
- char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
- this.offset = prefix.length();
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) currentScope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- String encoding = this.compilerOptions.defaultEncoding;
- BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
- fakeSource,
- null,
- "FakeType.java", //$NON-NLS-1$
- encoding);
+ //$FALL-THROUGH$
+ case Scope.BLOCK_SCOPE :
+ BlockScope blockScope = (BlockScope) currentScope;
- this.actualCompletionPosition = prefix.length() + position - 1;
+ next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+ LocalVariableBinding local = blockScope.locals[i];
- CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
- CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
+ if (local == null)
+ break next;
- parseBlockStatements(fakeAST, this.actualCompletionPosition);
+ if (local.isSecret())
+ continue next;
- return (Initializer)fakeAST.types[0].fields[0];
- }
+ result.add(local.name);
+ }
+ break;
- /**
- * Ask the engine to compute a completion at the specified position
- * of the given compilation unit.
- *
- * No return
- * completion results are answered through a requestor.
- *
- * @param sourceUnit org.eclipse.jdt.internal.compiler.env.ICompilationUnit
- * the source of the current compilation unit.
- *
- * @param completionPosition int
- * a position in the source where the completion is taking place.
- * This position is relative to the source provided.
- */
- public void complete(ICompilationUnit sourceUnit, int completionPosition, int pos, ITypeRoot root) {
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) currentScope;
+ SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+ computeAlreadyDefinedName(
+ enclosingType,
+ classScope,
+ staticsOnly,
+ invocationSite,
+ result);
+ staticsOnly |= enclosingType.isStatic();
+ break;
- if(DEBUG) {
- System.out.print("COMPLETION IN "); //$NON-NLS-1$
- System.out.print(sourceUnit.getFileName());
- System.out.print(" AT POSITION "); //$NON-NLS-1$
- System.out.println(completionPosition);
- System.out.println("COMPLETION - Source :"); //$NON-NLS-1$
- System.out.println(sourceUnit.getContents());
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done1;
+ }
+ currentScope = currentScope.parent;
}
- this.requestor.beginReporting();
- boolean contextAccepted = false;
- try {
- this.fileName = sourceUnit.getFileName();
- this.actualCompletionPosition = completionPosition - 1;
- this.offset = pos;
- this.typeRoot = root;
- // for now until we can change the UI.
- CompilationResult result = new CompilationResult(sourceUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
- CompilationUnitDeclaration parsedUnit = this.parser.dietParse(sourceUnit, result, this.actualCompletionPosition);
- // boolean completionNodeFound = false;
- if (parsedUnit != null) {
- if(DEBUG) {
- System.out.println("COMPLETION - Diet AST :"); //$NON-NLS-1$
- System.out.println(parsedUnit.toString());
- }
+ if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
- // scan the package & import statements first
- if (parsedUnit.currentPackage instanceof CompletionOnPackageReference) {
- contextAccepted = true;
- buildContext(parsedUnit.currentPackage, null, parsedUnit, null, null);
- if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
- findPackages((CompletionOnPackageReference) parsedUnit.currentPackage);
- }
- if(this.noProposal && this.problem != null) {
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
- }
- }
- return;
- }
+ return (char[][])result.toArray(new char[result.size()][]);
+ }
- ImportReference[] imports = parsedUnit.imports;
- if (imports != null) {
- for (int i = 0, length = imports.length; i < length; i++) {
- ImportReference importReference = imports[i];
- if (importReference instanceof CompletionOnImportReference) {
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
- if ((this.unitScope = parsedUnit.scope) != null) {
- contextAccepted = true;
- buildContext(importReference, null, parsedUnit, null, null);
+ private void computeAlreadyDefinedName(
+ FieldBinding[] fields,
+ Scope scope,
+ boolean onlyStaticFields,
+ ReferenceBinding receiverType,
+ InvocationSite invocationSite,
+ ArrayList result) {
- long positions = importReference.sourcePositions[importReference.sourcePositions.length - 1];
- setSourceAndTokenRange((int) (positions >>> 32), (int) positions);
+ next : for (int f = fields.length; --f >= 0;) {
+ FieldBinding field = fields[f];
- char[][] oldTokens = importReference.tokens;
- int tokenCount = oldTokens.length;
- if (tokenCount == 1) {
- findImports((CompletionOnImportReference)importReference, true);
- } else if(tokenCount > 1){
- this.insideQualifiedReference = true;
+ if (field.isSynthetic()) continue next;
- char[] lastToken = oldTokens[tokenCount - 1];
- char[][] qualifierTokens = CharOperation.subarray(oldTokens, 0, tokenCount - 1);
+ if (onlyStaticFields && !field.isStatic()) continue next;
- Binding binding = this.unitScope.getTypeOrPackage(qualifierTokens);
- if(binding != null) {
- if(binding instanceof PackageBinding) {
- findImports((CompletionOnImportReference)importReference, false);
- } else {
- ReferenceBinding ref = (ReferenceBinding) binding;
+ if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- findImportsOfMemberTypes(lastToken, ref, importReference.isStatic());
- }
- if(importReference.isStatic()) {
+ result.add(field.name);
+ }
+ }
- if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- findImportsOfStaticFields(lastToken, ref);
- }
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
- findImportsOfStaticMethods(lastToken, ref);
- }
- }
- }
- }
- }
+ private void computeAlreadyDefinedName(
+ SourceTypeBinding receiverType,
+ ClassScope scope,
+ boolean onlyStaticFields,
+ InvocationSite invocationSite,
+ ArrayList result) {
- if(this.noProposal && this.problem != null) {
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
- }
- }
- }
- return;
- } else if(importReference instanceof CompletionOnKeyword) {
- contextAccepted = true;
- buildContext(importReference, null, parsedUnit, null, null);
- if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- setSourceAndTokenRange(importReference.sourceStart, importReference.sourceEnd);
- CompletionOnKeyword keyword = (CompletionOnKeyword)importReference;
- findKeywords(keyword.getToken(), keyword.getPossibleKeywords(), false, false);
- }
- if(this.noProposal && this.problem != null) {
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
- }
- }
- return;
- }
+ ReferenceBinding currentType = receiverType;
+ ReferenceBinding[] interfacesToVisit = null;
+ int nextPosition = 0;
+ do {
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ if (interfacesToVisit == null) {
+ interfacesToVisit = itsInterfaces;
+ nextPosition = interfacesToVisit.length;
+ } else {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
}
}
+ }
- if (parsedUnit.types != null) {
- try {
- this.lookupEnvironment.buildTypeBindings(parsedUnit, null /*no access restriction*/);
+ FieldBinding[] fields = currentType.availableFields();
+ if(fields != null && fields.length > 0) {
+ computeAlreadyDefinedName(
+ fields,
+ scope,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ result);
+ }
+ currentType = currentType.superclass();
+ } while ( currentType != null);
- if ((this.unitScope = parsedUnit.scope) != null) {
- this.source = sourceUnit.getContents();
- this.lookupEnvironment.completeTypeBindings(parsedUnit, true);
- parsedUnit.scope.faultInTypes();
- parseBlockStatements(parsedUnit, this.actualCompletionPosition);
- if(DEBUG) {
- System.out.println("COMPLETION - AST :"); //$NON-NLS-1$
- System.out.println(parsedUnit.toString());
- }
- parsedUnit.resolve();
- }
- } catch (CompletionNodeFound e) {
- // completionNodeFound = true;
- if (e.astNode != null) {
- // if null then we found a problem in the completion node
- if(DEBUG) {
- System.out.print("COMPLETION - Completion node : "); //$NON-NLS-1$
- System.out.println(e.astNode.toString());
- if(this.parser.assistNodeParent != null) {
- System.out.print("COMPLETION - Parent Node : "); //$NON-NLS-1$
- System.out.println(this.parser.assistNodeParent);
- }
- }
- this.lookupEnvironment.unitBeingCompleted = parsedUnit; // better resilient to further error reporting
- contextAccepted =
- complete(
- e.astNode,
- this.parser.assistNodeParent,
- this.parser.enclosingNode,
- parsedUnit,
- e.qualifiedBinding,
- e.scope,
- e.insideTypeAnnotation);
- }
+ if (interfacesToVisit != null) {
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding anInterface = interfacesToVisit[i];
+ FieldBinding[] fields = anInterface.availableFields();
+ if(fields != null) {
+ computeAlreadyDefinedName(
+ fields,
+ scope,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ result);
+ }
+
+ ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
}
}
}
+ }
+ }
- if(this.noProposal && this.problem != null) {
- if(!contextAccepted) {
- contextAccepted = true;
- InternalCompletionContext context = new InternalCompletionContext();
- context.setOffset(completionPosition - this.offset);
- context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
- if (this.requestor.isExtendedContextRequired()) context.setExtended();
- this.requestor.acceptContext(context);
- }
- this.requestor.completionFailure(this.problem);
- if(DEBUG) {
- this.printDebug(this.problem);
+ int computeBaseRelevance(){
+ return R_DEFAULT;
+ }
+
+ private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
+
+ // default filter
+ this.expectedTypesFilter = SUBTYPE;
+ this.hasJavaLangObjectAsExpectedType = false;
+
+ // find types from parent
+ if(parent instanceof AbstractVariableDeclaration) {
+ AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
+ TypeBinding binding = variable.type.resolvedType;
+ if(binding != null) {
+ if(!(variable.initialization instanceof ArrayInitializer)) {
+ addExpectedType(binding, scope);
}
}
- /* Ignore package, import, class & interface keywords for now...
- if (!completionNodeFound) {
- if (parsedUnit == null || parsedUnit.types == null) {
- // this is not good enough... can still be trying to define a second type
- CompletionScanner scanner = (CompletionScanner) this.parser.scanner;
- setSourceRange(scanner.completedIdentifierStart, scanner.completedIdentifierEnd);
- findKeywords(scanner.completionIdentifier, mainDeclarations, null);
- }
- // currently have no way to know if extends/implements are possible keywords
- }
- */
- } catch (IndexOutOfBoundsException e) { // work-around internal failure - 1GEMF6D
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch (InvalidCursorLocation e) { // may eventually report a usefull error
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
- }
- } catch (AbortCompilation e) { // ignore this exception for now since it typically means we cannot find java.lang.Object
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
+ } else if(parent instanceof Assignment) {
+ TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
+ if(binding != null) {
+ addExpectedType(binding, scope);
}
- } catch (CompletionNodeFound e){ // internal failure - bugs 5618
- if(DEBUG) {
- System.out.println("Exception caught by CompletionEngine:"); //$NON-NLS-1$
- e.printStackTrace(System.out);
+ } else if(parent instanceof ReturnStatement) {
+ if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
+ MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
+ TypeBinding binding = methodBinding == null ? null : methodBinding.returnType;
+ if(binding != null) {
+ addExpectedType(binding, scope);
+ }
}
- } finally {
- reset();
- if(!contextAccepted) {
- contextAccepted = true;
- InternalCompletionContext context = new InternalCompletionContext();
- context.setTokenKind(CompletionContext.TOKEN_KIND_UNKNOWN);
- context.setOffset(completionPosition - this.offset);
- if (this.requestor.isExtendedContextRequired()) context.setExtended();
- this.requestor.acceptContext(context);
+ } else if(parent instanceof CastExpression) {
+ Expression e = ((CastExpression)parent).type;
+ TypeBinding binding = e.resolvedType;
+ if(binding != null){
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
}
- this.requestor.endReporting();
- }
- }
+ } else if(parent instanceof MessageSend) {
+ MessageSend messageSend = (MessageSend) parent;
- private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
- ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
+ if(messageSend.actualReceiverType instanceof ReferenceBinding) {
+ ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
+ boolean isStatic = messageSend.receiver.isTypeReference();
- if (annotatedElement instanceof TypeDeclaration) {
- TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
- if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
- return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
- }
- return TagBits.AnnotationForType;
- } else if (annotatedElement instanceof FieldDeclaration) {
- if (fakeNode.isParameter) {
- return TagBits.AnnotationForParameter;
+ while(binding != null) {
+ computeExpectedTypesForMessageSend(
+ binding,
+ messageSend.selector,
+ messageSend.arguments,
+ (ReferenceBinding)messageSend.actualReceiverType,
+ scope,
+ messageSend,
+ isStatic);
+ computeExpectedTypesForMessageSendForInterface(
+ binding,
+ messageSend.selector,
+ messageSend.arguments,
+ (ReferenceBinding)messageSend.actualReceiverType,
+ scope,
+ messageSend,
+ isStatic);
+ binding = binding.superclass();
+ }
}
- return TagBits.AnnotationForField;
- } else if (annotatedElement instanceof MethodDeclaration) {
- return TagBits.AnnotationForMethod;
- } else if (annotatedElement instanceof Argument) {
- return TagBits.AnnotationForParameter;
- } else if (annotatedElement instanceof ConstructorDeclaration) {
- return TagBits.AnnotationForConstructor;
- } else if (annotatedElement instanceof LocalDeclaration) {
- return TagBits.AnnotationForLocalVariable;
- } else if (annotatedElement instanceof ImportReference) {
- return TagBits.AnnotationForPackage;
- }
- return 0;
- }
+ } else if(parent instanceof AllocationExpression) {
+ AllocationExpression allocationExpression = (AllocationExpression) parent;
- private TypeBinding[] computeTypes(Expression[] arguments) {
- if (arguments == null) return null;
- int argsLength = arguments.length;
- TypeBinding[] argTypes = new TypeBinding[argsLength];
- for (int a = argsLength; --a >= 0;) {
- argTypes[a] = arguments[a].resolvedType;
- }
- return argTypes;
- }
-
- private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
- if (arguments == null) return null;
- int argsLength = arguments.length;
- TypeBinding[] argTypes = new TypeBinding[argsLength];
- for (int a = argsLength; --a >= 0;) {
- TypeBinding typeBinding = arguments[a].resolvedType;
- if(typeBinding == null || !typeBinding.isValidBinding()) return null;
- argTypes[a] = typeBinding;
- }
- return argTypes;
- }
-
- private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
- MethodBinding[] methods = annotation.availableMethods();
- nextAttribute: for (int i = 0; i < methods.length; i++) {
- MethodBinding method = methods[i];
+ ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
- if(!CharOperation.prefixEquals(token, method.selector, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
+ if(binding != null) {
+ computeExpectedTypesForAllocationExpression(
+ binding,
+ allocationExpression.arguments,
+ scope,
+ allocationExpression);
+ }
+ } else if(parent instanceof OperatorExpression) {
+ int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
+ if(parent instanceof ConditionalExpression) {
+ // for future use
+ } else if(parent instanceof InstanceOfExpression) {
+ InstanceOfExpression e = (InstanceOfExpression) parent;
+ TypeBinding binding = e.expression.resolvedType;
+ if(binding != null){
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+ }
+ } else if(parent instanceof BinaryExpression) {
+ BinaryExpression binaryExpression = (BinaryExpression) parent;
+ switch(operator) {
+ case OperatorIds.EQUAL_EQUAL :
+ // expected type is not relevant in this case
+ TypeBinding binding = binaryExpression.left.resolvedType;
+ if (binding != null) {
+ addExpectedType(binding, scope);
+ this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
+ }
+ break;
+ case OperatorIds.PLUS :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ addExpectedType(scope.getJavaLangString(), scope);
+ break;
+ case OperatorIds.AND_AND :
+ case OperatorIds.OR_OR :
+ case OperatorIds.XOR :
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ break;
+ default :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ }
+ if(operator == OperatorIds.LESS) {
+ if(binaryExpression.left instanceof SingleNameReference){
+ SingleNameReference name = (SingleNameReference) binaryExpression.left;
+ Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
+ if(b instanceof ReferenceBinding) {
+ TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
+ if(typeVariableBindings != null && typeVariableBindings.length > 0) {
+ addExpectedType(typeVariableBindings[0].firstBound, scope);
+ }
- int length = attributesFound == null ? 0 : attributesFound.length;
- for (int j = 0; j < length; j++) {
- if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
+ }
+ }
+ }
+ } else if(parent instanceof UnaryExpression) {
+ switch(operator) {
+ case OperatorIds.NOT :
+ addExpectedType(TypeBinding.BOOLEAN, scope);
+ break;
+ case OperatorIds.TWIDDLE :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ case OperatorIds.PLUS :
+ case OperatorIds.MINUS :
+ case OperatorIds.PLUS_PLUS :
+ case OperatorIds.MINUS_MINUS :
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ addExpectedType(TypeBinding.FLOAT, scope);
+ addExpectedType(TypeBinding.DOUBLE, scope);
+ addExpectedType(TypeBinding.CHAR, scope);
+ addExpectedType(TypeBinding.BYTE, scope);
+ break;
+ }
}
+ } else if(parent instanceof ArrayReference) {
+ addExpectedType(TypeBinding.SHORT, scope);
+ addExpectedType(TypeBinding.INT, scope);
+ addExpectedType(TypeBinding.LONG, scope);
+ } else if(parent instanceof ParameterizedSingleTypeReference) {
+ ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
+ TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+ int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
+ if(typeVariables != null && typeVariables.length >= length) {
+ int index = length - 1;
+ while(index > -1 && ref.typeArguments[index] != node) index--;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal(method);
- relevance += computeRelevanceForCaseMatching(token, method.selector);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ TypeBinding bound = typeVariables[index].firstBound;
+ addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+ }
+ } else if(parent instanceof ParameterizedQualifiedTypeReference) {
+ ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
+ TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
+ TypeReference[][] arguments = ref.typeArguments;
+ if(typeVariables != null) {
+ int iLength = arguments == null ? 0 : arguments.length;
+ done: for (int i = 0; i < iLength; i++) {
+ int jLength = arguments[i] == null ? 0 : arguments[i].length;
+ for (int j = 0; j < jLength; j++) {
+ if(arguments[i][j] == node && typeVariables.length > j) {
+ TypeBinding bound = typeVariables[j].firstBound;
+ addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+ break done;
+ }
+ }
+ }
+ }
+ } else if(parent instanceof MemberValuePair) {
+ MemberValuePair memberValuePair = (MemberValuePair) parent;
+ if(memberValuePair.binding != null) {
+ addExpectedType(memberValuePair.binding.returnType, scope);
+ }
+ } else if (parent instanceof NormalAnnotation) {
+ NormalAnnotation annotation = (NormalAnnotation) parent;
+ MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
+ if(memberValuePairs == null || memberValuePairs.length == 0) {
+ if(annotation.resolvedType instanceof ReferenceBinding) {
+ MethodBinding[] methodBindings =
+ ((ReferenceBinding)annotation.resolvedType).availableMethods();
+ if (methodBindings != null &&
+ methodBindings.length > 0 &&
+ CharOperation.equals(methodBindings[0].selector, VALUE)) {
+ boolean canBeSingleMemberAnnotation = true;
+ done : for (int i = 1; i < methodBindings.length; i++) {
+ if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
+ canBeSingleMemberAnnotation = false;
+ break done;
+ }
+ }
+ if (canBeSingleMemberAnnotation) {
+ this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
+ addExpectedType(methodBindings[0].returnType, scope);
+ }
+ }
+ }
+ }
+ } else if (parent instanceof TryStatement) {
+ boolean isException = false;
+ if (node instanceof CompletionOnSingleTypeReference) {
+ isException = ((CompletionOnSingleTypeReference)node).isException();
+ } else if (node instanceof CompletionOnQualifiedTypeReference) {
+ isException = ((CompletionOnQualifiedTypeReference)node).isException();
+ } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
+ }
+ if (isException) {
+ ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
+ ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
+ if (bindings != null && bindings.length > 0) {
+ for (int i = 0; i < bindings.length; i++) {
+ addExpectedType(bindings[i], scope);
+ }
+ this.expectedTypesFilter = SUPERTYPE;
+ }
+ }
+ } else if (parent instanceof SwitchStatement) {
+ SwitchStatement switchStatement = (SwitchStatement) parent;
+ if (switchStatement.expression != null &&
+ switchStatement.expression.resolvedType != null) {
+ addExpectedType(switchStatement.expression.resolvedType, scope);
+ }
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
- CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method.returnType));
- proposal.setName(method.selector);
- proposal.setCompletion(method.selector);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ // Expected types for javadoc
+ } else if (parent instanceof Javadoc) {
+ if (scope.kind == Scope.METHOD_SCOPE) {
+ MethodScope methodScope = (MethodScope) scope;
+ AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
+ if (methodDecl != null && methodDecl.binding != null) {
+ ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
+ if (exceptions != null) {
+ for (int i = 0; i < exceptions.length; i++) {
+ addExpectedType(exceptions[i], scope);
+ }
+ }
}
}
}
+
+ if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
+ System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
+ }
}
- private void findAnonymousType(
- ReferenceBinding currentType,
- TypeBinding[] argTypes,
+
+ private void computeExpectedTypesForAllocationExpression(
+ ReferenceBinding binding,
+ Expression[] arguments,
Scope scope,
InvocationSite invocationSite) {
- if (currentType.isInterface()) {
- char[] completion = CharOperation.NO_CHAR;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ MethodBinding[] methods = binding.availableMethods();
+ nextMethod : for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setDeclarationKey(currentType.computeUniqueKey());
- proposal.setSignature(
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR,
- CharOperation.NO_CHAR));
- //proposal.setOriginalSignature(null);
- //proposal.setUniqueKey(null);
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- //proposal.setParameterPackageNames(null);
- //proposal.setParameterTypeNames(null);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setCompletion(completion);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- findConstructors(
- currentType,
- argTypes,
- scope,
- invocationSite,
- true);
- }
- }
+ if (!method.isConstructor()) continue nextMethod;
- private void findClassField(
- char[] token,
- TypeBinding receiverType,
- Scope scope,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
+ if (method.isSynthetic()) continue nextMethod;
- if (token == null) return;
+ if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
- if (token.length <= classField.length
- && CharOperation.prefixEquals(token, classField, false /* ignore case */
- )) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, classField);
- relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
- relevance += R_NON_INHERITED;
+ TypeBinding[] parameters = method.parameters;
+ if(parameters.length < arguments.length)
+ continue nextMethod;
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+ int length = arguments.length - 1;
+
+ for (int j = 0; j < length; j++) {
+ Expression argument = arguments[j];
+ TypeBinding argType = argument.resolvedType;
+ if(argType != null && !argType.isCompatibleWith(parameters[j]))
+ continue nextMethod;
}
- this.noProposal = false;
- if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- //proposal.setDeclarationSignature(null);
- char[] signature =
- createNonGenericTypeSignature(
- CharOperation.concatWith(JAVA_LANG, '.'),
- CLASS);
- if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
- // add type argument
- char[] typeArgument = getTypeSignature(receiverType);
- int oldLength = signature.length;
- int argumentLength = typeArgument.length;
- int newLength = oldLength + argumentLength + 2;
- System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
- signature[oldLength - 1] = '<';
- System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
- signature[newLength - 2] = '>';
- signature[newLength - 1] = ';';
- }
- proposal.setSignature(signature);
- //proposal.setDeclarationPackageName(null);
- //proposal.setDeclarationTypeName(null);
- proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
- proposal.setTypeName(CLASS);
- proposal.setName(classField);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(classField);
- proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
+ TypeBinding expectedType = method.parameters[arguments.length - 1];
+ if(expectedType != null) {
+ addExpectedType(expectedType, scope);
}
}
}
+ private void computeExpectedTypesForMessageSend(
+ ReferenceBinding binding,
+ char[] selector,
+ Expression[] arguments,
+ ReferenceBinding receiverType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isStatic) {
- private void findEnumConstants(
- char[] enumConstantName,
- ReferenceBinding enumType,
- Scope invocationScope,
- ObjectVector fieldsFound,
- char[][] alreadyUsedConstants,
- int alreadyUsedConstantCount,
- boolean needQualification) {
+ MethodBinding[] methods = binding.availableMethods();
+ nextMethod : for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
- FieldBinding[] fields = enumType.fields();
+ if (method.isSynthetic()) continue nextMethod;
- int enumConstantLength = enumConstantName.length;
- next : for (int f = fields.length; --f >= 0;) {
- FieldBinding field = fields[f];
+ if (method.isDefaultAbstract()) continue nextMethod;
- if (field.isSynthetic()) continue next;
+ if (method.isConstructor()) continue nextMethod;
- if ((field.modifiers & Flags.AccEnum) == 0) continue next;
+ if (isStatic && !method.isStatic()) continue nextMethod;
- if (enumConstantLength > field.name.length) continue next;
+ if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
- if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name))) continue next;
+ if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
- char[] fieldName = field.name;
+ TypeBinding[] parameters = method.parameters;
+ if(parameters.length < arguments.length)
+ continue nextMethod;
- for (int i = 0; i < alreadyUsedConstantCount; i++) {
- if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
+ int length = arguments.length - 1;
+
+ for (int j = 0; j < length; j++) {
+ Expression argument = arguments[j];
+ TypeBinding argType = argument.resolvedType;
+ if(argType != null && !argType.isCompatibleWith(parameters[j]))
+ continue nextMethod;
}
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal(field);
- relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
- relevance += computeRelevanceForExpectingType(field.type);
- relevance += computeRelevanceForEnumConstant(field.type);
- relevance += computeRelevanceForQualification(needQualification);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ TypeBinding expectedType = method.parameters[arguments.length - 1];
+ if(expectedType != null) {
+ addExpectedType(expectedType, scope);
+ }
+ }
+ }
+ private void computeExpectedTypesForMessageSendForInterface(
+ ReferenceBinding binding,
+ char[] selector,
+ Expression[] arguments,
+ ReferenceBinding receiverType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isStatic) {
- this.noProposal = false;
- if (!needQualification) {
- char[] completion = fieldName;
+ ReferenceBinding[] itsInterfaces = binding.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ ReferenceBinding[] interfacesToVisit = itsInterfaces;
+ int nextPosition = interfacesToVisit.length;
- if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding currentType = interfacesToVisit[i];
+ computeExpectedTypesForMessageSend(
+ currentType,
+ selector,
+ arguments,
+ receiverType,
+ scope,
+ invocationSite,
+ isStatic);
+
+ if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
}
}
+ }
+ }
+ }
- } else {
- TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
- boolean needImport = visibleType == null || !visibleType.isValidBinding();
-
- char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
-
- if (!needImport) {
- if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
+ this.forbbidenBindingsFilter = NONE;
+ if(scope instanceof ClassScope) {
+ TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
+ if(typeDeclaration.superclass == astNode) {
+ addForbiddenBindings(typeDeclaration.binding);
+ return scope.parent;
+ }
+ TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
+ int length = superInterfaces == null ? 0 : superInterfaces.length;
+ for (int i = 0; i < length; i++) {
+ if(superInterfaces[i] == astNode) {
+ addForbiddenBindings(typeDeclaration.binding);
+ return scope.parent;
+ }
+ }
+ } else {
+ if (astNodeParent != null && astNodeParent instanceof TryStatement) {
+ boolean isException = false;
+ if (astNode instanceof CompletionOnSingleTypeReference) {
+ isException = ((CompletionOnSingleTypeReference)astNode).isException();
+ } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
+ isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
+ } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
+ isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
+ }
+ if (isException) {
+ Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
+ int length = catchArguments == null ? 0 : catchArguments.length;
+ for (int i = 0; i < length; i++) {
+ TypeBinding caughtException = catchArguments[i].type.resolvedType;
+ if (caughtException != null) {
+ addForbiddenBindings(caughtException);
+ this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
}
}
- } else {
- if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
- CompilationUnitDeclaration cu = this.unitScope.referenceContext;
- int importStart = cu.types[0].declarationSourceStart;
- int importEnd = importStart;
+ this.forbbidenBindingsFilter = SUBTYPE;
+ }
+ }
+ }
+// else if(scope instanceof MethodScope) {
+// MethodScope methodScope = (MethodScope) scope;
+// if(methodScope.insideTypeAnnotation) {
+// return methodScope.parent.parent;
+// }
+// }
+ return scope;
+ }
- ReferenceBinding fieldType = (ReferenceBinding)field.type;
+ private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
+ StringBuffer completion = new StringBuffer(10);
- char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
+ if (isStatic) {
+ completion.append(declarationType.sourceName());
- InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
- typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
- typeImportProposal.completionEngine = this;
- char[] packageName = fieldType.qualifiedPackageName();
- typeImportProposal.setDeclarationSignature(packageName);
- typeImportProposal.setSignature(getSignature(fieldType));
- typeImportProposal.setPackageName(packageName);
- typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
- typeImportProposal.setCompletion(typeImportCompletion);
- typeImportProposal.setFlags(fieldType.modifiers);
- typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
- typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setRelevance(relevance);
+ } else if (declarationType == invocationType) {
+ completion.append(THIS);
- proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+ } else {
+
+ if (!declarationType.isNestedType()) {
+
+ completion.append(declarationType.sourceName());
+ completion.append('.');
+ completion.append(THIS);
+
+ } else if (!declarationType.isAnonymousType()) {
+
+ completion.append(declarationType.sourceName());
+ completion.append('.');
+ completion.append(THIS);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
}
}
+
+ return completion.toString().toCharArray();
}
- private void findEnumConstantsFromExpectedTypes(
- char[] token,
- Scope invocationScope,
- ObjectVector fieldsFound) {
- int length = this.expectedTypesPtr + 1;
- for (int i = 0; i < length; i++) {
- if (this.expectedTypes[i].isEnum()) {
- findEnumConstants(
- token,
- (ReferenceBinding)this.expectedTypes[i],
- invocationScope,
- fieldsFound,
- CharOperation.NO_CHAR_CHAR,
- 0,
- true);
- }
+ private int computeRelevanceForAnnotation(){
+ if(this.assistNodeIsAnnotation) {
+ return R_ANNOTATION;
}
+ return 0;
+ }
+ private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
+ if (this.assistNodeIsAnnotation &&
+ (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
+ long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+ if(target == 0 || (target & this.targetedElement) != 0) {
+ return R_TARGET;
+ }
+ }
+ return 0;
+ }
+ int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
+ if (this.options.camelCaseMatch) {
+ if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE + R_EXACT_NAME;
+ } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE;
+ } else if (CharOperation.camelCaseMatch(token, proposalName)){
+ return R_CAMEL_CASE;
+ } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+ return R_EXACT_NAME;
+ }
+ } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
+ if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
+ return R_CASE + R_EXACT_NAME;
+ } else {
+ return R_CASE;
+ }
+ } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
+ return R_EXACT_NAME;
+ }
+ return 0;
}
- private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
- TypeBinding expressionType = switchStatement.expression.resolvedType;
- if(expressionType != null && expressionType.isEnum()) {
- ReferenceBinding enumType = (ReferenceBinding) expressionType;
+ private int computeRelevanceForClass(){
+ if(this.assistNodeIsClass) {
+ return R_CLASS;
+ }
+ return 0;
+ }
- CaseStatement[] cases = switchStatement.cases;
+ private int computeRelevanceForEnum(){
+ if(this.assistNodeIsEnum) {
+ return R_ENUM;
+ }
+ return 0;
+ }
- char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
- int alreadyUsedConstantCount = 0;
- for (int i = 0; i < switchStatement.caseCount; i++) {
- Expression caseExpression = cases[i].constantExpression;
- if((caseExpression instanceof SingleNameReference)
- && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
- alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
+ private int computeRelevanceForEnumConstant(TypeBinding proposalType){
+ if(this.assistNodeIsEnum &&
+ proposalType != null &&
+ this.expectedTypes != null) {
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if (proposalType.isEnum() &&
+ proposalType == this.expectedTypes[i]) {
+ return R_ENUM + R_ENUM_CONSTANT;
}
+
}
+ }
+ return 0;
+ }
- findEnumConstants(
- enumConstantName,
- enumType,
- null /* doesn't need invocation scope */,
- new ObjectVector(),
- alreadyUsedConstants,
- alreadyUsedConstantCount,
- false);
+ private int computeRelevanceForException(){
+ if (this.assistNodeIsException) {
+ return R_EXCEPTION;
}
+ return 0;
}
- private void findExceptionFromTryStatement(
- char[] typeName,
- ReferenceBinding exceptionType,
- ReferenceBinding receiverType,
- SourceTypeBinding invocationType,
- BlockScope scope,
- ObjectVector typesFound,
- boolean searchSuperClasses) {
+ private int computeRelevanceForException(char[] proposalName){
- if (searchSuperClasses) {
- ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
- if (exceptionType != javaLangThrowable) {
- ReferenceBinding superClass = exceptionType.superclass();
- while(superClass != null && superClass != javaLangThrowable) {
- findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
- superClass = superClass.superclass();
+ if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
+ (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
+ CharOperation.match(ERROR_PATTERN, proposalName, false))) {
+ return R_EXCEPTION;
+ }
+ return 0;
+ }
+
+ private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
+ if(this.expectedTypes != null) {
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
+ return R_EXACT_EXPECTED_TYPE;
}
}
+ if(this.hasJavaLangObjectAsExpectedType) {
+ return R_EXPECTED_TYPE;
+ }
}
+ return 0;
+ }
- if (typeName.length > exceptionType.sourceName.length)
- return;
+ private int computeRelevanceForExpectingType(TypeBinding proposalType){
+ if(this.expectedTypes != null && proposalType != null) {
+ int relevance = 0;
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ if((this.expectedTypesFilter & SUBTYPE) != 0
+ && proposalType.isCompatibleWith(this.expectedTypes[i])) {
- if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
- return;
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+ return R_EXACT_EXPECTED_TYPE;
+ }
- if (this.options.checkDeprecation &&
- exceptionType.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(exceptionType))
- return;
+ relevance = R_EXPECTED_TYPE;
+ }
+ if((this.expectedTypesFilter & SUPERTYPE) != 0
+ && this.expectedTypes[i].isCompatibleWith(proposalType)) {
- if (this.options.checkVisibility) {
- if (invocationType != null) {
- if (receiverType != null) {
- if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
- } else {
- if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
+ if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
+ CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
+ return R_EXACT_EXPECTED_TYPE;
+ }
+
+ relevance = R_EXPECTED_TYPE;
}
- } else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
- return;
}
+ return relevance;
}
+ return 0;
+ }
- for (int j = typesFound.size; --j >= 0;) {
- ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+ private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
+ if (receiverType == declaringClass) return R_NON_INHERITED;
+ return 0;
+ }
- if (exceptionType == otherType)
- return;
+ int computeRelevanceForInterestingProposal(){
+ return computeRelevanceForInterestingProposal(null);
+ }
- if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
+ private int computeRelevanceForInterestingProposal(Binding binding){
+ if(this.uninterestingBindings != null) {
+ for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
+ if(this.uninterestingBindings[i] == binding) {
+ return 0;
+ }
+ }
+ }
+ return R_INTERESTING;
+ }
- if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
- return;
+ private int computeRelevanceForInterface(){
+ if(this.assistNodeIsInterface) {
+ return R_INTERFACE;
+ }
+ return 0;
+ }
- if (otherType.enclosingType().isInterface())
- if (exceptionType.enclosingType()
- .implementsInterface(otherType.enclosingType(), true))
- return;
+ private int computeRelevanceForMissingElements(boolean hasProblems) {
+ if (!hasProblems) {
+ return R_NO_PROBLEMS;
+ }
+ return 0;
+ }
+ int computeRelevanceForQualification(boolean prefixRequired) {
+ if(!prefixRequired && !this.insideQualifiedReference) {
+ return R_UNQUALIFIED;
+ }
- if (exceptionType.enclosingType().isInterface())
- if (otherType.enclosingType()
- .implementsInterface(exceptionType.enclosingType(), true))
- return;
- }
+ if(prefixRequired && this.insideQualifiedReference) {
+ return R_QUALIFIED;
}
+ return 0;
+ }
- typesFound.add(exceptionType);
+ int computeRelevanceForResolution(){
+ return computeRelevanceForResolution(true);
+ }
- char[] completionName = exceptionType.sourceName();
+ int computeRelevanceForResolution(boolean isResolved){
+ if (isResolved) {
+ return R_RESOLVED;
+ }
+ return 0;
+ }
- boolean isQualified = false;
+ int computeRelevanceForRestrictions(int accessRuleKind) {
+ if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
+ return R_NON_RESTRICTED;
+ }
+ return 0;
+ }
- if(!this.insideQualifiedReference) {
- isQualified = true;
+ private int computeRelevanceForStatic(boolean onlyStatic, boolean isStatic) {
+ if(this.insideQualifiedReference && !onlyStatic && !isStatic) {
+ return R_NON_STATIC;
+ }
+ return 0;
+ }
- char[] memberPackageName = exceptionType.qualifiedPackageName();
- char[] memberTypeName = exceptionType.sourceName();
- char[] memberEnclosingTypeNames = null;
+ private long computeTargetedElement(CompletionOnAnnotationOfType fakeNode) {
+ ASTNode annotatedElement = fakeNode.potentialAnnotatedNode;
- ReferenceBinding enclosingType = exceptionType.enclosingType();
- if (enclosingType != null) {
- memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
+ if (annotatedElement instanceof TypeDeclaration) {
+ TypeDeclaration annotatedTypeDeclaration = (TypeDeclaration) annotatedElement;
+ if (TypeDeclaration.kind(annotatedTypeDeclaration.modifiers) == TypeDeclaration.ANNOTATION_TYPE_DECL) {
+ return TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType;
+ }
+ return TagBits.AnnotationForType;
+ } else if (annotatedElement instanceof FieldDeclaration) {
+ if (fakeNode.isParameter) {
+ return TagBits.AnnotationForParameter;
}
+ return TagBits.AnnotationForField;
+ } else if (annotatedElement instanceof MethodDeclaration) {
+ return TagBits.AnnotationForMethod;
+ } else if (annotatedElement instanceof Argument) {
+ return TagBits.AnnotationForParameter;
+ } else if (annotatedElement instanceof ConstructorDeclaration) {
+ return TagBits.AnnotationForConstructor;
+ } else if (annotatedElement instanceof LocalDeclaration) {
+ return TagBits.AnnotationForLocalVariable;
+ } else if (annotatedElement instanceof ImportReference) {
+ return TagBits.AnnotationForPackage;
+ }
+ return 0;
+ }
+ private TypeBinding[] computeTypes(Expression[] arguments) {
+ if (arguments == null) return null;
+ int argsLength = arguments.length;
+ TypeBinding[] argTypes = new TypeBinding[argsLength];
+ for (int a = argsLength; --a >= 0;) {
+ argTypes[a] = arguments[a].resolvedType;
+ }
+ return argTypes;
+ }
- Scope currentScope = scope;
- done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+ private TypeBinding[] computeTypesIfCorrect(Expression[] arguments) {
+ if (arguments == null) return null;
+ int argsLength = arguments.length;
+ TypeBinding[] argTypes = new TypeBinding[argsLength];
+ for (int a = argsLength; --a >= 0;) {
+ TypeBinding typeBinding = arguments[a].resolvedType;
+ if(typeBinding == null || !typeBinding.isValidBinding()) return null;
+ argTypes[a] = typeBinding;
+ }
+ return argTypes;
+ }
- switch (currentScope.kind) {
+ private void computeUninterestingBindings(ASTNode parent, Scope scope){
+ if(parent instanceof LocalDeclaration) {
+ addUninterestingBindings(((LocalDeclaration)parent).binding);
+ } else if (parent instanceof FieldDeclaration) {
+ addUninterestingBindings(((FieldDeclaration)parent).binding);
+ }
+ }
- case Scope.METHOD_SCOPE :
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) currentScope;
+ private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
+ char[] result = IMPORT;
+ if (isStatic) {
+ result = CharOperation.concat(result, STATIC, ' ');
+ }
+ result = CharOperation.concat(result, importedElement, ' ');
+ if (onDemand) {
+ result = CharOperation.concat(result, ON_DEMAND);
+ }
+ return CharOperation.concat(result, IMPORT_END);
+ }
- for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
+ private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
+ //// Modifiers
+ // flush uninteresting modifiers
+ int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
+ if(insertedModifiers != ClassFileConstants.AccDefault){
+ ASTNode.printModifiers(insertedModifiers, completion);
+ }
- if (blockScope.subscopes[j] instanceof ClassScope) {
- SourceTypeBinding localType =
- ((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
+ //// Type parameters
- if (localType == exceptionType) {
- isQualified = false;
- break done;
- }
- }
- }
- break;
+ TypeVariableBinding[] typeVariableBindings = method.typeVariables;
+ if(typeVariableBindings != null && typeVariableBindings.length != 0) {
+ completion.append('<');
+ for (int i = 0; i < typeVariableBindings.length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
+ }
+ createTypeVariable(typeVariableBindings[i], scope, completion);
+ }
+ completion.append('>');
+ completion.append(' ');
+ }
- case Scope.CLASS_SCOPE :
- SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
- ReferenceBinding[] memberTypes = type.memberTypes();
- if (memberTypes != null) {
- for (int j = 0; j < memberTypes.length; j++) {
- if (memberTypes[j] == exceptionType) {
- isQualified = false;
- break done;
- }
- }
- }
+ //// Return type
+ createType(method.returnType, scope, completion);
+ completion.append(' ');
+ //// Selector
+ completion.append(method.selector);
- break;
+ completion.append('(');
- case Scope.COMPILATION_UNIT_SCOPE :
- SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
- if (types != null) {
- for (int j = 0; j < types.length; j++) {
- if (types[j] == exceptionType) {
- isQualified = false;
- break done;
- }
- }
- }
- break done;
- }
- currentScope = currentScope.parent;
+ ////Parameters
+ TypeBinding[] parameterTypes = method.parameters;
+ int length = parameterTypes.length;
+ for (int i = 0; i < length; i++) {
+ if(i != 0) {
+ completion.append(',');
+ completion.append(' ');
}
-
- if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
- if (memberPackageName == null || memberPackageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- return; // ignore types from the default package from outside it
+ createType(parameterTypes[i], scope, completion);
+ completion.append(' ');
+ if(parameterNames != null){
+ completion.append(parameterNames[i]);
} else {
- isQualified = false;
- }
-
- if (isQualified) {
- completionName =
- CharOperation.concat(
- memberPackageName,
- CharOperation.concat(
- memberEnclosingTypeNames,
- memberTypeName,
- '.'),
- '.');
+ completion.append('%');
}
}
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
- relevance += computeRelevanceForExpectingType(exceptionType);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if(!this.insideQualifiedReference) {
- relevance += computeRelevanceForQualification(isQualified);
- }
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException();
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(
- exceptionType,
- exceptionType.qualifiedSourceName(),
- IAccessRule.K_ACCESSIBLE,
- completionName,
- relevance,
- null,
- null,
- null,
- false);
- }
- }
-
- private void findExceptionFromTryStatement(
- char[] typeName,
- ReferenceBinding receiverType,
- SourceTypeBinding invocationType,
- BlockScope scope,
- ObjectVector typesFound) {
+ completion.append(')');
- for (int i = 0; i <= this.expectedTypesPtr; i++) {
- ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
+ //// Exceptions
+ ReferenceBinding[] exceptions = method.thrownExceptions;
- findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
+ if (exceptions != null && exceptions.length > 0){
+ completion.append(' ');
+ completion.append(THROWS);
+ completion.append(' ');
+ for(int i = 0; i < exceptions.length ; i++){
+ if(i != 0) {
+ completion.append(' ');
+ completion.append(',');
+ }
+ createType(exceptions[i], scope, completion);
+ }
}
}
- private void findExplicitConstructors(
- char[] name,
- ReferenceBinding currentType,
- MethodScope scope,
- InvocationSite invocationSite) {
-
- ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
- MethodBinding enclosingConstructor = constructorDeclaration.binding;
-
- // No visibility checks can be performed without the scope & invocationSite
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding constructor = methods[f];
- if (constructor != enclosingConstructor && constructor.isConstructor()) {
- if (constructor.isSynthetic()) continue next;
+ protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ return proposal;
+ }
- if (this.options.checkDeprecation &&
- constructor.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(constructor.declaringClass))
- continue next;
+ private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
+ InternalCompletionProposal proposal = null;
+ if (binding instanceof ReferenceBinding) {
+ ReferenceBinding typeBinding = (ReferenceBinding) binding;
- if (this.options.checkVisibility
- && !constructor.canBeSeenBy(invocationSite, scope)) continue next;
+ char[] packageName = typeBinding.qualifiedPackageName();
+ char[] typeName = typeBinding.qualifiedSourceName();
+ char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
- TypeBinding[] parameters = constructor.parameters;
- int paramLength = parameters.length;
+ proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getRequiredTypeSignature(typeBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(fullyQualifiedName);
+ proposal.setFlags(typeBinding.modifiers);
+ proposal.setReplaceRange(start - this.offset, end - this.offset);
+ proposal.setTokenRange(start - this.offset, end - this.offset);
+ proposal.setRelevance(relevance);
+ } else if (binding instanceof PackageBinding) {
+ PackageBinding packageBinding = (PackageBinding) binding;
- char[][] parameterPackageNames = new char[paramLength][];
- char[][] parameterTypeNames = new char[paramLength][];
- for (int i = 0; i < paramLength; i++) {
- TypeBinding type = parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
+ char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
- char[] completion = CharOperation.NO_CHAR;
- if (this.source != null
- && this.source.length > this.endPosition
- && this.source[this.endPosition] == '(')
- completion = name;
- else
- completion = CharOperation.concat(name, new char[] { '(', ')' });
+ proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setPackageName(packageName);
+ proposal.setCompletion(packageName);
+ proposal.setReplaceRange(start - this.offset, end - this.offset);
+ proposal.setTokenRange(start - this.offset, end - this.offset);
+ proposal.setRelevance(relevance);
+ }
+ return proposal;
+ }
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(this.completionToken, name);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
+ switch (type.kind()) {
+ case Binding.BASE_TYPE :
+ completion.append(type.sourceName());
+ break;
+ case Binding.WILDCARD_TYPE :
+ case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
+ WildcardBinding wildcardBinding = (WildcardBinding) type;
+ completion.append('?');
+ switch (wildcardBinding.boundKind) {
+ case Wildcard.EXTENDS:
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ createType(wildcardBinding.bound, scope, completion);
+ if(wildcardBinding.otherBounds != null) {
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setName(name);
- proposal.setIsContructor(true);
- proposal.setCompletion(completion);
- proposal.setFlags(constructor.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ int length = wildcardBinding.otherBounds.length;
+ for (int i = 0; i < length; i++) {
+ completion.append(' ');
+ completion.append('&');
+ completion.append(' ');
+ createType(wildcardBinding.otherBounds[i], scope, completion);
+ }
}
- }
+ break;
+ case Wildcard.SUPER:
+ completion.append(' ');
+ completion.append(SUPER);
+ completion.append(' ');
+ createType(wildcardBinding.bound, scope, completion);
+ break;
+ }
+ break;
+ case Binding.ARRAY_TYPE :
+ createType(type.leafComponentType(), scope, completion);
+ int dim = type.dimensions();
+ for (int i = 0; i < dim; i++) {
+ completion.append('[');
+ completion.append(']');
+ }
+ break;
+ case Binding.PARAMETERIZED_TYPE :
+ ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
+ if (type.isMemberType()) {
+ createType(parameterizedType.enclosingType(), scope, completion);
+ completion.append('.');
+ completion.append(parameterizedType.sourceName);
+ } else {
+ completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
+ }
+ if (parameterizedType.arguments != null) {
+ completion.append('<');
+ for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
+ if (i != 0) completion.append(',');
+ createType(parameterizedType.arguments[i], scope, completion);
+ }
+ completion.append('>');
}
+ break;
+ default :
+ char[] packageName = type.qualifiedPackageName();
+ char[] typeName = type.qualifiedSourceName();
+ if(mustQualifyType(
+ (ReferenceBinding)type,
+ packageName,
+ scope)) {
+ completion.append(CharOperation.concat(packageName, typeName,'.'));
+ } else {
+ completion.append(type.sourceName());
}
+ break;
}
}
- private void findConstructors(
- ReferenceBinding currentType,
- TypeBinding[] argTypes,
- Scope scope,
- InvocationSite invocationSite,
- boolean forAnonymousType) {
- // No visibility checks can be performed without the scope & invocationSite
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- int minArgLength = argTypes == null ? 0 : argTypes.length;
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding constructor = methods[f];
- if (constructor.isConstructor()) {
-
- if (constructor.isSynthetic()) continue next;
-
- if (this.options.checkDeprecation &&
- constructor.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(constructor.declaringClass))
- continue next;
-
- if (this.options.checkVisibility
- && !constructor.canBeSeenBy(invocationSite, scope)) {
- if(!forAnonymousType || !constructor.isProtected())
- continue next;
- }
-
- TypeBinding[] parameters = constructor.parameters;
- int paramLength = parameters.length;
- if (minArgLength > paramLength)
- continue next;
- for (int a = minArgLength; --a >= 0;)
- if (argTypes[a] != null) { // can be null if it could not be resolved properly
- if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
- continue next;
- }
-
- char[][] parameterPackageNames = new char[paramLength][];
- char[][] parameterTypeNames = new char[paramLength][];
- for (int i = 0; i < paramLength; i++) {
- TypeBinding type = parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
-
- char[] completion = CharOperation.NO_CHAR;
- if(forAnonymousType){
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setDeclarationKey(currentType.computeUniqueKey());
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setKey(constructor.computeUniqueKey());
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setCompletion(completion);
- proposal.setFlags(constructor.modifiers);
- proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
-
- // Special case for completion in javadoc
- if (this.assistNodeInJavadoc > 0) {
- Expression receiver = null;
- char[] selector = null;
- if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
- CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
- receiver = alloc.type;
- } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
- CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
- receiver = fieldRef.receiver;
- }
- if (receiver != null) {
- StringBuffer javadocCompletion = new StringBuffer();
- if (receiver.isThis()) {
- selector = (((JavadocImplicitTypeReference)receiver).token);
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
- javadocCompletion.append('#');
- }
- } else if (receiver instanceof JavadocSingleTypeReference) {
- JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
- selector = typeRef.token;
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
- javadocCompletion.append(typeRef.token);
- javadocCompletion.append('#');
- }
- } else if (receiver instanceof JavadocQualifiedTypeReference) {
- JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
- selector = typeRef.tokens[typeRef.tokens.length-1];
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
- javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
- javadocCompletion.append('#');
- }
- }
- // Append parameters types
- javadocCompletion.append(selector);
- javadocCompletion.append('(');
- if (constructor.parameters != null) {
- boolean isVarargs = constructor.isVarargs();
- for (int p=0, ln=constructor.parameters.length; p0) javadocCompletion.append(", "); //$NON-NLS-1$
- TypeBinding argTypeBinding = constructor.parameters[p];
- if (isVarargs && p == ln - 1) {
- createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
- } else {
- createType(argTypeBinding.erasure(), scope, javadocCompletion);
- }
- }
- }
- javadocCompletion.append(')');
- completion = javadocCompletion.toString().toCharArray();
- }
- }
-
- // Create standard proposal
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setName(currentType.sourceName());
- proposal.setIsContructor(true);
- proposal.setCompletion(completion);
- proposal.setFlags(constructor.modifiers);
- int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
- char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(currentType));
- proposal.setSignature(getSignature(constructor));
- MethodBinding original = constructor.original();
- if(original != constructor) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
- proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- //proposal.setPackageName(null);
- //proposal.setTypeName(null);
- proposal.setName(currentType.sourceName());
- proposal.setIsContructor(true);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(constructor.modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- }
- }
- }
- }
-
- private char[][] findEnclosingTypeNames(Scope scope){
- char[][] excludedNames = new char[10][];
- int excludedNameCount = 0;
-
- Scope currentScope = scope;
- while(currentScope != null) {
- switch (currentScope.kind) {
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
-
- TypeDeclaration typeDeclaration = classScope.referenceContext;
-
- if(excludedNameCount == excludedNames.length) {
- System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
- }
- excludedNames[excludedNameCount++] = typeDeclaration.name;
-
- TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
- if(classTypeParameters != null) {
- for (int i = 0; i < classTypeParameters.length; i++) {
- TypeParameter typeParameter = classTypeParameters[i];
- if(excludedNameCount == excludedNames.length) {
- System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
- }
- excludedNames[excludedNameCount++] = typeParameter.name;
- }
- }
- break;
- case Scope.METHOD_SCOPE :
- MethodScope methodScope = (MethodScope) currentScope;
- if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
- TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
- if(methodTypeParameters != null) {
- for (int i = 0; i < methodTypeParameters.length; i++) {
- TypeParameter typeParameter = methodTypeParameters[i];
- if(excludedNameCount == excludedNames.length) {
- System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
- }
- excludedNames[excludedNameCount++] = typeParameter.name;
- }
- }
- }
- break;
- }
-
- currentScope = currentScope.parent;
- }
-
- if(excludedNameCount == 0) {
- return CharOperation.NO_CHAR_CHAR;
- }
- System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
- return excludedNames;
- }
-
- // Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
- private void findFields(
- char[] fieldName,
- FieldBinding[] fields,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector localsFound,
- boolean onlyStaticFields,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean canBePrefixed,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[] castedReceiver,
- int receiverStart,
- int receiverEnd) {
-
- ObjectVector newFieldsFound = new ObjectVector();
- // Inherited fields which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
-
- int fieldLength = fieldName.length;
- next : for (int f = fields.length; --f >= 0;) {
- FieldBinding field = fields[f];
-
- if (field.isSynthetic()) continue next;
-
- if (onlyStaticFields && !field.isStatic()) continue next;
-
- if (fieldLength > field.name.length) continue next;
-
- if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
-
- if (this.options.checkDeprecation &&
- field.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(field.declaringClass))
- continue next;
-
- if (this.options.checkVisibility
- && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-
- boolean prefixRequired = false;
-
- for (int i = fieldsFound.size; --i >= 0;) {
- Object[] other = (Object[])fieldsFound.elementAt(i);
- FieldBinding otherField = (FieldBinding) other[0];
- ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
- if (field == otherField && receiverType == otherReceiverType)
- continue next;
- if (CharOperation.equals(field.name, otherField.name, true)) {
- if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
- continue next;
- if (otherField.declaringClass.isInterface()) {
- if (field.declaringClass == scope.getJavaLangObject())
- continue next;
- if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
- continue next;
- }
- if (field.declaringClass.isInterface())
- if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
- continue next;
- if(canBePrefixed) {
- prefixRequired = true;
- } else {
- continue next;
- }
- }
- }
-
- for (int l = localsFound.size; --l >= 0;) {
- LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
-
- if (CharOperation.equals(field.name, local.name, true)) {
- SourceTypeBinding declarationType = scope.enclosingSourceType();
- if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
- continue next;
- }
- if(canBePrefixed) {
- prefixRequired = true;
- } else {
- continue next;
- }
- break;
- }
- }
-
- newFieldsFound.add(new Object[]{field, receiverType});
-
- char[] completion = field.name;
-
- if(prefixRequired || this.options.forceImplicitQualification){
- char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
- completion = CharOperation.concat(prefix,completion,'.');
- }
-
-
- if (castedReceiver != null) {
- completion = CharOperation.concat(castedReceiver, completion);
- }
-
- // Special case for javadoc completion
- if (this.assistNodeInJavadoc > 0) {
- if (invocationSite instanceof CompletionOnJavadocFieldReference) {
- CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
- if (fieldRef.receiver.isThis()) {
- if (fieldRef.completeInText()) {
- completion = CharOperation.concat(new char[] { '#' }, field.name);
- }
- } else if (fieldRef.completeInText()) {
- if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
- JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
- completion = CharOperation.concat(typeRef.token, field.name, '#');
- } else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
- JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
- completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
- }
- }
- }
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal(field);
- if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
- relevance += computeRelevanceForExpectingType(field.type);
- relevance += computeRelevanceForEnumConstant(field.type);
- relevance += computeRelevanceForStatic(onlyStaticFields, field.isStatic());
- relevance += computeRelevanceForQualification(prefixRequired);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if (onlyStaticFields && this.insideQualifiedReference) {
- relevance += computeRelevanceForInheritance(receiverType, field.declaringClass);
- }
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
- }
-
- this.noProposal = false;
- if (castedReceiver == null) {
- // Standard proposal
- if (!this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
-
- // Javadoc completions
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
- char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(field.modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- // Javadoc value completion for static fields
- if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
- javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
- InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
- valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
- valueProposal.setSignature(getSignature(field.type));
- valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- valueProposal.setPackageName(field.type.qualifiedPackageName());
- valueProposal.setTypeName(field.type.qualifiedSourceName());
- valueProposal.setName(field.name);
- valueProposal.setCompletion(javadocCompletion);
- valueProposal.setFlags(field.modifiers);
- valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- valueProposal.setRelevance(relevance+R_VALUE_TAG);
- this.requestor.accept(valueProposal);
- if(DEBUG) {
- this.printDebug(valueProposal);
- }
- }
- }
- } else {
- if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setReceiverSignature(getSignature(receiverType));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- }
-
- fieldsFound.addAll(newFieldsFound);
- }
-
- private void findFields(
- char[] fieldName,
- ReferenceBinding receiverType,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector localsFound,
- boolean onlyStaticFields,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean canBePrefixed,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[] castedReceiver,
- int receiverStart,
- int receiverEnd) {
-
- boolean notInJavadoc = this.assistNodeInJavadoc == 0;
- if (fieldName == null && notInJavadoc)
- return;
-
- ReferenceBinding currentType = receiverType;
- ReferenceBinding[] interfacesToVisit = null;
- int nextPosition = 0;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
- if (interfacesToVisit == null) {
- interfacesToVisit = itsInterfaces;
- nextPosition = interfacesToVisit.length;
- } else {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
- }
- }
-
- FieldBinding[] fields = currentType.availableFields();
- if(fields != null && fields.length > 0) {
- findFields(
- fieldName,
- fields,
- scope,
- fieldsFound,
- localsFound,
- onlyStaticFields,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- }
- currentType = currentType.superclass();
- } while (notInJavadoc && currentType != null);
-
- if (notInJavadoc && interfacesToVisit != null) {
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding anInterface = interfacesToVisit[i];
- FieldBinding[] fields = anInterface.availableFields();
- if(fields != null) {
- findFields(
- fieldName,
- fields,
- scope,
- fieldsFound,
- localsFound,
- onlyStaticFields,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- }
+ /*
+ * Create a completion proposal for a member type.
+ */
+ private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
+ char[] completionName = typeParameter.name;
- ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
- }
+ // Create standard type proposal
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setSignature(getSignature(typeParameter.binding));
+ proposal.setTypeName(completionName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(typeParameter.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
}
- }
-
- protected void findFieldsAndMethodsFromAnotherReceiver(
- char[] token,
- TypeReference receiverType,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector methodsFound,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean superCall,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[][] receiverName,
- int receiverStart,
- int receiverEnd) {
-
- if (receiverType.resolvedType == null) return;
-
- TypeBinding receiverTypeBinding = receiverType.resolvedType;
- char[] castedReceiver = null;
-
- char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
- if(this.source != null) {
- int memberRefStart = this.startPosition;
- char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
- char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
-
- castedReceiver =
- CharOperation.concat(
- CharOperation.concat(
- '(',
- CharOperation.concat(
- CharOperation.concat('(', castedTypeChars, ')'),
- receiverChars),
- ')'),
- dotChars);
- } else {
- castedReceiver =
- CharOperation.concat(
- CharOperation.concat(
- '(',
- CharOperation.concat(
- CharOperation.concat('(', castedTypeChars, ')'),
- CharOperation.concatWith(receiverName, '.')),
- ')'),
- DOT);
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+ char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setSignature(getSignature(typeParameter.binding));
+ proposal.setTypeName(javadocCompletion);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(typeParameter.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
-
- if (castedReceiver == null) return;
-
- int oldStartPosition = this.startPosition;
- this.startPosition = receiverStart;
-
- findFieldsAndMethods(
- token,
- receiverTypeBinding,
- scope,
- fieldsFound,
- methodsFound,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
-
- this.startPosition = oldStartPosition;
}
- protected void findFieldsAndMethods(
- char[] token,
- TypeBinding receiverType,
- Scope scope,
- ObjectVector fieldsFound,
- ObjectVector methodsFound,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean superCall,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[] castedReceiver,
- int receiverStart,
- int receiverEnd) {
-
- if (token == null)
- return;
-
- if (receiverType.isBaseType())
- return; // nothing else is possible with base types
-
- boolean proposeField =
- castedReceiver == null ?
- !this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
- !this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
- boolean proposeMethod =
- castedReceiver == null ?
- !this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
- !this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
- if (receiverType.isArrayType()) {
- if (proposeField
- && token.length <= lengthField.length
- && CharOperation.prefixEquals(token, lengthField, false /* ignore case */
- )) {
+ /*
+ * Create a completion proposal for a type.
+ */
+ private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance, boolean isNotOptimum) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token,lengthField);
- relevance += computeRelevanceForExpectingType(TypeBinding.INT);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
- }
- this.noProposal = false;
- if (castedReceiver == null) {
- if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(receiverType));
- proposal.setSignature(INT_SIGNATURE);
- proposal.setTypeName(INT);
- proposal.setName(lengthField);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(lengthField);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- char[] completion = CharOperation.concat(castedReceiver, lengthField);
+ // Create standard type proposal
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(modifiers);
+ if (isNotOptimum) proposal.setAdditionalFlags(CompletionFlags.NotOptimum);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
- if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(receiverType));
- proposal.setSignature(INT_SIGNATURE);
- proposal.setReceiverSignature(getSignature(receiverType));
- proposal.setTypeName(INT);
- proposal.setName(lengthField);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+ char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(modifiers);
+ if (isNotOptimum) proposal.setAdditionalFlags(CompletionFlags.NotOptimum);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
- if (proposeMethod
- && token.length <= cloneMethod.length
- && CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
- ) {
- ReferenceBinding objectRef = scope.getJavaLangObject();
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, cloneMethod);
- relevance += computeRelevanceForExpectingType(objectRef);
- relevance += computeRelevanceForStatic(false, false);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
- }
- char[] completion;
- if (this.source != null
- && this.source.length > this.endPosition
- && this.source[this.endPosition] == '(') {
- completion = cloneMethod;
- } else {
- completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
- }
+ }
+ }
- if (castedReceiver != null) {
- completion = CharOperation.concat(castedReceiver, completion);
- }
+ /*
+ * Create a completion proposal for a member type.
+ */
+ private void createTypeProposal(
+ ReferenceBinding refBinding,
+ char[] typeName,
+ int accessibility,
+ char[] completionName,
+ int relevance,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
- this.noProposal = false;
- if (castedReceiver == null) {
- if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(receiverType));
- proposal.setSignature(
- this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- getSignature(receiverType)) :
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- CharOperation.concatWith(JAVA_LANG, '.'),
- OBJECT));
- //proposal.setOriginalSignature(null);
- //proposal.setDeclarationPackageName(null);
- //proposal.setDeclarationTypeName(null);
- //proposal.setParameterPackageNames(null);
- //proposal.setParameterTypeNames(null);
- proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
- proposal.setTypeName(OBJECT);
- proposal.setName(cloneMethod);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
- } else {
- if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(receiverType));
- proposal.setSignature(
- this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- getSignature(receiverType)) :
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- CharOperation.concatWith(JAVA_LANG, '.'),
- OBJECT));
- proposal.setReceiverSignature(getSignature(receiverType));
- proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
- proposal.setTypeName(OBJECT);
- proposal.setName(cloneMethod);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
+ // Create standard type proposal
+ if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
+ proposal.setSignature(getCompletedTypeSignature(refBinding));
+ proposal.setPackageName(refBinding.qualifiedPackageName());
+ proposal.setTypeName(typeName);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
}
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completionName);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
-
- receiverType = scope.getJavaLangObject();
}
- if(proposeField) {
- findFields(
- token,
- (ReferenceBinding) receiverType,
- scope,
- fieldsFound,
- new ObjectVector(),
- false,
- invocationSite,
- invocationScope,
- implicitCall,
- false,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
+ // Create javadoc text proposal if necessary
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
+ char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
+ proposal.nameLookup = this.nameEnvironment.nameLookup;
+ proposal.completionEngine = this;
+ proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
+ proposal.setSignature(getCompletedTypeSignature(refBinding));
+ proposal.setPackageName(refBinding.qualifiedPackageName());
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(refBinding.modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
+ }
+ private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
+ completion.append(typeVariable.sourceName);
- if(proposeMethod) {
- findMethods(
- token,
- null,
- null,
- (ReferenceBinding) receiverType,
- scope,
- methodsFound,
- false,
- false,
- false,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- false,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
+ if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ createType(typeVariable.superclass, scope, completion);
+ }
+ if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
+ if (typeVariable.firstBound != typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ }
+ for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
+ if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
+ completion.append(' ');
+ completion.append(EXTENDS);
+ completion.append(' ');
+ }
+ createType(typeVariable.superInterfaces[i], scope, completion);
+ }
+ }
+ }
+ private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
+ if (type.isArrayType()) {
+ createType(type.leafComponentType(), scope, completion);
+ int dim = type.dimensions() - 1;
+ for (int i = 0; i < dim; i++) {
+ completion.append('[');
+ completion.append(']');
+ }
+ completion.append(VARARGS);
+ } else {
+ createType(type, scope, completion);
}
}
+ private void findAnnotationAttributes(char[] token, MemberValuePair[] attributesFound, ReferenceBinding annotation) {
+ MethodBinding[] methods = annotation.availableMethods();
+ nextAttribute: for (int i = 0; i < methods.length; i++) {
+ MethodBinding method = methods[i];
- private void findFieldsAndMethodsFromFavorites(
- char[] token,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope,
- ObjectVector localsFound,
- ObjectVector fieldsFound,
- ObjectVector methodsFound) {
-
- ObjectVector methodsFoundFromFavorites = new ObjectVector();
+ if(!CharOperation.prefixEquals(token, method.selector, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, method.selector))) continue nextAttribute;
- ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
+ int length = attributesFound == null ? 0 : attributesFound.length;
+ for (int j = 0; j < length; j++) {
+ if(CharOperation.equals(method.selector, attributesFound[j].name, false)) continue nextAttribute;
+ }
- if (favoriteBindings != null && favoriteBindings.length > 0) {
- for (int i = 0; i < favoriteBindings.length; i++) {
- ImportBinding favoriteBinding = favoriteBindings[i];
- switch (favoriteBinding.resolvedImport.kind()) {
- case Binding.FIELD:
- FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
- findFieldsFromFavorites(
- token,
- new FieldBinding[]{fieldBinding},
- scope,
- fieldsFound,
- localsFound,
- fieldBinding.declaringClass,
- invocationSite,
- invocationScope);
- break;
- case Binding.METHOD:
- MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
- MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
- long range;
- if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
- int start = (int) range, end = (int) (range >> 32);
- int length = end - start + 1;
- System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
- } else {
- methods = Binding.NO_METHODS;
- }
- findLocalMethodsFromFavorites(
- token,
- methods,
- scope,
- methodsFound,
- methodsFoundFromFavorites,
- methodBinding.declaringClass,
- invocationSite,
- invocationScope);
- break;
- case Binding.TYPE:
- ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
- if(favoriteBinding.onDemand) {
- findFieldsFromFavorites(
- token,
- referenceBinding.availableFields(),
- scope,
- fieldsFound,
- localsFound,
- referenceBinding,
- invocationSite,
- invocationScope);
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal(method);
+ relevance += computeRelevanceForCaseMatching(token, method.selector);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- findLocalMethodsFromFavorites(
- token,
- referenceBinding.availableMethods(),
- scope,
- methodsFound,
- methodsFoundFromFavorites,
- referenceBinding,
- invocationSite,
- invocationScope);
- }
- break;
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.ANNOTATION_ATTRIBUTE_REF)) {
+ CompletionProposal proposal = createProposal(CompletionProposal.ANNOTATION_ATTRIBUTE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method.returnType));
+ proposal.setName(method.selector);
+ proposal.setCompletion(method.selector);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
}
}
-
- methodsFound.addAll(methodsFoundFromFavorites);
}
-
- private boolean findFieldsAndMethodsFromMissingFieldType(
- char[] token,
+ private void findAnonymousType(
+ ReferenceBinding currentType,
+ TypeBinding[] argTypes,
Scope scope,
- InvocationSite invocationSite,
- boolean insideTypeAnnotation) {
-
- boolean foundSomeFields = false;
+ InvocationSite invocationSite) {
- boolean staticsOnly = false;
- Scope currentScope = scope;
+ if (currentType.isInterface()) {
+ char[] completion = CharOperation.NO_CHAR;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR,
+ CharOperation.NO_CHAR));
+ //proposal.setOriginalSignature(null);
+ //proposal.setUniqueKey(null);
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ //proposal.setParameterPackageNames(null);
+ //proposal.setParameterTypeNames(null);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ findConstructors(
+ currentType,
+ argTypes,
+ scope,
+ invocationSite,
+ true);
+ }
+ }
+ private void findClassField(
+ char[] token,
+ TypeBinding receiverType,
+ Scope scope,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
- switch (currentScope.kind) {
+ if (token == null) return;
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- break;
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- if(!insideTypeAnnotation) {
+ if (token.length <= classField.length
+ && CharOperation.prefixEquals(token, classField, false /* ignore case */
+ )) {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, classField);
+ relevance += computeRelevanceForExpectingType(scope.getJavaLangClass());
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); //no access restriction for class field
+ relevance += R_NON_INHERITED;
- FieldDeclaration[] fields = classScope.referenceContext.fields;
+ if (missingElements != null) {
+ relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+ }
- int fieldsCount = fields == null ? 0 : fields.length;
- for (int i = 0; i < fieldsCount; i++) {
- FieldDeclaration fieldDeclaration = fields[i];
- if (CharOperation.equals(fieldDeclaration.name, token)) {
- FieldBinding fieldBinding = fieldDeclaration.binding;
- if (fieldBinding == null || fieldBinding.type == null || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
- foundSomeFields = true;
- findFieldsAndMethodsFromMissingType(
- fieldDeclaration.type,
- currentScope,
- invocationSite,
- scope);
- }
- break done;
- }
- }
+ this.noProposal = false;
+ if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ //proposal.setDeclarationSignature(null);
+ char[] signature =
+ createNonGenericTypeSignature(
+ CharOperation.concatWith(JAVA_LANG, '.'),
+ CLASS);
+ if (this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4) {
+ // add type argument
+ char[] typeArgument = getTypeSignature(receiverType);
+ int oldLength = signature.length;
+ int argumentLength = typeArgument.length;
+ int newLength = oldLength + argumentLength + 2;
+ System.arraycopy(signature, 0, signature = new char[newLength], 0, oldLength - 1);
+ signature[oldLength - 1] = '<';
+ System.arraycopy(typeArgument, 0, signature, oldLength , argumentLength);
+ signature[newLength - 2] = '>';
+ signature[newLength - 1] = ';';
+ }
+ proposal.setSignature(signature);
+ //proposal.setDeclarationPackageName(null);
+ //proposal.setDeclarationTypeName(null);
+ proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+ proposal.setTypeName(CLASS);
+ proposal.setName(classField);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
}
- staticsOnly |= enclosingType.isStatic();
- insideTypeAnnotation = false;
- break;
- case Scope.COMPILATION_UNIT_SCOPE :
- break done;
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(classField);
+ proposal.setFlags(Flags.AccStatic | Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- currentScope = currentScope.parent;
}
- return foundSomeFields;
}
-
- private void findFieldsAndMethodsFromMissingReturnType(
- char[] token,
- TypeBinding[] arguments,
+ private void findConstructors(
+ ReferenceBinding currentType,
+ TypeBinding[] argTypes,
Scope scope,
InvocationSite invocationSite,
- boolean insideTypeAnnotation) {
+ boolean forAnonymousType) {
- boolean staticsOnly = false;
- Scope currentScope = scope;
+ // No visibility checks can be performed without the scope & invocationSite
+ MethodBinding[] methods = currentType.availableMethods();
+ if(methods != null) {
+ int minArgLength = argTypes == null ? 0 : argTypes.length;
+ next : for (int f = methods.length; --f >= 0;) {
+ MethodBinding constructor = methods[f];
+ if (constructor.isConstructor()) {
- done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+ if (constructor.isSynthetic()) continue next;
- switch (currentScope.kind) {
+ if (this.options.checkDeprecation &&
+ constructor.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(constructor.declaringClass))
+ continue next;
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- break;
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- if(!insideTypeAnnotation) {
+ if (this.options.checkVisibility
+ && !constructor.canBeSeenBy(invocationSite, scope)) {
+ if(!forAnonymousType || !constructor.isProtected())
+ continue next;
+ }
- AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
+ TypeBinding[] parameters = constructor.parameters;
+ int paramLength = parameters.length;
+ if (minArgLength > paramLength)
+ continue next;
+ for (int a = minArgLength; --a >= 0;)
+ if (argTypes[a] != null) { // can be null if it could not be resolved properly
+ if (!argTypes[a].isCompatibleWith(constructor.parameters[a]))
+ continue next;
+ }
- int methodsCount = methods == null ? 0 : methods.length;
- for (int i = 0; i < methodsCount; i++) {
- AbstractMethodDeclaration methodDeclaration = methods[i];
- if (methodDeclaration instanceof MethodDeclaration &&
- CharOperation.equals(methodDeclaration.selector, token)) {
- MethodDeclaration method = (MethodDeclaration) methodDeclaration;
- MethodBinding methodBinding = method.binding;
- if (methodBinding == null || methodBinding.returnType == null || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
- Argument[] parameters = method.arguments;
- int parametersLength = parameters == null ? 0 : parameters.length;
- int argumentsLength = arguments == null ? 0 : arguments.length;
+ char[][] parameterPackageNames = new char[paramLength][];
+ char[][] parameterTypeNames = new char[paramLength][];
+ for (int i = 0; i < paramLength; i++) {
+ TypeBinding type = parameters[i];
+ parameterPackageNames[i] = type.qualifiedPackageName();
+ parameterTypeNames[i] = type.qualifiedSourceName();
+ }
+ char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
- if (parametersLength == 0) {
- if (argumentsLength == 0) {
- findFieldsAndMethodsFromMissingType(
- method.returnType,
- currentScope,
- invocationSite,
- scope);
- break done;
- }
- } else {
- TypeBinding[] parametersBindings;
- if (methodBinding == null) { // since no binding, extra types from type references
- parametersBindings = new TypeBinding[parametersLength];
- for (int j = 0; j < parametersLength; j++) {
- TypeBinding parameterType = parameters[j].type.resolvedType;
- if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
- parameterType = parameterType.closestMatch();
- }
- parametersBindings[j] = parameterType;
- }
+ char[] completion = CharOperation.NO_CHAR;
+ if(forAnonymousType){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setDeclarationKey(currentType.computeUniqueKey());
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setKey(constructor.computeUniqueKey());
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ proposal.setReplaceRange(this.endPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenEnd - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ // Special case for completion in javadoc
+ if (this.assistNodeInJavadoc > 0) {
+ Expression receiver = null;
+ char[] selector = null;
+ if (invocationSite instanceof CompletionOnJavadocAllocationExpression) {
+ CompletionOnJavadocAllocationExpression alloc = (CompletionOnJavadocAllocationExpression) invocationSite;
+ receiver = alloc.type;
+ } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+ CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+ receiver = fieldRef.receiver;
+ }
+ if (receiver != null) {
+ StringBuffer javadocCompletion = new StringBuffer();
+ if (receiver.isThis()) {
+ selector = (((JavadocImplicitTypeReference)receiver).token);
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+ javadocCompletion.append('#');
+ }
+ } else if (receiver instanceof JavadocSingleTypeReference) {
+ JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
+ selector = typeRef.token;
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+ javadocCompletion.append(typeRef.token);
+ javadocCompletion.append('#');
+ }
+ } else if (receiver instanceof JavadocQualifiedTypeReference) {
+ JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
+ selector = typeRef.tokens[typeRef.tokens.length-1];
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+ javadocCompletion.append(CharOperation.concatWith(typeRef.tokens, '.'));
+ javadocCompletion.append('#');
+ }
+ }
+ // Append parameters types
+ javadocCompletion.append(selector);
+ javadocCompletion.append('(');
+ if (constructor.parameters != null) {
+ boolean isVarargs = constructor.isVarargs();
+ for (int p=0, ln=constructor.parameters.length; p0) javadocCompletion.append(", "); //$NON-NLS-1$
+ TypeBinding argTypeBinding = constructor.parameters[p];
+ if (isVarargs && p == ln - 1) {
+ createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
} else {
- parametersBindings = methodBinding.parameters;
- }
- if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
- findFieldsAndMethodsFromMissingType(
- method.returnType,
- currentScope,
- invocationSite,
- scope);
- break done;
+ createType(argTypeBinding.erasure(), scope, javadocCompletion);
}
}
}
+ javadocCompletion.append(')');
+ completion = javadocCompletion.toString().toCharArray();
+ }
+ }
+
+ // Create standard proposal
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ int start = (this.assistNodeInJavadoc > 0) ? this.startPosition : this.endPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+ char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(currentType.sourceName());
+ proposal.setIsContructor(true);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(constructor.modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ private char[][] findEnclosingTypeNames(Scope scope){
+ char[][] excludedNames = new char[10][];
+ int excludedNameCount = 0;
+
+ Scope currentScope = scope;
+ while(currentScope != null) {
+ switch (currentScope.kind) {
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) currentScope;
+
+ TypeDeclaration typeDeclaration = classScope.referenceContext;
+
+ if(excludedNameCount == excludedNames.length) {
+ System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+ }
+ excludedNames[excludedNameCount++] = typeDeclaration.name;
+ TypeParameter[] classTypeParameters = typeDeclaration.typeParameters;
+ if(classTypeParameters != null) {
+ for (int i = 0; i < classTypeParameters.length; i++) {
+ TypeParameter typeParameter = classTypeParameters[i];
+ if(excludedNameCount == excludedNames.length) {
+ System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+ }
+ excludedNames[excludedNameCount++] = typeParameter.name;
+ }
+ }
+ break;
+ case Scope.METHOD_SCOPE :
+ MethodScope methodScope = (MethodScope) currentScope;
+ if(methodScope.referenceContext instanceof AbstractMethodDeclaration) {
+ TypeParameter[] methodTypeParameters = ((AbstractMethodDeclaration)methodScope.referenceContext).typeParameters();
+ if(methodTypeParameters != null) {
+ for (int i = 0; i < methodTypeParameters.length; i++) {
+ TypeParameter typeParameter = methodTypeParameters[i];
+ if(excludedNameCount == excludedNames.length) {
+ System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount * 2][], 0, excludedNameCount);
+ }
+ excludedNames[excludedNameCount++] = typeParameter.name;
}
}
}
- staticsOnly |= enclosingType.isStatic();
- insideTypeAnnotation = false;
break;
- case Scope.COMPILATION_UNIT_SCOPE :
- break done;
}
+
currentScope = currentScope.parent;
}
- }
-
- private void findFieldsAndMethodsFromMissingType(
- TypeReference typeRef,
- final Scope scope,
- final InvocationSite invocationSite,
- final Scope invocationScope) {
- MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
- MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
- new MissingTypesGuesser.GuessedTypeRequestor() {
- public void accept(
- TypeBinding guessedType,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean hasProblems) {
- findFieldsAndMethods(
- CompletionEngine.this.completionToken,
- guessedType,
- scope,
- new ObjectVector(),
- new ObjectVector(),
- invocationSite,
- invocationScope,
- false,
- false,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- hasProblems,
- null,
- -1,
- -1);
- }
- };
- missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+ if(excludedNameCount == 0) {
+ return CharOperation.NO_CHAR_CHAR;
+ }
+ System.arraycopy(excludedNames, 0, excludedNames = new char[excludedNameCount][], 0, excludedNameCount);
+ return excludedNames;
}
-
- private void findFieldsFromFavorites(
- char[] fieldName,
- FieldBinding[] fields,
- Scope scope,
+ private void findEnumConstants(
+ char[] enumConstantName,
+ ReferenceBinding enumType,
+ Scope invocationScope,
ObjectVector fieldsFound,
- ObjectVector localsFound,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- Scope invocationScope) {
+ char[][] alreadyUsedConstants,
+ int alreadyUsedConstantCount,
+ boolean needQualification) {
- char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
+ FieldBinding[] fields = enumType.fields();
- int fieldLength = fieldName.length;
+ int enumConstantLength = enumConstantName.length;
next : for (int f = fields.length; --f >= 0;) {
FieldBinding field = fields[f];
- if (field.isSynthetic()) continue next;
+ if (field.isSynthetic()) continue next;
- // only static fields must be proposed
- if (!field.isStatic()) continue next;
+ if ((field.modifiers & Flags.AccEnum) == 0) continue next;
- if (fieldLength > field.name.length) continue next;
+ if (enumConstantLength > field.name.length) continue next;
- if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
+ if (!CharOperation.prefixEquals(enumConstantName, field.name, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(enumConstantName, field.name))) continue next;
+
+ char[] fieldName = field.name;
+
+ for (int i = 0; i < alreadyUsedConstantCount; i++) {
+ if(CharOperation.equals(alreadyUsedConstants[i], fieldName)) continue next;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal(field);
+ relevance += computeRelevanceForCaseMatching(enumConstantName, field.name);
+ relevance += computeRelevanceForExpectingType(field.type);
+ relevance += computeRelevanceForEnumConstant(field.type);
+ relevance += computeRelevanceForQualification(needQualification);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ this.noProposal = false;
+ if (!needQualification) {
+ char[] completion = fieldName;
+
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+
+ } else {
+ TypeBinding visibleType = invocationScope.getType(field.type.sourceName());
+ boolean needImport = visibleType == null || !visibleType.isValidBinding();
+
+ char[] completion = CharOperation.concat(field.type.sourceName(), field.name, '.');
+
+ if (!needImport) {
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
+ CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+ int importStart = cu.types[0].declarationSourceStart;
+ int importEnd = importStart;
+
+ ReferenceBinding fieldType = (ReferenceBinding)field.type;
+
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+
+ char[] typeImportCompletion = createImportCharArray(CharOperation.concatWith(fieldType.compoundName, '.'), false, false);
+
+ InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+ typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeImportProposal.completionEngine = this;
+ char[] packageName = fieldType.qualifiedPackageName();
+ typeImportProposal.setDeclarationSignature(packageName);
+ typeImportProposal.setSignature(getSignature(fieldType));
+ typeImportProposal.setPackageName(packageName);
+ typeImportProposal.setTypeName(fieldType.qualifiedSourceName());
+ typeImportProposal.setCompletion(typeImportCompletion);
+ typeImportProposal.setFlags(fieldType.modifiers);
+ typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+ typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setRelevance(relevance);
+
+ proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
+ }
+ }
+ private void findEnumConstantsFromExpectedTypes(
+ char[] token,
+ Scope invocationScope,
+ ObjectVector fieldsFound) {
+ int length = this.expectedTypesPtr + 1;
+ for (int i = 0; i < length; i++) {
+ if (this.expectedTypes[i].isEnum()) {
+ findEnumConstants(
+ token,
+ (ReferenceBinding)this.expectedTypes[i],
+ invocationScope,
+ fieldsFound,
+ CharOperation.NO_CHAR_CHAR,
+ 0,
+ true);
+ }
+ }
+
+ }
+ private void findEnumConstantsFromSwithStatement(char[] enumConstantName, SwitchStatement switchStatement) {
+ TypeBinding expressionType = switchStatement.expression.resolvedType;
+ if(expressionType != null && expressionType.isEnum()) {
+ ReferenceBinding enumType = (ReferenceBinding) expressionType;
- if (this.options.checkDeprecation &&
- field.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(field.declaringClass))
- continue next;
+ CaseStatement[] cases = switchStatement.cases;
- if (this.options.checkVisibility
- && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+ char[][] alreadyUsedConstants = new char[switchStatement.caseCount][];
+ int alreadyUsedConstantCount = 0;
+ for (int i = 0; i < switchStatement.caseCount; i++) {
+ Expression caseExpression = cases[i].constantExpression;
+ if((caseExpression instanceof SingleNameReference)
+ && (caseExpression.resolvedType != null && caseExpression.resolvedType.isEnum())) {
+ alreadyUsedConstants[alreadyUsedConstantCount++] = ((SingleNameReference)cases[i].constantExpression).token;
+ }
+ }
- for (int i = fieldsFound.size; --i >= 0;) {
- Object[] other = (Object[])fieldsFound.elementAt(i);
- FieldBinding otherField = (FieldBinding) other[0];
+ findEnumConstants(
+ enumConstantName,
+ enumType,
+ null /* doesn't need invocation scope */,
+ new ObjectVector(),
+ alreadyUsedConstants,
+ alreadyUsedConstantCount,
+ false);
+ }
+ }
+ private void findExceptionFromTryStatement(
+ char[] typeName,
+ ReferenceBinding exceptionType,
+ ReferenceBinding receiverType,
+ SourceTypeBinding invocationType,
+ BlockScope scope,
+ ObjectVector typesFound,
+ boolean searchSuperClasses) {
- if (field == otherField) continue next;
+ if (searchSuperClasses) {
+ ReferenceBinding javaLangThrowable = scope.getJavaLangThrowable();
+ if (exceptionType != javaLangThrowable) {
+ ReferenceBinding superClass = exceptionType.superclass();
+ while(superClass != null && superClass != javaLangThrowable) {
+ findExceptionFromTryStatement(typeName, superClass, receiverType, invocationType, scope, typesFound, false);
+ superClass = superClass.superclass();
+ }
}
+ }
- fieldsFound.add(new Object[]{field, receiverType});
+ if (typeName.length > exceptionType.sourceName.length)
+ return;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal(field);
- if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
- relevance += computeRelevanceForExpectingType(field.type);
- relevance += computeRelevanceForEnumConstant(field.type);
- relevance += computeRelevanceForStatic(true, true);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ if (!CharOperation.prefixEquals(typeName, exceptionType.sourceName, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, exceptionType.sourceName)))
+ return;
- CompilationUnitDeclaration cu = this.unitScope.referenceContext;
- int importStart = cu.types[0].declarationSourceStart;
- int importEnd = importStart;
+ if (this.options.checkDeprecation &&
+ exceptionType.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(exceptionType))
+ return;
- this.noProposal = false;
+ if (this.options.checkVisibility) {
+ if (invocationType != null) {
+ if (receiverType != null) {
+ if (!exceptionType.canBeSeenBy(receiverType, invocationType)) return;
+ } else {
+ if (!exceptionType.canBeSeenBy(exceptionType, invocationType)) return;
+ }
+ } else if(!exceptionType.canBeSeenBy(this.unitScope.fPackage)) {
+ return;
+ }
+ }
- if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
- !this.options.suggestStaticImport) {
- if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
- char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
+ for (int j = typesFound.size; --j >= 0;) {
+ ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
+ if (exceptionType == otherType)
+ return;
- char[] typeImportCompletion = createImportCharArray(typeName, false, false);
+ if (CharOperation.equals(exceptionType.sourceName, otherType.sourceName, true)) {
- InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
- typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
- typeImportProposal.completionEngine = this;
- char[] packageName = receiverType.qualifiedPackageName();
- typeImportProposal.setDeclarationSignature(packageName);
- typeImportProposal.setSignature(getSignature(receiverType));
- typeImportProposal.setPackageName(packageName);
- typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
- typeImportProposal.setCompletion(typeImportCompletion);
- typeImportProposal.setFlags(receiverType.modifiers);
- typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
- typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setRelevance(relevance);
+ if (exceptionType.enclosingType().isSuperclassOf(otherType.enclosingType()))
+ return;
- proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+ if (otherType.enclosingType().isInterface())
+ if (exceptionType.enclosingType()
+ .implementsInterface(otherType.enclosingType(), true))
+ return;
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
- char[] completion = field.name;
+ if (exceptionType.enclosingType().isInterface())
+ if (otherType.enclosingType()
+ .implementsInterface(exceptionType.enclosingType(), true))
+ return;
+ }
+ }
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completion);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
+ typesFound.add(exceptionType);
- char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
+ char[] completionName = exceptionType.sourceName();
- InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
- fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
- fieldImportProposal.setSignature(getSignature(field.type));
- fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
- fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
- fieldImportProposal.setName(field.name);
- fieldImportProposal.setCompletion(fieldImportCompletion);
- fieldImportProposal.setFlags(field.modifiers);
- fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
- fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
- fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
- fieldImportProposal.setRelevance(relevance);
+ boolean isQualified = false;
- proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
+ if(!this.insideQualifiedReference) {
+ isQualified = true;
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- }
- }
+ char[] memberPackageName = exceptionType.qualifiedPackageName();
+ char[] memberTypeName = exceptionType.sourceName();
+ char[] memberEnclosingTypeNames = null;
- private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
- char[][] tokens = importReference.tokens;
+ ReferenceBinding enclosingType = exceptionType.enclosingType();
+ if (enclosingType != null) {
+ memberEnclosingTypeNames = exceptionType.enclosingType().qualifiedSourceName();
+ }
- char[] importName = CharOperation.concatWith(tokens, '.');
+ Scope currentScope = scope;
+ done : while (currentScope != null) { // done when a COMPILATION_UNIT_SCOPE is found
- if (importName.length == 0)
- return;
+ switch (currentScope.kind) {
- char[] lastToken = tokens[tokens.length - 1];
- if(lastToken != null && lastToken.length == 0)
- importName = CharOperation.concat(importName, new char[]{'.'});
+ case Scope.METHOD_SCOPE :
+ case Scope.BLOCK_SCOPE :
+ BlockScope blockScope = (BlockScope) currentScope;
- this.resolvingImports = true;
- this.resolvingStaticImports = importReference.isStatic();
+ for (int j = 0, length = blockScope.subscopeCount; j < length; j++) {
- this.completionToken = lastToken;
- this.qualifiedCompletionToken = importName;
+ if (blockScope.subscopes[j] instanceof ClassScope) {
+ SourceTypeBinding localType =
+ ((ClassScope) blockScope.subscopes[j]).referenceContext.binding;
- // want to replace the existing .*;
- if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
- int oldStart = this.startPosition;
- int oldEnd = this.endPosition;
- setSourceRange(
- importReference.sourceStart,
- importReference.declarationSourceEnd);
- this.nameEnvironment.findPackages(importName, this);
- setSourceRange(
- oldStart,
- oldEnd - 1,
- false);
- }
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- this.nameEnvironment.findTypes(
- importName,
- findMembers,
- this.options.camelCaseMatch,
- IJavaSearchConstants.TYPE,
- this);
- acceptTypes(null);
- }
- }
+ if (localType == exceptionType) {
+ isQualified = false;
+ break done;
+ }
+ }
+ }
+ break;
- private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) {
- ReferenceBinding[] memberTypes = ref.memberTypes();
+ case Scope.CLASS_SCOPE :
+ SourceTypeBinding type = ((ClassScope)currentScope).referenceContext.binding;
+ ReferenceBinding[] memberTypes = type.memberTypes();
+ if (memberTypes != null) {
+ for (int j = 0; j < memberTypes.length; j++) {
+ if (memberTypes[j] == exceptionType) {
+ isQualified = false;
+ break done;
+ }
+ }
+ }
- int typeLength = typeName.length;
- next : for (int m = memberTypes.length; --m >= 0;) {
- ReferenceBinding memberType = memberTypes[m];
- // if (!wantClasses && memberType.isClass()) continue next;
- // if (!wantInterfaces && memberType.isInterface()) continue next;
- if (onlyStatic && !memberType.isStatic())
- continue next;
+ break;
- if (typeLength > memberType.sourceName.length)
- continue next;
+ case Scope.COMPILATION_UNIT_SCOPE :
+ SourceTypeBinding[] types = ((CompilationUnitScope)currentScope).topLevelTypes;
+ if (types != null) {
+ for (int j = 0; j < types.length; j++) {
+ if (types[j] == exceptionType) {
+ isQualified = false;
+ break done;
+ }
+ }
+ }
+ break done;
+ }
+ currentScope = currentScope.parent;
+ }
- if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
- continue next;
+ if (isQualified && mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, exceptionType.modifiers)) {
+ if (memberPackageName == null || memberPackageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ return; // ignore types from the default package from outside it
+ } else {
+ isQualified = false;
+ }
- if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
+ if (isQualified) {
+ completionName =
+ CharOperation.concat(
+ memberPackageName,
+ CharOperation.concat(
+ memberEnclosingTypeNames,
+ memberTypeName,
+ '.'),
+ '.');
+ }
+ }
- if (this.options.checkVisibility
- && !memberType.canBeSeenBy(this.unitScope.fPackage))
- continue next;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(typeName, exceptionType.sourceName);
+ relevance += computeRelevanceForExpectingType(exceptionType);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ if(!this.insideQualifiedReference) {
+ relevance += computeRelevanceForQualification(isQualified);
+ }
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException();
- char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(
+ exceptionType,
+ exceptionType.qualifiedSourceName(),
+ IAccessRule.K_ACCESSIBLE,
+ completionName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ private void findExceptionFromTryStatement(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ SourceTypeBinding invocationType,
+ BlockScope scope,
+ ObjectVector typesFound) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ for (int i = 0; i <= this.expectedTypesPtr; i++) {
+ ReferenceBinding exceptionType = (ReferenceBinding)this.expectedTypes[i];
- if (memberType.isClass()) {
- relevance += computeRelevanceForClass();
- } else if(memberType.isEnum()) {
- relevance += computeRelevanceForEnum();
- } else if (memberType.isInterface()) {
- relevance += computeRelevanceForInterface();
- }
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(
- memberType,
- memberType.qualifiedSourceName(),
- IAccessRule.K_ACCESSIBLE,
- completionName,
- relevance,
- null,
- null,
- null,
- false);
- }
+ findExceptionFromTryStatement(typeName, exceptionType, receiverType, invocationType, scope, typesFound, true);
}
}
+ private void findExplicitConstructors(
+ char[] name,
+ ReferenceBinding currentType,
+ MethodScope scope,
+ InvocationSite invocationSite) {
- private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
- FieldBinding[] fields = ref.availableFields();
-
- int fieldLength = fieldName.length;
- next : for (int m = fields.length; --m >= 0;) {
- FieldBinding field = fields[m];
+ ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration)scope.referenceContext;
+ MethodBinding enclosingConstructor = constructorDeclaration.binding;
- if (fieldLength > field.name.length)
- continue next;
+ // No visibility checks can be performed without the scope & invocationSite
+ MethodBinding[] methods = currentType.availableMethods();
+ if(methods != null) {
+ next : for (int f = methods.length; --f >= 0;) {
+ MethodBinding constructor = methods[f];
+ if (constructor != enclosingConstructor && constructor.isConstructor()) {
- if (field.isSynthetic())
- continue next;
+ if (constructor.isSynthetic()) continue next;
- if (!field.isStatic())
- continue next;
+ if (this.options.checkDeprecation &&
+ constructor.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(constructor.declaringClass))
+ continue next;
- if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
- continue next;
+ if (this.options.checkVisibility
+ && !constructor.canBeSeenBy(invocationSite, scope)) continue next;
- if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
+ TypeBinding[] parameters = constructor.parameters;
+ int paramLength = parameters.length;
- if (this.options.checkVisibility
- && !field.canBeSeenBy(this.unitScope.fPackage))
- continue next;
+ char[][] parameterPackageNames = new char[paramLength][];
+ char[][] parameterTypeNames = new char[paramLength][];
+ for (int i = 0; i < paramLength; i++) {
+ TypeBinding type = parameters[i];
+ parameterPackageNames[i] = type.qualifiedPackageName();
+ parameterTypeNames[i] = type.qualifiedSourceName();
+ }
+ char[][] parameterNames = findMethodParameterNames(constructor,parameterTypeNames);
- char[] completionName = CharOperation.concat(field.name, SEMICOLON);
+ char[] completion = CharOperation.NO_CHAR;
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(')
+ completion = name;
+ else
+ completion = CharOperation.concat(name, new char[] { '(', ')' });
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(fieldName, field.name);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(this.completionToken, name);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(field.declaringClass));
- proposal.setSignature(getSignature(field.type));
- proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
- proposal.setPackageName(field.type.qualifiedPackageName());
- proposal.setTypeName(field.type.qualifiedSourceName());
- proposal.setName(field.name);
- proposal.setCompletion(completionName);
- proposal.setFlags(field.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(currentType));
+ proposal.setSignature(getSignature(constructor));
+ MethodBinding original = constructor.original();
+ if(original != constructor) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(currentType.qualifiedPackageName());
+ proposal.setDeclarationTypeName(currentType.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ //proposal.setPackageName(null);
+ //proposal.setTypeName(null);
+ proposal.setName(name);
+ proposal.setIsContructor(true);
+ proposal.setCompletion(completion);
+ proposal.setFlags(constructor.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
}
}
}
}
+ // Helper method for findFields(char[], ReferenceBinding, Scope, ObjectVector, boolean)
+ private void findFields(
+ char[] fieldName,
+ FieldBinding[] fields,
+ Scope scope,
+ ObjectVector fieldsFound,
+ ObjectVector localsFound,
+ boolean onlyStaticFields,
+ ReferenceBinding receiverType,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean canBePrefixed,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems,
+ char[] castedReceiver,
+ int receiverStart,
+ int receiverEnd) {
- private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
- MethodBinding[] methods = ref.availableMethods();
+ ObjectVector newFieldsFound = new ObjectVector();
+ // Inherited fields which are hidden by subclasses are filtered out
+ // No visibility checks can be performed without the scope & invocationSite
- int methodLength = methodName.length;
- next : for (int m = methods.length; --m >= 0;) {
- MethodBinding method = methods[m];
+ int fieldLength = fieldName.length;
+ next : for (int f = fields.length; --f >= 0;) {
+ FieldBinding field = fields[f];
- if (method.isSynthetic()) continue next;
+ if (field.isSynthetic()) continue next;
- if (method.isDefaultAbstract()) continue next;
+ if (onlyStaticFields && !field.isStatic()) continue next;
- if (method.isConstructor()) continue next;
+ if (fieldLength > field.name.length) continue next;
- if (!method.isStatic()) continue next;
+ if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
- if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
+ if (this.options.checkDeprecation &&
+ field.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(field.declaringClass))
+ continue next;
if (this.options.checkVisibility
- && !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
+ && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
- if (methodLength > method.selector.length)
- continue next;
+ boolean prefixRequired = false;
- if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
- continue next;
+ for (int i = fieldsFound.size; --i >= 0;) {
+ Object[] other = (Object[])fieldsFound.elementAt(i);
+ FieldBinding otherField = (FieldBinding) other[0];
+ ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+ if (field == otherField && receiverType == otherReceiverType)
+ continue next;
+ if (CharOperation.equals(field.name, otherField.name, true)) {
+ if (field.declaringClass.isSuperclassOf(otherField.declaringClass))
+ continue next;
+ if (otherField.declaringClass.isInterface()) {
+ if (field.declaringClass == scope.getJavaLangObject())
+ continue next;
+ if (field.declaringClass.implementsInterface(otherField.declaringClass, true))
+ continue next;
+ }
+ if (field.declaringClass.isInterface())
+ if (otherField.declaringClass.implementsInterface(field.declaringClass, true))
+ continue next;
+ if(canBePrefixed) {
+ prefixRequired = true;
+ } else {
+ continue next;
+ }
+ }
+ }
- int length = method.parameters.length;
- char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
+ for (int l = localsFound.size; --l >= 0;) {
+ LocalVariableBinding local = (LocalVariableBinding) localsFound.elementAt(l);
- for (int i = 0; i < length; i++) {
- TypeBinding type = method.original().parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
+ if (CharOperation.equals(field.name, local.name, true)) {
+ SourceTypeBinding declarationType = scope.enclosingSourceType();
+ if (declarationType.isAnonymousType() && declarationType != invocationScope.enclosingSourceType()) {
+ continue next;
+ }
+ if(canBePrefixed) {
+ prefixRequired = true;
+ } else {
+ continue next;
+ }
+ break;
+ }
}
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
- char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
+ newFieldsFound.add(new Object[]{field, receiverType});
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(methodName, method.selector);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ char[] completion = field.name;
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- proposal.setCompletion(completionName);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
+ if(prefixRequired || this.options.forceImplicitQualification){
+ char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), field.isStatic());
+ completion = CharOperation.concat(prefix,completion,'.');
}
- }
- }
- /*
- * Find javadoc block tags for a given completion javadoc tag node
- */
- private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
- char[][] possibleTags = javadocTag.getPossibleBlockTags();
- if (possibleTags == null) return;
- int length = possibleTags.length;
- for (int i=0; i 0) {
+ if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+ CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+ if (fieldRef.receiver.isThis()) {
+ if (fieldRef.completeInText()) {
+ completion = CharOperation.concat(new char[] { '#' }, field.name);
+ }
+ } else if (fieldRef.completeInText()) {
+ if (fieldRef.receiver instanceof JavadocSingleTypeReference) {
+ JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) fieldRef.receiver;
+ completion = CharOperation.concat(typeRef.token, field.name, '#');
+ } else if (fieldRef.receiver instanceof JavadocQualifiedTypeReference) {
+ JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) fieldRef.receiver;
+ completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), field.name, '#');
+ }
+ }
}
}
- }
- }
- /*
- * Find javadoc inline tags for a given completion javadoc tag node
- */
- private void findJavadocInlineTags(CompletionOnJavadocTag javadocTag) {
- char[][] possibleTags = javadocTag.getPossibleInlineTags();
- if (possibleTags == null) return;
- int length = possibleTags.length;
- for (int i=0; i 0)
- for (int i = 0; i < choices.length; i++)
- if (length <= choices[i].length
- && CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
- )){
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
- if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
- if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
- relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
- relevance += computeRelevanceForQualification(false);
+ // Javadoc completions
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_FIELD_REF)) {
+ char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(field.modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
- proposal.setName(choices[i]);
- proposal.setCompletion(choices[i]);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
+ // Javadoc value completion for static fields
+ if (field.isStatic() && !this.requestor.isIgnored(CompletionProposal.JAVADOC_VALUE_REF)) {
+ javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_VALUE);
+ InternalCompletionProposal valueProposal = createProposal(CompletionProposal.JAVADOC_VALUE_REF, this.actualCompletionPosition);
+ valueProposal.setDeclarationSignature(getSignature(field.declaringClass));
+ valueProposal.setSignature(getSignature(field.type));
+ valueProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ valueProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ valueProposal.setPackageName(field.type.qualifiedPackageName());
+ valueProposal.setTypeName(field.type.qualifiedSourceName());
+ valueProposal.setName(field.name);
+ valueProposal.setCompletion(javadocCompletion);
+ valueProposal.setFlags(field.modifiers);
+ valueProposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ valueProposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ valueProposal.setRelevance(relevance+R_VALUE_TAG);
+ this.requestor.accept(valueProposal);
if(DEBUG) {
- this.printDebug(proposal);
+ this.printDebug(valueProposal);
}
}
}
- }
- private void findTrueOrFalseKeywords(char[][] choices) {
- if(choices == null || choices.length == 0) return;
-
- if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
-
- for (int i = 0; i < choices.length; i++) {
- if (CharOperation.equals(choices[i], Keywords.TRUE) ||
- CharOperation.equals(choices[i], Keywords.FALSE)
- ){
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
- relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
- relevance += computeRelevanceForQualification(false);
- relevance += R_TRUE_OR_FALSE;
-
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
- proposal.setName(choices[i]);
- proposal.setCompletion(choices[i]);
+ } else {
+ if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setReceiverSignature(getSignature(receiverType));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
proposal.setRelevance(relevance);
this.requestor.accept(proposal);
@@ -5076,1560 +5076,1358 @@
}
}
}
- }
-
- private void findKeywordsForMember(char[] token, int modifiers) {
- char[][] keywords = new char[Keywords.COUNT][];
- int count = 0;
-
- // visibility
- if((modifiers & ClassFileConstants.AccPrivate) == 0
- && (modifiers & ClassFileConstants.AccProtected) == 0
- && (modifiers & ClassFileConstants.AccPublic) == 0) {
- keywords[count++] = Keywords.PROTECTED;
- keywords[count++] = Keywords.PUBLIC;
- if((modifiers & ClassFileConstants.AccAbstract) == 0) {
- keywords[count++] = Keywords.PRIVATE;
- }
- }
-
- if((modifiers & ClassFileConstants.AccAbstract) == 0) {
- // abtract
- if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
- keywords[count++] = Keywords.ABSTRACT;
- }
-
- // final
- if((modifiers & ClassFileConstants.AccFinal) == 0) {
- keywords[count++] = Keywords.FINAL;
- }
-
- // static
- if((modifiers & ClassFileConstants.AccStatic) == 0) {
- keywords[count++] = Keywords.STATIC;
- }
-
- boolean canBeField = true;
- boolean canBeMethod = true;
- boolean canBeType = true;
- if((modifiers & ClassFileConstants.AccNative) != 0
- || (modifiers & ClassFileConstants.AccStrictfp) != 0
- || (modifiers & ClassFileConstants.AccSynchronized) != 0) {
- canBeField = false;
- canBeType = false;
- }
-
- if((modifiers & ClassFileConstants.AccTransient) != 0
- || (modifiers & ClassFileConstants.AccVolatile) != 0) {
- canBeMethod = false;
- canBeType = false;
- }
-
- if(canBeField) {
- // transient
- if((modifiers & ClassFileConstants.AccTransient) == 0) {
- keywords[count++] = Keywords.TRANSIENT;
- }
-
- // volatile
- if((modifiers & ClassFileConstants.AccVolatile) == 0) {
- keywords[count++] = Keywords.VOLATILE;
- }
- }
-
- if(canBeMethod) {
- // native
- if((modifiers & ClassFileConstants.AccNative) == 0) {
- keywords[count++] = Keywords.NATIVE;
- }
-
- // strictfp
- if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
- keywords[count++] = Keywords.STRICTFP;
- }
-
- // synchronized
- if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
- keywords[count++] = Keywords.SYNCHRONIZED;
- }
- }
-
- if(canBeType) {
- keywords[count++] = Keywords.CLASS;
- keywords[count++] = Keywords.INTERFACE;
-
- if((modifiers & ClassFileConstants.AccFinal) == 0) {
- keywords[count++] = Keywords.ENUM;
- }
- }
- } else {
- // class
- keywords[count++] = Keywords.CLASS;
- keywords[count++] = Keywords.INTERFACE;
- }
- System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
- findKeywords(token, keywords, false, false);
+ fieldsFound.addAll(newFieldsFound);
}
+ private void findFields(
+ char[] fieldName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ ObjectVector fieldsFound,
+ ObjectVector localsFound,
+ boolean onlyStaticFields,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean canBePrefixed,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems,
+ char[] castedReceiver,
+ int receiverStart,
+ int receiverEnd) {
- protected void findMembers(
- char[] token,
- ReferenceBinding receiverType,
- Scope scope,
- InvocationSite invocationSite,
- boolean isInsideAnnotationAttribute,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
+ boolean notInJavadoc = this.assistNodeInJavadoc == 0;
+ if (fieldName == null && notInJavadoc)
+ return;
- if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- findMemberTypes(
- token,
- receiverType,
- scope,
- scope.enclosingSourceType(),
- false,
- true,
- new ObjectVector(),
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems);
- }
- if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- findClassField(
- token,
- receiverType,
+ ReferenceBinding currentType = receiverType;
+ ReferenceBinding[] interfacesToVisit = null;
+ int nextPosition = 0;
+ do {
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (notInJavadoc && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ if (interfacesToVisit == null) {
+ interfacesToVisit = itsInterfaces;
+ nextPosition = interfacesToVisit.length;
+ } else {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
+
+ FieldBinding[] fields = currentType.availableFields();
+ if(fields != null && fields.length > 0) {
+ findFields(
+ fieldName,
+ fields,
scope,
+ fieldsFound,
+ localsFound,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ canBePrefixed,
missingElements,
missingElementsStarts,
missingElementsEnds,
- missingElementsHaveProblems);
- }
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+ }
+ currentType = currentType.superclass();
+ } while (notInJavadoc && currentType != null);
- MethodScope methodScope = null;
- if (!isInsideAnnotationAttribute &&
- !this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
- ((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
- || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
- if (token.length > 0) {
- findKeywords(token, new char[][]{Keywords.THIS}, false, true);
- } else {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
- relevance += R_NON_INHERITED;
+ if (notInJavadoc && interfacesToVisit != null) {
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding anInterface = interfacesToVisit[i];
+ FieldBinding[] fields = anInterface.availableFields();
+ if(fields != null) {
+ findFields(
+ fieldName,
+ fields,
+ scope,
+ fieldsFound,
+ localsFound,
+ onlyStaticFields,
+ receiverType,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ canBePrefixed,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+ }
- this.noProposal = false;
- if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
- proposal.setName(Keywords.THIS);
- proposal.setCompletion(Keywords.THIS);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if (DEBUG) {
- this.printDebug(proposal);
+ ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
}
}
}
}
-
- if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
- findFields(
- token,
- receiverType,
- scope,
- new ObjectVector(),
- new ObjectVector(),
- true,
- invocationSite,
- scope,
- false,
- false,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- null,
- -1,
- -1);
- }
-
- if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- findMethods(
- token,
- null,
- null,
- receiverType,
- scope,
- new ObjectVector(),
- true,
- false,
- false,
- invocationSite,
- scope,
- false,
- false,
- false,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- null,
- -1,
- -1);
- }
- }
-
- private void findMembersFromMissingType(
- final char[] token,
- final long pos,
- TypeBinding resolveType,
- final Scope scope,
- final InvocationSite invocationSite,
- final boolean isInsideAnnotationAttribute) {
- MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
- MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
- new MissingTypesGuesser.GuessedTypeRequestor() {
- public void accept(
- TypeBinding guessedType,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean hasProblems) {
- if (guessedType instanceof ReferenceBinding) {
- findMembers(
- CompletionEngine.this.completionToken,
- (ReferenceBinding)guessedType,
- scope,
- invocationSite,
- isInsideAnnotationAttribute,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- hasProblems);
- }
- }
- };
- SingleTypeReference typeRef = new SingleTypeReference(token, pos);
- typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
- missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
}
- // Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
- private void findMemberTypes(
- char[] typeName,
- ReferenceBinding[] memberTypes,
- ObjectVector typesFound,
- ReferenceBinding receiverType,
- SourceTypeBinding invocationType,
- boolean staticOnly,
- boolean staticFieldsAndMethodOnly,
- boolean fromStaticImport,
- boolean checkQualification,
+ protected void findFieldsAndMethods(
+ char[] token,
+ TypeBinding receiverType,
Scope scope,
+ ObjectVector fieldsFound,
+ ObjectVector methodsFound,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean superCall,
Binding[] missingElements,
int[] missingElementsStarts,
int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
-
- // Inherited member types which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
- int typeLength = typeName.length;
- next : for (int m = memberTypes.length; --m >= 0;) {
- ReferenceBinding memberType = memberTypes[m];
- // if (!wantClasses && memberType.isClass()) continue next;
- // if (!wantInterfaces && memberType.isInterface()) continue next;
+ boolean missingElementsHaveProblems,
+ char[] castedReceiver,
+ int receiverStart,
+ int receiverEnd) {
- if (staticOnly && !memberType.isStatic()) continue next;
+ if (token == null)
+ return;
- if (isForbidden(memberType)) continue next;
+ if (receiverType.isBaseType())
+ return; // nothing else is possible with base types
- if (typeLength > memberType.sourceName.length)
- continue next;
+ boolean proposeField =
+ castedReceiver == null ?
+ !this.isIgnored(CompletionProposal.FIELD_REF, missingElements != null) :
+ !this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null) ;
+ boolean proposeMethod =
+ castedReceiver == null ?
+ !this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) :
+ !this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null);
- if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
- continue next;
+ if (receiverType.isArrayType()) {
+ if (proposeField
+ && token.length <= lengthField.length
+ && CharOperation.prefixEquals(token, lengthField, false /* ignore case */
+ )) {
- if (this.options.checkDeprecation &&
- memberType.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(memberType))
- continue next;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token,lengthField);
+ relevance += computeRelevanceForExpectingType(TypeBinding.INT);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for length field
+ if (missingElements != null) {
+ relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+ }
+ this.noProposal = false;
+ if (castedReceiver == null) {
+ if(!isIgnored(CompletionProposal.FIELD_REF, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(receiverType));
+ proposal.setSignature(INT_SIGNATURE);
+ proposal.setTypeName(INT);
+ proposal.setName(lengthField);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(lengthField);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ char[] completion = CharOperation.concat(castedReceiver, lengthField);
- if (this.options.checkVisibility) {
- if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
- continue next;
- } else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
- continue next;
+ if(!this.isIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(receiverType));
+ proposal.setSignature(INT_SIGNATURE);
+ proposal.setReceiverSignature(getSignature(receiverType));
+ proposal.setTypeName(INT);
+ proposal.setName(lengthField);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
}
}
+ if (proposeMethod
+ && token.length <= cloneMethod.length
+ && CharOperation.prefixEquals(token, cloneMethod, false /* ignore case */)
+ ) {
+ ReferenceBinding objectRef = scope.getJavaLangObject();
- if (this.insideQualifiedReference &&
- receiverType.isParameterizedType() &&
- memberType.isStatic()) {
- continue next;
- }
-
- for (int i = typesFound.size; --i >= 0;) {
- ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
-
- if (memberType == otherType)
- continue next;
-
- if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
-
- if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
- continue next;
-
- if (otherType.enclosingType().isInterface())
- if (memberType.enclosingType()
- .implementsInterface(otherType.enclosingType(), true))
- continue next;
-
- if (memberType.enclosingType().isInterface())
- if (otherType.enclosingType()
- .implementsInterface(memberType.enclosingType(), true))
- continue next;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, cloneMethod);
+ relevance += computeRelevanceForExpectingType(objectRef);
+ relevance += computeRelevanceForStatic(false, false);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for clone() method
+ if (missingElements != null) {
+ relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
}
- }
-
- typesFound.add(memberType);
-
- if(!this.insideQualifiedReference) {
- if(this.assistNodeIsClass) {
- if(!memberType.isClass()) continue next;
- } else if(this.assistNodeIsInterface) {
- if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
- } else if (this.assistNodeIsAnnotation) {
- if(!memberType.isAnnotationType()) continue next;
+ char[] completion;
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = cloneMethod;
+ } else {
+ completion = CharOperation.concat(cloneMethod, new char[] { '(', ')' });
}
- }
-
- char[] completionName = memberType.sourceName();
- boolean isQualified = false;
- if(checkQualification && !fromStaticImport) {
- char[] memberPackageName = memberType.qualifiedPackageName();
- char[] memberTypeName = memberType.sourceName();
- char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
- if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
- if (memberPackageName == null || memberPackageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- break next; // ignore types from the default package from outside it
- isQualified = true;
- completionName =
- CharOperation.concat(
- memberPackageName,
- CharOperation.concat(
- memberEnclosingTypeNames,
- memberTypeName,
- '.'),
- '.');
+ if (castedReceiver != null) {
+ completion = CharOperation.concat(castedReceiver, completion);
}
- }
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
- relevance += computeRelevanceForExpectingType(memberType);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if(!this.insideQualifiedReference) {
- relevance += computeRelevanceForQualification(isQualified);
- }
- 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.
-
- if (memberType.isAnnotationType()) {
- relevance += computeRelevanceForAnnotation();
- relevance += computeRelevanceForAnnotationTarget(memberType);
- } else if (memberType.isClass()) {
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(memberType.sourceName);
- } else if(memberType.isEnum()) {
- relevance += computeRelevanceForEnum();
- } else if(memberType.isInterface()) {
- relevance += computeRelevanceForInterface();
- }
-
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
- }
-
- this.noProposal = false;
- createTypeProposal(
- memberType,
- memberType.qualifiedSourceName(),
- IAccessRule.K_ACCESSIBLE,
- completionName,
- relevance,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems);
+ this.noProposal = false;
+ if (castedReceiver == null) {
+ if (!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(receiverType));
+ proposal.setSignature(
+ this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ getSignature(receiverType)) :
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.concatWith(JAVA_LANG, '.'),
+ OBJECT));
+ //proposal.setOriginalSignature(null);
+ //proposal.setDeclarationPackageName(null);
+ //proposal.setDeclarationTypeName(null);
+ //proposal.setParameterPackageNames(null);
+ //proposal.setParameterTypeNames(null);
+ proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+ proposal.setTypeName(OBJECT);
+ proposal.setName(cloneMethod);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ methodsFound.add(new Object[]{objectRef.getMethods(cloneMethod)[0], objectRef});
+ } else {
+ if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(receiverType));
+ proposal.setSignature(
+ this.compilerOptions.sourceLevel > ClassFileConstants.JDK1_4 && receiverType.isArrayType() ?
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ getSignature(receiverType)) :
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.concatWith(JAVA_LANG, '.'),
+ OBJECT));
+ proposal.setReceiverSignature(getSignature(receiverType));
+ proposal.setPackageName(CharOperation.concatWith(JAVA_LANG, '.'));
+ proposal.setTypeName(OBJECT);
+ proposal.setName(cloneMethod);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
+
+ receiverType = scope.getJavaLangObject();
+ }
+
+ checkTimeout();
+
+ if(proposeField) {
+ findFields(
+ token,
+ (ReferenceBinding) receiverType,
+ scope,
+ fieldsFound,
+ new ObjectVector(),
+ false,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ false,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
}
- }
- protected void findMemberTypes(
- char[] typeName,
- ReferenceBinding receiverType,
- Scope scope,
- SourceTypeBinding typeInvocation,
- boolean staticOnly,
- boolean staticFieldsAndMethodOnly,
- ObjectVector typesFound,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
- findMemberTypes(
- typeName,
- receiverType,
+ if(proposeMethod) {
+ findMethods(
+ token,
+ null,
+ null,
+ (ReferenceBinding) receiverType,
scope,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
+ methodsFound,
false,
false,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
false,
- null,
- typesFound,
missingElements,
missingElementsStarts,
missingElementsEnds,
- missingElementsHaveProblems);
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+ }
}
- private void findMemberTypes(
- char[] typeName,
- ReferenceBinding receiverType,
- Scope scope,
- SourceTypeBinding typeInvocation,
- boolean staticOnly,
- boolean staticFieldsAndMethodOnly,
- boolean fromStaticImport,
- boolean checkQualification,
- boolean proposeAllMemberTypes,
- SourceTypeBinding typeToIgnore,
- ObjectVector typesFound,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
- ReferenceBinding currentType = receiverType;
- if (typeName == null)
- return;
+ protected void findFieldsAndMethodsFromAnotherReceiver(
+ char[] token,
+ TypeReference receiverType,
+ Scope scope,
+ ObjectVector fieldsFound,
+ ObjectVector methodsFound,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean superCall,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems,
+ char[][] receiverName,
+ int receiverStart,
+ int receiverEnd) {
- if (this.insideQualifiedReference
- || typeName.length == 0) { // do not search up the hierarchy
+ if (receiverType.resolvedType == null) return;
- findMemberTypes(
- typeName,
- currentType.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- checkQualification,
- scope,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems);
- return;
+ TypeBinding receiverTypeBinding = receiverType.resolvedType;
+ char[] castedReceiver = null;
+
+ char[] castedTypeChars = CharOperation.concatWith(receiverType.getTypeName(), '.');
+ if(this.source != null) {
+ int memberRefStart = this.startPosition;
+
+ char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
+ char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
+
+ castedReceiver =
+ CharOperation.concat(
+ CharOperation.concat(
+ '(',
+ CharOperation.concat(
+ CharOperation.concat('(', castedTypeChars, ')'),
+ receiverChars),
+ ')'),
+ dotChars);
+ } else {
+ castedReceiver =
+ CharOperation.concat(
+ CharOperation.concat(
+ '(',
+ CharOperation.concat(
+ CharOperation.concat('(', castedTypeChars, ')'),
+ CharOperation.concatWith(receiverName, '.')),
+ ')'),
+ DOT);
}
- ReferenceBinding[] interfacesToVisit = null;
- int nextPosition = 0;
+ if (castedReceiver == null) return;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
- if (interfacesToVisit == null) {
- interfacesToVisit = itsInterfaces;
- nextPosition = interfacesToVisit.length;
- } else {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
- }
- }
+ int oldStartPosition = this.startPosition;
+ this.startPosition = receiverStart;
- findMemberTypes(
- typeName,
- currentType.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- checkQualification,
+ findFieldsAndMethods(
+ token,
+ receiverTypeBinding,
scope,
+ fieldsFound,
+ methodsFound,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
missingElements,
missingElementsStarts,
missingElementsEnds,
- missingElementsHaveProblems);
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
- currentType = currentType.superclass();
- } while (currentType != null);
+ this.startPosition = oldStartPosition;
+ }
+ private void findFieldsAndMethodsFromCastedReceiver(
+ ASTNode enclosingNode,
+ Binding qualifiedBinding,
+ Scope scope,
+ ObjectVector fieldsFound,
+ ObjectVector methodsFound,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ Expression receiver) {
- if(proposeAllMemberTypes) {
- ReferenceBinding[] memberTypes = receiverType.memberTypes();
- for (int i = 0; i < memberTypes.length; i++) {
- if(memberTypes[i] != typeToIgnore) {
- findSubMemberTypes(
- typeName,
- memberTypes[i],
- scope,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- typesFound);
- }
- }
- }
+ if (enclosingNode == null || !(enclosingNode instanceof IfStatement)) return;
- if (interfacesToVisit != null) {
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding anInterface = interfacesToVisit[i];
- findMemberTypes(
- typeName,
- anInterface.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- checkQualification,
- scope,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems);
+ IfStatement ifStatement = (IfStatement)enclosingNode;
+
+ if (!(ifStatement.condition instanceof InstanceOfExpression)) return;
+
+ InstanceOfExpression instanceOfExpression = (InstanceOfExpression) ifStatement.condition;
+
+ TypeReference instanceOfType = instanceOfExpression.type;
+
+ if (instanceOfType.resolvedType == null) return;
+
+ boolean findFromAnotherReceiver = false;
+
+ char[][] receiverName = null;
+ int receiverStart = -1;
+ int receiverEnd = -1;
+
+ if (receiver instanceof QualifiedNameReference) {
+ QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) receiver;
- ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
- if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
- }
+ receiverName = qualifiedNameReference.tokens;
+
+ if (receiverName.length != 1) return;
+
+ receiverStart = (int) (qualifiedNameReference.sourcePositions[0] >>> 32);
+ receiverEnd = (int) qualifiedNameReference.sourcePositions[qualifiedNameReference.tokens.length - 1] + 1;
+
+ // if (local instanceof X) local.|
+ // if (field instanceof X) field.|
+ if (instanceOfExpression.expression instanceof SingleNameReference &&
+ ((SingleNameReference)instanceOfExpression.expression).binding == qualifiedBinding &&
+ (qualifiedBinding instanceof LocalVariableBinding || qualifiedBinding instanceof FieldBinding)) {
+ findFromAnotherReceiver = true;
}
- }
- }
- private void findMemberTypesFromMissingType(
- char[] typeName,
- final long pos,
- final Scope scope) {
- MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
- MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
- new MissingTypesGuesser.GuessedTypeRequestor() {
- public void accept(
- TypeBinding guessedType,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean hasProblems) {
- if (guessedType instanceof ReferenceBinding) {
- findMemberTypes(
- CompletionEngine.this.completionToken,
- (ReferenceBinding)guessedType,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- new ObjectVector(),
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- hasProblems);
- }
- }
- };
- SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
- typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
- missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
- }
+ // if (this.field instanceof X) field.|
+ if (instanceOfExpression.expression instanceof FieldReference) {
+ FieldReference fieldReference = (FieldReference)instanceOfExpression.expression;
- private void findMemberTypesFromMissingType(
- TypeReference typeRef,
- final long pos,
- final Scope scope) {
- MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
- MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
- new MissingTypesGuesser.GuessedTypeRequestor() {
- public void accept(
- TypeBinding guessedType,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean hasProblems) {
- if (guessedType instanceof ReferenceBinding) {
- findMemberTypes(
- CompletionEngine.this.completionToken,
- (ReferenceBinding)guessedType,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- new ObjectVector(),
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- hasProblems);
- }
+ if (fieldReference.receiver instanceof ThisReference &&
+ qualifiedBinding instanceof FieldBinding &&
+ fieldReference.binding == qualifiedBinding) {
+ findFromAnotherReceiver = true;
}
- };
- missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
- }
+ }
+ } else if (receiver instanceof FieldReference) {
+ FieldReference fieldReference1 = (FieldReference) receiver;
- /*
- * Find javadoc parameter names.
- */
- private void findJavadocParamNames(char[] token, char[][] missingParams, boolean isTypeParam) {
+ receiverStart = fieldReference1.sourceStart;
+ receiverEnd = fieldReference1.sourceEnd + 1;
- if (missingParams == null) return;
+ if (fieldReference1.receiver instanceof ThisReference) {
- // Get relevance
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for param name
- if (!isTypeParam) relevance += R_INTERESTING;
+ receiverName = new char[][] {THIS, fieldReference1.token};
- // Propose missing param
- int length = missingParams.length;
- relevance += length;
- for (int i=0; i') : argName;
- proposal.setCompletion(completion);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(--relevance);
- this.requestor.accept(proposal);
- if (DEBUG) {
- this.printDebug(proposal);
+ // if (this.field instanceof X) this.field.|
+ if (instanceOfExpression.expression instanceof FieldReference) {
+ FieldReference fieldReference2 = (FieldReference)instanceOfExpression.expression;
+
+ if (fieldReference2.receiver instanceof ThisReference &&
+ fieldReference2.binding == fieldReference1.binding) {
+ findFromAnotherReceiver = true;
}
}
}
}
- }
-
- private void findSubMemberTypes(
- char[] typeName,
- ReferenceBinding receiverType,
- Scope scope,
- SourceTypeBinding typeInvocation,
- boolean staticOnly,
- boolean staticFieldsAndMethodOnly,
- boolean fromStaticImport,
- ObjectVector typesFound) {
- ReferenceBinding currentType = receiverType;
- if (typeName == null || typeName.length == 0)
- return;
+ if (findFromAnotherReceiver) {
+ TypeBinding receiverTypeBinding = instanceOfType.resolvedType;
+ char[] castedReceiver = null;
- if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
+ char[] castedTypeChars = CharOperation.concatWith(instanceOfType.getTypeName(), '.');
+ if(this.source != null) {
+ int memberRefStart = this.startPosition;
- findMemberTypes(
- typeName,
- currentType.memberTypes(),
- typesFound,
- receiverType,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- true,
- scope,
- null,
- null,
- null,
- false);
+ char[] receiverChars = CharOperation.subarray(this.source, receiverStart, receiverEnd);
+ char[] dotChars = CharOperation.subarray(this.source, receiverEnd, memberRefStart);
- ReferenceBinding[] memberTypes = receiverType.memberTypes();
- next : for (int i = 0; i < memberTypes.length; i++) {
- if (this.options.checkVisibility) {
- if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
- continue next;
- } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
- continue next;
- }
+ castedReceiver =
+ CharOperation.concat(
+ CharOperation.concat(
+ '(',
+ CharOperation.concat(
+ CharOperation.concat('(', castedTypeChars, ')'),
+ receiverChars),
+ ')'),
+ dotChars);
+ } else {
+ castedReceiver =
+ CharOperation.concat(
+ CharOperation.concat(
+ '(',
+ CharOperation.concat(
+ CharOperation.concat('(', castedTypeChars, ')'),
+ CharOperation.concatWith(receiverName, '.')),
+ ')'),
+ DOT);
}
- findSubMemberTypes(
- typeName,
- memberTypes[i],
- scope,
- typeInvocation,
- staticOnly,
- staticFieldsAndMethodOnly,
- fromStaticImport,
- typesFound);
- }
- }
- private void findInterfacesMethods(
- char[] selector,
- TypeBinding[] typeArgTypes,
- TypeBinding[] argTypes,
- ReferenceBinding receiverType,
- ReferenceBinding[] itsInterfaces,
- Scope scope,
- ObjectVector methodsFound,
- boolean onlyStaticMethods,
- boolean exactMatch,
- boolean isCompletingDeclaration,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean superCall,
- boolean canBePrefixed,
- Binding[] missingElements,
- int[] missingElementssStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[] castedReceiver,
- int receiverStart,
- int receiverEnd) {
+ if (castedReceiver == null) return;
+
+ int oldStartPosition = this.startPosition;
+ this.startPosition = receiverStart;
+
+ findFieldsAndMethods(
+ this.completionToken,
+ receiverTypeBinding,
+ scope,
+ fieldsFound,
+ methodsFound,
+ invocationSite,
+ invocationScope,
+ false,
+ false,
+ null,
+ null,
+ null,
+ false,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
- if (selector == null)
- return;
+ this.startPosition = oldStartPosition;
+ }
+ }
+ private void findFieldsAndMethodsFromFavorites(
+ char[] token,
+ Scope scope,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ ObjectVector localsFound,
+ ObjectVector fieldsFound,
+ ObjectVector methodsFound) {
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- ReferenceBinding[] interfacesToVisit = itsInterfaces;
- int nextPosition = interfacesToVisit.length;
+ ObjectVector methodsFoundFromFavorites = new ObjectVector();
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding currentType = interfacesToVisit[i];
- MethodBinding[] methods = currentType.availableMethods();
- if(methods != null) {
- if(isCompletingDeclaration) {
- findLocalMethodDeclarations(
- selector,
- methods,
- scope,
- methodsFound,
- exactMatch,
- receiverType);
- } else {
- findLocalMethods(
- selector,
- typeArgTypes,
- argTypes,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementssStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- }
- }
+ ImportBinding[] favoriteBindings = getFavoriteReferenceBindings(invocationScope);
- itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
+ if (favoriteBindings != null && favoriteBindings.length > 0) {
+ for (int i = 0; i < favoriteBindings.length; i++) {
+ ImportBinding favoriteBinding = favoriteBindings[i];
+ switch (favoriteBinding.resolvedImport.kind()) {
+ case Binding.FIELD:
+ FieldBinding fieldBinding = (FieldBinding) favoriteBinding.resolvedImport;
+ findFieldsFromFavorites(
+ token,
+ new FieldBinding[]{fieldBinding},
+ scope,
+ fieldsFound,
+ localsFound,
+ fieldBinding.declaringClass,
+ invocationSite,
+ invocationScope);
+ break;
+ case Binding.METHOD:
+ MethodBinding methodBinding = (MethodBinding) favoriteBinding.resolvedImport;
+ MethodBinding[] methods = methodBinding.declaringClass.availableMethods();
+ long range;
+ if ((range = ReferenceBinding.binarySearch(methodBinding.selector, methods)) >= 0) {
+ int start = (int) range, end = (int) (range >> 32);
+ int length = end - start + 1;
+ System.arraycopy(methods, start, methods = new MethodBinding[length], 0, length);
+ } else {
+ methods = Binding.NO_METHODS;
+ }
+ findLocalMethodsFromFavorites(
+ token,
+ methods,
+ scope,
+ methodsFound,
+ methodsFoundFromFavorites,
+ methodBinding.declaringClass,
+ invocationSite,
+ invocationScope);
+ break;
+ case Binding.TYPE:
+ ReferenceBinding referenceBinding = (ReferenceBinding) favoriteBinding.resolvedImport;
+ if(favoriteBinding.onDemand) {
+ findFieldsFromFavorites(
+ token,
+ referenceBinding.availableFields(),
+ scope,
+ fieldsFound,
+ localsFound,
+ referenceBinding,
+ invocationSite,
+ invocationScope);
+
+ findLocalMethodsFromFavorites(
+ token,
+ referenceBinding.availableMethods(),
+ scope,
+ methodsFound,
+ methodsFoundFromFavorites,
+ referenceBinding,
+ invocationSite,
+ invocationScope);
+ }
+ break;
}
}
}
+
+ methodsFound.addAll(methodsFoundFromFavorites);
}
- private void findImplicitMessageSends(
+ private boolean findFieldsAndMethodsFromMissingFieldType(
char[] token,
- TypeBinding[] argTypes,
Scope scope,
InvocationSite invocationSite,
- Scope invocationScope,
- ObjectVector methodsFound) {
+ boolean insideTypeAnnotation) {
- if (token == null)
- return;
+ boolean foundSomeFields = false;
boolean staticsOnly = false;
- // need to know if we're in a static context (or inside a constructor)
+ Scope currentScope = scope;
done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- switch (scope.kind) {
+ switch (currentScope.kind) {
case Scope.METHOD_SCOPE :
// handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) scope;
+ MethodScope methodScope = (MethodScope) currentScope;
staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
break;
-
case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) scope;
+ ClassScope classScope = (ClassScope) currentScope;
SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- findMethods(
- token,
- null,
- argTypes,
- enclosingType,
- classScope,
- methodsFound,
- staticsOnly,
- true,
- false,
- invocationSite,
- invocationScope,
- true,
- false,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
+ if(!insideTypeAnnotation) {
+
+ FieldDeclaration[] fields = classScope.referenceContext.fields;
+
+ int fieldsCount = fields == null ? 0 : fields.length;
+ for (int i = 0; i < fieldsCount; i++) {
+ FieldDeclaration fieldDeclaration = fields[i];
+ if (CharOperation.equals(fieldDeclaration.name, token)) {
+ FieldBinding fieldBinding = fieldDeclaration.binding;
+ if (fieldBinding == null || fieldBinding.type == null || (fieldBinding.type.tagBits & TagBits.HasMissingType) != 0) {
+ foundSomeFields = true;
+ findFieldsAndMethodsFromMissingType(
+ fieldDeclaration.type,
+ currentScope,
+ invocationSite,
+ scope);
+ }
+ break done;
+ }
+ }
+ }
staticsOnly |= enclosingType.isStatic();
+ insideTypeAnnotation = false;
break;
-
case Scope.COMPILATION_UNIT_SCOPE :
break done;
}
- scope = scope.parent;
+ currentScope = currentScope.parent;
}
+ return foundSomeFields;
}
- // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
- private void findLocalMethods(
- char[] methodName,
- TypeBinding[] typeArgTypes,
- TypeBinding[] argTypes,
- MethodBinding[] methods,
+ private void findFieldsAndMethodsFromMissingReturnType(
+ char[] token,
+ TypeBinding[] arguments,
Scope scope,
- ObjectVector methodsFound,
- boolean onlyStaticMethods,
- boolean exactMatch,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean implicitCall,
- boolean superCall,
- boolean canBePrefixed,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems,
- char[] castedReceiver,
- int receiverStart,
- int receiverEnd) {
-
- ObjectVector newMethodsFound = new ObjectVector();
- // Inherited methods which are hidden by subclasses are filtered out
- // No visibility checks can be performed without the scope & invocationSite
-
- int methodLength = methodName.length;
- int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
- int minArgLength = argTypes == null ? 0 : argTypes.length;
-
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding method = methods[f];
-
- if (method.isSynthetic()) continue next;
-
- if (method.isDefaultAbstract()) continue next;
-
- if (method.isConstructor()) continue next;
-
- if (this.options.checkDeprecation &&
- method.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(method.declaringClass))
- continue next;
-
- //TODO (david) perhaps the relevance of a void method must be lesser than other methods
- //if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
-
- if (onlyStaticMethods && !method.isStatic()) continue next;
-
- if (this.options.checkVisibility
- && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-
- if(superCall && method.isAbstract()) {
- methodsFound.add(new Object[]{method, receiverType});
- continue next;
- }
-
- if (exactMatch) {
- if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
- continue next;
- }
- } else {
- if (methodLength > method.selector.length) continue next;
- if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
- continue next;
- }
- }
-
- if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
- continue next;
+ InvocationSite invocationSite,
+ boolean insideTypeAnnotation) {
- if (minTypeArgLength != 0) {
- method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
- }
+ boolean staticsOnly = false;
+ Scope currentScope = scope;
- if (minArgLength > method.parameters.length)
- continue next;
+ done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- for (int a = minArgLength; --a >= 0;){
- if (argTypes[a] != null) { // can be null if it could not be resolved properly
- if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
- continue next;
- }
- }
- }
+ switch (currentScope.kind) {
- boolean prefixRequired = false;
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) currentScope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+ break;
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) currentScope;
+ SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+ if(!insideTypeAnnotation) {
- for (int i = methodsFound.size; --i >= 0;) {
- Object[] other = (Object[]) methodsFound.elementAt(i);
- MethodBinding otherMethod = (MethodBinding) other[0];
- ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
- if (method == otherMethod && receiverType == otherReceiverType)
- continue next;
+ AbstractMethodDeclaration[] methods = classScope.referenceContext.methods;
- if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
- if (receiverType == otherReceiverType) {
- if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
- if (!superCall || !otherMethod.declaringClass.isInterface()) {
- continue next;
- }
- }
- } else {
- if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
- if(receiverType.isAnonymousType()) continue next;
+ int methodsCount = methods == null ? 0 : methods.length;
+ for (int i = 0; i < methodsCount; i++) {
+ AbstractMethodDeclaration methodDeclaration = methods[i];
+ if (methodDeclaration instanceof MethodDeclaration &&
+ CharOperation.equals(methodDeclaration.selector, token)) {
+ MethodDeclaration method = (MethodDeclaration) methodDeclaration;
+ MethodBinding methodBinding = method.binding;
+ if (methodBinding == null || methodBinding.returnType == null || (methodBinding.returnType.tagBits & TagBits.HasMissingType) != 0) {
+ Argument[] parameters = method.arguments;
+ int parametersLength = parameters == null ? 0 : parameters.length;
+ int argumentsLength = arguments == null ? 0 : arguments.length;
- if(!superCall) {
- if(!canBePrefixed) continue next;
+ if (parametersLength == 0) {
+ if (argumentsLength == 0) {
+ findFieldsAndMethodsFromMissingType(
+ method.returnType,
+ currentScope,
+ invocationSite,
+ scope);
+ break done;
+ }
+ } else {
+ TypeBinding[] parametersBindings;
+ if (methodBinding == null) { // since no binding, extra types from type references
+ parametersBindings = new TypeBinding[parametersLength];
+ for (int j = 0; j < parametersLength; j++) {
+ TypeBinding parameterType = parameters[j].type.resolvedType;
+ if (!parameterType.isValidBinding() && parameterType.closestMatch() != null) {
+ parameterType = parameterType.closestMatch();
+ }
+ parametersBindings[j] = parameterType;
+ }
+ } else {
+ parametersBindings = methodBinding.parameters;
+ }
+ if(areParametersCompatibleWith(parametersBindings, arguments, parameters[parametersLength - 1].isVarArgs())) {
+ findFieldsAndMethodsFromMissingType(
+ method.returnType,
+ currentScope,
+ invocationSite,
+ scope);
+ break done;
+ }
+ }
+ }
- prefixRequired = true;
}
}
}
- }
+ staticsOnly |= enclosingType.isStatic();
+ insideTypeAnnotation = false;
+ break;
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done;
}
+ currentScope = currentScope.parent;
+ }
+ }
- newMethodsFound.add(new Object[]{method, receiverType});
+ private void findFieldsAndMethodsFromMissingType(
+ TypeReference typeRef,
+ final Scope scope,
+ final InvocationSite invocationSite,
+ final Scope invocationScope) {
+ MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+ MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+ new MissingTypesGuesser.GuessedTypeRequestor() {
+ public void accept(
+ TypeBinding guessedType,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean hasProblems) {
+ findFieldsAndMethods(
+ CompletionEngine.this.completionToken,
+ guessedType,
+ scope,
+ new ObjectVector(),
+ new ObjectVector(),
+ invocationSite,
+ invocationScope,
+ false,
+ false,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ hasProblems,
+ null,
+ -1,
+ -1);
- ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
- if (method.declaringClass != superTypeWithSameErasure) {
- MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
- for (int i = 0; i < otherMethods.length; i++) {
- if(otherMethods[i].original() == method.original()) {
- method = otherMethods[i];
- }
}
- }
-
- int length = method.parameters.length;
- char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
-
- for (int i = 0; i < length; i++) {
- TypeBinding type = method.original().parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
-
- char[] completion = CharOperation.NO_CHAR;
-
- int previousStartPosition = this.startPosition;
- int previousTokenStart = this.tokenStart;
+ };
+ missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+ }
- // Special case for completion in javadoc
- if (this.assistNodeInJavadoc > 0) {
- Expression receiver = null;
- if (invocationSite instanceof CompletionOnJavadocMessageSend) {
- CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
- receiver = msg.receiver;
- } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
- CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
- receiver = fieldRef.receiver;
- }
- if (receiver != null) {
- StringBuffer javadocCompletion = new StringBuffer();
- if (receiver.isThis()) {
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
- javadocCompletion.append('#');
- }
- } else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
- if (receiver instanceof JavadocSingleTypeReference) {
- JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
- javadocCompletion.append(typeRef.token);
- javadocCompletion.append('#');
- } else if (receiver instanceof JavadocQualifiedTypeReference) {
- JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
- completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
- for (int t=0,nt =typeRef.tokens.length; t0) javadocCompletion.append('.');
- javadocCompletion.append(typeRef.tokens[t]);
+ private void findFieldsAndMethodsFromStaticImports(
+ char[] token,
+ Scope scope,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean exactMatch,
+ boolean insideAnnotationAttribute,
+ ObjectVector localsFound,
+ ObjectVector fieldsFound,
+ ObjectVector methodsFound,
+ boolean proposeField,
+ boolean proposeMethod) {
+ // search in static import
+ ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+ for (int i = 0; i < importBindings.length; i++) {
+ ImportBinding importBinding = importBindings[i];
+ if(importBinding.isValidBinding() && importBinding.isStatic()) {
+ Binding binding = importBinding.resolvedImport;
+ if(binding != null && binding.isValidBinding()) {
+ if(importBinding.onDemand) {
+ if((binding.kind() & Binding.TYPE) != 0) {
+ if(proposeField) {
+ findFields(
+ token,
+ (ReferenceBinding)binding,
+ scope,
+ fieldsFound,
+ localsFound,
+ true,
+ invocationSite,
+ invocationScope,
+ true,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
}
- javadocCompletion.append('#');
- }
- }
- javadocCompletion.append(method.selector);
- // Append parameters types
- javadocCompletion.append('(');
- if (method.parameters != null) {
- boolean isVarargs = method.isVarargs();
- for (int p=0, ln=method.parameters.length; p0) javadocCompletion.append(", "); //$NON-NLS-1$
- TypeBinding argTypeBinding = method.parameters[p];
- if (isVarargs && p == ln - 1) {
- createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
- } else {
- createType(argTypeBinding.erasure(), scope,javadocCompletion);
+ if(proposeMethod && !insideAnnotationAttribute) {
+ findMethods(
+ token,
+ null,
+ null,
+ (ReferenceBinding)binding,
+ scope,
+ methodsFound,
+ true,
+ exactMatch,
+ invocationSite,
+ invocationScope,
+ true,
+ false,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
}
}
- }
- javadocCompletion.append(')');
- completion = javadocCompletion.toString().toCharArray();
- }
- } else {
- // nothing to insert - do not want to replace the existing selector & arguments
- if (!exactMatch) {
- if (this.source != null
- && this.source.length > this.endPosition
- && this.source[this.endPosition] == '(')
- completion = method.selector;
- else
- completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
-
- if (castedReceiver != null) {
- completion = CharOperation.concat(castedReceiver, completion);
- }
- } else {
- if(prefixRequired && (this.source != null)) {
- completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
} else {
- this.startPosition = this.endPosition;
- }
- this.tokenStart = this.tokenEnd;
- }
-
- if(prefixRequired || this.options.forceImplicitQualification){
- char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
- completion = CharOperation.concat(prefix,completion,'.');
- }
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
- relevance += computeRelevanceForExpectingType(method.returnType);
- relevance += computeRelevanceForEnumConstant(method.returnType);
- relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
- relevance += computeRelevanceForQualification(prefixRequired);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if (onlyStaticMethods && this.insideQualifiedReference) {
- relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
- }
- if (missingElements != null) {
- relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
- }
-
- this.noProposal = false;
-
- if (castedReceiver == null) {
- // Standard proposal
- if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
+ if ((binding.kind() & Binding.FIELD) != 0) {
+ if(proposeField) {
+ findFields(
+ token,
+ new FieldBinding[]{(FieldBinding)binding},
+ scope,
+ fieldsFound,
+ localsFound,
+ true,
+ ((FieldBinding)binding).declaringClass,
+ invocationSite,
+ invocationScope,
+ true,
+ false,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ } else if ((binding.kind() & Binding.METHOD) != 0) {
+ if(proposeMethod && !insideAnnotationAttribute) {
+ MethodBinding methodBinding = (MethodBinding)binding;
+ if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
+ !exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
- // Javadoc proposal
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
- char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(method.modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setReceiverSignature(getSignature(receiverType));
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
+ findLocalMethodsFromStaticImports(
+ methodBinding.selector,
+ methodBinding.declaringClass.methods(),
+ scope,
+ exactMatch,
+ methodsFound,
+ methodBinding.declaringClass,
+ invocationSite);
+ }
+ }
}
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completion);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
}
}
}
- this.startPosition = previousStartPosition;
- this.tokenStart = previousTokenStart;
}
-
- methodsFound.addAll(newMethodsFound);
}
- private void findLocalMethodsFromFavorites(
- char[] methodName,
- MethodBinding[] methods,
+ private void findFieldsFromFavorites(
+ char[] fieldName,
+ FieldBinding[] fields,
Scope scope,
- ObjectVector methodsFound,
- ObjectVector methodsFoundFromFavorites,
+ ObjectVector fieldsFound,
+ ObjectVector localsFound,
ReferenceBinding receiverType,
InvocationSite invocationSite,
Scope invocationScope) {
- char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
+ char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
- int methodLength = methodName.length;
+ int fieldLength = fieldName.length;
+ next : for (int f = fields.length; --f >= 0;) {
+ FieldBinding field = fields[f];
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding method = methods[f];
+ if (field.isSynthetic()) continue next;
+
+ // only static fields must be proposed
+ if (!field.isStatic()) continue next;
+
+ if (fieldLength > field.name.length) continue next;
+
+ if (!CharOperation.prefixEquals(fieldName, field.name, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name))) continue next;
+
+ if (this.options.checkDeprecation &&
+ field.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(field.declaringClass))
+ continue next;
+
+ if (this.options.checkVisibility
+ && !field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+ for (int i = fieldsFound.size; --i >= 0;) {
+ Object[] other = (Object[])fieldsFound.elementAt(i);
+ FieldBinding otherField = (FieldBinding) other[0];
+
+ if (field == otherField) continue next;
+ }
+
+ fieldsFound.add(new Object[]{field, receiverType});
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal(field);
+ if (fieldName != null) relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+ relevance += computeRelevanceForExpectingType(field.type);
+ relevance += computeRelevanceForEnumConstant(field.type);
+ relevance += computeRelevanceForStatic(true, true);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if (method.isSynthetic()) continue next;
+ CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+ int importStart = cu.types[0].declarationSourceStart;
+ int importEnd = importStart;
- if (method.isDefaultAbstract()) continue next;
+ this.noProposal = false;
- if (method.isConstructor()) continue next;
+ if (this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5 ||
+ !this.options.suggestStaticImport) {
+ if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.TYPE_IMPORT)) {
+ char[] completion = CharOperation.concat(receiverType.sourceName, field.name, '.');
- if (this.options.checkDeprecation &&
- method.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(method.declaringClass))
- continue next;
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
- if (!method.isStatic()) continue next;
+ char[] typeImportCompletion = createImportCharArray(typeName, false, false);
- if (this.options.checkVisibility
- && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+ InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+ typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeImportProposal.completionEngine = this;
+ char[] packageName = receiverType.qualifiedPackageName();
+ typeImportProposal.setDeclarationSignature(packageName);
+ typeImportProposal.setSignature(getSignature(receiverType));
+ typeImportProposal.setPackageName(packageName);
+ typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
+ typeImportProposal.setCompletion(typeImportCompletion);
+ typeImportProposal.setFlags(receiverType.modifiers);
+ typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+ typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setRelevance(relevance);
- if (methodLength > method.selector.length) continue next;
+ proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
- if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
- continue next;
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
+ } else {
+ if (!this.isIgnored(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT)) {
+ char[] completion = field.name;
- for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
- Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
- MethodBinding otherMethod = (MethodBinding) other[0];
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completion);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
- if (method == otherMethod) continue next;
+ char[] fieldImportCompletion = createImportCharArray(CharOperation.concat(typeName, field.name, '.'), true, false);
- if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
- if (otherMethod.declaringClass == method.declaringClass &&
- this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
- continue next;
- }
+ InternalCompletionProposal fieldImportProposal = createProposal(CompletionProposal.FIELD_IMPORT, this.actualCompletionPosition);
+ fieldImportProposal.setDeclarationSignature(getSignature(field.declaringClass));
+ fieldImportProposal.setSignature(getSignature(field.type));
+ fieldImportProposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ fieldImportProposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ fieldImportProposal.setPackageName(field.type.qualifiedPackageName());
+ fieldImportProposal.setTypeName(field.type.qualifiedSourceName());
+ fieldImportProposal.setName(field.name);
+ fieldImportProposal.setCompletion(fieldImportCompletion);
+ fieldImportProposal.setFlags(field.modifiers);
+ fieldImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
+ fieldImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+ fieldImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+ fieldImportProposal.setRelevance(relevance);
+
+ proposal.setRequiredProposals(new CompletionProposal[]{fieldImportProposal});
+
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
}
+ }
+ }
+ }
+ private void findImplicitMessageSends(
+ char[] token,
+ TypeBinding[] argTypes,
+ Scope scope,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ ObjectVector methodsFound) {
- for (int i = methodsFound.size; --i >= 0;) {
- Object[] other = (Object[]) methodsFound.elementAt(i);
- MethodBinding otherMethod = (MethodBinding) other[0];
+ if (token == null)
+ return;
- if (method == otherMethod) continue next;
+ boolean staticsOnly = false;
+ // need to know if we're in a static context (or inside a constructor)
- if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
- if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
- continue next;
- }
- }
- }
+ done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
- this.options.suggestStaticImport;
+ switch (scope.kind) {
- boolean isAlreadyImported = false;
- if (!proposeStaticImport) {
- if(!this.importCachesInitialized) {
- initializeImportCaches();
- }
- for (int j = 0; j < this.importCacheCount; j++) {
- char[][] importName = this.importsCache[j];
- if(CharOperation.equals(receiverType.sourceName, importName[0])) {
- if (!CharOperation.equals(typeName, importName[1])) {
- continue next;
- } else {
- isAlreadyImported = true;
- }
- }
- }
- }
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) scope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+ break;
- methodsFoundFromFavorites.add(new Object[]{method, receiverType});
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) scope;
+ SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+ findMethods(
+ token,
+ null,
+ argTypes,
+ enclosingType,
+ classScope,
+ methodsFound,
+ staticsOnly,
+ true,
+ invocationSite,
+ invocationScope,
+ true,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ staticsOnly |= enclosingType.isStatic();
+ break;
- ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
- if (method.declaringClass != superTypeWithSameErasure) {
- MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
- for (int i = 0; i < otherMethods.length; i++) {
- if(otherMethods[i].original() == method.original()) {
- method = otherMethods[i];
- }
- }
- }
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done;
+ }
+ scope = scope.parent;
+ }
+ }
+ private void findImports(CompletionOnImportReference importReference, boolean findMembers) {
+ char[][] tokens = importReference.tokens;
- int length = method.parameters.length;
- char[][] parameterPackageNames = new char[length][];
- char[][] parameterTypeNames = new char[length][];
+ char[] importName = CharOperation.concatWith(tokens, '.');
- for (int i = 0; i < length; i++) {
- TypeBinding type = method.original().parameters[i];
- parameterPackageNames[i] = type.qualifiedPackageName();
- parameterTypeNames[i] = type.qualifiedSourceName();
- }
- char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
+ if (importName.length == 0)
+ return;
- char[] completion = CharOperation.NO_CHAR;
+ char[] lastToken = tokens[tokens.length - 1];
+ if(lastToken != null && lastToken.length == 0)
+ importName = CharOperation.concat(importName, new char[]{'.'});
- int previousStartPosition = this.startPosition;
- int previousTokenStart = this.tokenStart;
+ this.resolvingImports = true;
+ this.resolvingStaticImports = importReference.isStatic();
- if (this.source != null
- && this.source.length > this.endPosition
- && this.source[this.endPosition] == '(') {
- completion = method.selector;
- } else {
- completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
- }
+ this.completionToken = lastToken;
+ this.qualifiedCompletionToken = importName;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
- relevance += computeRelevanceForExpectingType(method.returnType);
- relevance += computeRelevanceForEnumConstant(method.returnType);
- relevance += computeRelevanceForStatic(true, method.isStatic());
- relevance += computeRelevanceForQualification(true);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ // want to replace the existing .*;
+ if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+ int oldStart = this.startPosition;
+ int oldEnd = this.endPosition;
+ setSourceRange(
+ importReference.sourceStart,
+ importReference.declarationSourceEnd);
+ this.nameEnvironment.findPackages(importName, this);
+ setSourceRange(
+ oldStart,
+ oldEnd - 1,
+ false);
+ }
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ this.nameEnvironment.findTypes(
+ importName,
+ findMembers,
+ this.options.camelCaseMatch,
+ IJavaSearchConstants.TYPE,
+ this);
+ acceptTypes(null);
+ }
+ }
- CompilationUnitDeclaration cu = this.unitScope.referenceContext;
- int importStart = cu.types[0].declarationSourceStart;
- int importEnd = importStart;
+ private void findImportsOfMemberTypes(char[] typeName, ReferenceBinding ref, boolean onlyStatic) {
+ ReferenceBinding[] memberTypes = ref.memberTypes();
- this.noProposal = false;
+ int typeLength = typeName.length;
+ next : for (int m = memberTypes.length; --m >= 0;) {
+ ReferenceBinding memberType = memberTypes[m];
+ // if (!wantClasses && memberType.isClass()) continue next;
+ // if (!wantInterfaces && memberType.isInterface()) continue next;
- if (!proposeStaticImport) {
- if (isAlreadyImported) {
- if (!isIgnored(CompletionProposal.METHOD_REF)) {
- completion = CharOperation.concat(receiverType.sourceName, completion, '.');
+ if (onlyStatic && !memberType.isStatic())
+ continue next;
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- proposal.setCompletion(completion);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ if (typeLength > memberType.sourceName.length)
+ continue next;
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
- completion = CharOperation.concat(receiverType.sourceName, completion, '.');
+ if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
+ continue next;
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- proposal.setCompletion(completion);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ if (this.options.checkDeprecation && memberType.isViewedAsDeprecated()) continue next;
- char[] typeImportCompletion = createImportCharArray(typeName, false, false);
+ if (this.options.checkVisibility
+ && !memberType.canBeSeenBy(this.unitScope.fPackage))
+ continue next;
- InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
- typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
- typeImportProposal.completionEngine = this;
- char[] packageName = receiverType.qualifiedPackageName();
- typeImportProposal.setDeclarationSignature(packageName);
- typeImportProposal.setSignature(getSignature(receiverType));
- typeImportProposal.setPackageName(packageName);
- typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
- typeImportProposal.setCompletion(typeImportCompletion);
- typeImportProposal.setFlags(receiverType.modifiers);
- typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
- typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
- typeImportProposal.setRelevance(relevance);
+ char[] completionName = CharOperation.concat(memberType.sourceName, SEMICOLON);
- proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- } else {
- if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(method.declaringClass));
- proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setName(method.selector);
- proposal.setCompletion(completion);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ if (memberType.isClass()) {
+ relevance += computeRelevanceForClass();
+ } else if(memberType.isEnum()) {
+ relevance += computeRelevanceForEnum();
+ } else if (memberType.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ }
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(
+ memberType,
+ memberType.qualifiedSourceName(),
+ IAccessRule.K_ACCESSIBLE,
+ completionName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
- char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
+ private void findImportsOfStaticFields(char[] fieldName, ReferenceBinding ref) {
+ FieldBinding[] fields = ref.availableFields();
- InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
- methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
- methodImportProposal.setSignature(getSignature(method));
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
- methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- methodImportProposal.setParameterPackageNames(parameterPackageNames);
- methodImportProposal.setParameterTypeNames(parameterTypeNames);
- methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
- methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
- methodImportProposal.setName(method.selector);
- methodImportProposal.setCompletion(methodImportCompletion);
- methodImportProposal.setFlags(method.modifiers);
- methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
- methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
- methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
- methodImportProposal.setRelevance(relevance);
- if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
+ int fieldLength = fieldName.length;
+ next : for (int m = fields.length; --m >= 0;) {
+ FieldBinding field = fields[m];
- proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
+ if (fieldLength > field.name.length)
+ continue next;
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
+ if (field.isSynthetic())
+ continue next;
- this.startPosition = previousStartPosition;
- this.tokenStart = previousTokenStart;
- }
- }
+ if (!field.isStatic())
+ continue next;
- private CompletionProposal createRequiredTypeProposal(Binding binding, int start, int end, int relevance) {
- InternalCompletionProposal proposal = null;
- if (binding instanceof ReferenceBinding) {
- ReferenceBinding typeBinding = (ReferenceBinding) binding;
+ if (!CharOperation.prefixEquals(fieldName, field.name, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(fieldName, field.name)))
+ continue next;
- char[] packageName = typeBinding.qualifiedPackageName();
- char[] typeName = typeBinding.qualifiedSourceName();
- char[] fullyQualifiedName = CharOperation.concat(packageName, typeName, '.');
+ if (this.options.checkDeprecation && field.isViewedAsDeprecated()) continue next;
- proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setDeclarationSignature(packageName);
- proposal.setSignature(getRequiredTypeSignature(typeBinding));
- proposal.setPackageName(packageName);
- proposal.setTypeName(typeName);
- proposal.setCompletion(fullyQualifiedName);
- proposal.setFlags(typeBinding.modifiers);
- proposal.setReplaceRange(start - this.offset, end - this.offset);
- proposal.setTokenRange(start - this.offset, end - this.offset);
- proposal.setRelevance(relevance);
- } else if (binding instanceof PackageBinding) {
- PackageBinding packageBinding = (PackageBinding) binding;
+ if (this.options.checkVisibility
+ && !field.canBeSeenBy(this.unitScope.fPackage))
+ continue next;
- char[] packageName = CharOperation.concatWith(packageBinding.compoundName, '.');
+ char[] completionName = CharOperation.concat(field.name, SEMICOLON);
- proposal = createProposal(CompletionProposal.PACKAGE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(packageName);
- proposal.setPackageName(packageName);
- proposal.setCompletion(packageName);
- proposal.setReplaceRange(start - this.offset, end - this.offset);
- proposal.setTokenRange(start - this.offset, end - this.offset);
- proposal.setRelevance(relevance);
- }
- return proposal;
- }
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(fieldName, field.name);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
- private void findLocalMethodsFromStaticImports(
- char[] methodName,
- MethodBinding[] methods,
- Scope scope,
- boolean exactMatch,
- ObjectVector methodsFound,
- ReferenceBinding receiverType,
- InvocationSite invocationSite) {
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.FIELD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(field.declaringClass));
+ proposal.setSignature(getSignature(field.type));
+ proposal.setDeclarationPackageName(field.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(field.declaringClass.qualifiedSourceName());
+ proposal.setPackageName(field.type.qualifiedPackageName());
+ proposal.setTypeName(field.type.qualifiedSourceName());
+ proposal.setName(field.name);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(field.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
- ObjectVector newMethodsFound = new ObjectVector();
+ private void findImportsOfStaticMethods(char[] methodName, ReferenceBinding ref) {
+ MethodBinding[] methods = ref.availableMethods();
- next : for (int f = methods.length; --f >= 0;) {
- MethodBinding method = methods[f];
+ int methodLength = methodName.length;
+ next : for (int m = methods.length; --m >= 0;) {
+ MethodBinding method = methods[m];
if (method.isSynthetic()) continue next;
@@ -6639,33 +6437,17 @@
if (!method.isStatic()) continue next;
- if (this.options.checkDeprecation &&
- method.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(method.declaringClass))
- continue next;
+ if (this.options.checkDeprecation && method.isViewedAsDeprecated()) continue next;
if (this.options.checkVisibility
- && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+ && !method.canBeSeenBy(this.unitScope.fPackage)) continue next;
- if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
+ if (methodLength > method.selector.length)
continue next;
- for (int i = methodsFound.size; --i >= 0;) {
- Object[] other = (Object[]) methodsFound.elementAt(i);
- MethodBinding otherMethod = (MethodBinding) other[0];
- ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
- if (method == otherMethod && receiverType == otherReceiverType)
- continue next;
-
- if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
- if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
- continue next;
- }
- }
- }
-
- newMethodsFound.add(new Object[]{method, receiverType});
+ if (!CharOperation.prefixEquals(methodName, method.selector, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
+ continue next;
int length = method.parameters.length;
char[][] parameterPackageNames = new char[length][];
@@ -6678,43 +6460,19 @@
}
char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
- char[] completion = CharOperation.NO_CHAR;
-
- int previousStartPosition = this.startPosition;
- int previousTokenStart = this.tokenStart;
-
- if (!exactMatch) {
- if (this.source != null
- && this.source.length > this.endPosition
- && this.source[this.endPosition] == '(') {
- completion = method.selector;
- } else {
- completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
- }
- } else {
- this.startPosition = this.endPosition;
- this.tokenStart = this.tokenEnd;
- }
+ char[] completionName = CharOperation.concat(method.selector, SEMICOLON);
int relevance = computeBaseRelevance();
relevance += computeRelevanceForResolution();
relevance += computeRelevanceForInterestingProposal();
relevance += computeRelevanceForCaseMatching(methodName, method.selector);
- relevance += computeRelevanceForExpectingType(method.returnType);
- relevance += computeRelevanceForEnumConstant(method.returnType);
- relevance += computeRelevanceForStatic(true, method.isStatic());
- relevance += computeRelevanceForQualification(false);
relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_NAME_REFERENCE)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_NAME_REFERENCE, this.actualCompletionPosition);
proposal.setDeclarationSignature(getSignature(method.declaringClass));
proposal.setSignature(getSignature(method));
- MethodBinding original = method.original();
- if(original != method) {
- proposal.setOriginalSignature(getSignature(original));
- }
proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
proposal.setParameterPackageNames(parameterPackageNames);
@@ -6722,7 +6480,7 @@
proposal.setPackageName(method.returnType.qualifiedPackageName());
proposal.setTypeName(method.returnType.qualifiedSourceName());
proposal.setName(method.selector);
- proposal.setCompletion(completion);
+ proposal.setCompletion(completionName);
proposal.setFlags(method.modifiers);
proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
@@ -6733,195 +6491,368 @@
this.printDebug(proposal);
}
}
- this.startPosition = previousStartPosition;
- this.tokenStart = previousTokenStart;
- }
-
- methodsFound.addAll(newMethodsFound);
- }
- int computeRelevanceForCaseMatching(char[] token, char[] proposalName){
- if (this.options.camelCaseMatch) {
- if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
- return R_CASE + R_EXACT_NAME;
- } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
- return R_CASE;
- } else if (CharOperation.camelCaseMatch(token, proposalName)){
- return R_CAMEL_CASE;
- } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
- return R_EXACT_NAME;
- }
- } else if (CharOperation.prefixEquals(token, proposalName, true /* do not ignore case */)) {
- if(CharOperation.equals(token, proposalName, true /* do not ignore case */)) {
- return R_CASE + R_EXACT_NAME;
- } else {
- return R_CASE;
- }
- } else if(CharOperation.equals(token, proposalName, false /* ignore case */)) {
- return R_EXACT_NAME;
- }
- return 0;
- }
- private int computeRelevanceForAnnotation(){
- if(this.assistNodeIsAnnotation) {
- return R_ANNOTATION;
}
- return 0;
}
- private int computeRelevanceForAnnotationTarget(TypeBinding typeBinding){
- if (this.assistNodeIsAnnotation &&
- (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
- long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
- if(target == 0 || (target & this.targetedElement) != 0) {
- return R_TARGET;
+
+ private void findInterfacesMethodDeclarations(
+ char[] selector,
+ ReferenceBinding receiverType,
+ ReferenceBinding[] itsInterfaces,
+ Scope scope,
+ ObjectVector methodsFound,
+ Binding[] missingElements,
+ int[] missingElementssStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
+
+ if (selector == null)
+ return;
+
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ ReferenceBinding[] interfacesToVisit = itsInterfaces;
+ int nextPosition = interfacesToVisit.length;
+
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding currentType = interfacesToVisit[i];
+ MethodBinding[] methods = currentType.availableMethods();
+ if(methods != null) {
+ findLocalMethodDeclarations(
+ selector,
+ methods,
+ scope,
+ methodsFound,
+ false,
+ receiverType);
+ }
+
+ itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
}
}
- return 0;
- }
- private int computeRelevanceForClass(){
- if(this.assistNodeIsClass) {
- return R_CLASS;
- }
- return 0;
- }
- private int computeRelevanceForEnum(){
- if(this.assistNodeIsEnum) {
- return R_ENUM;
- }
- return 0;
- }
- private int computeRelevanceForInterface(){
- if(this.assistNodeIsInterface) {
- return R_INTERFACE;
- }
- return 0;
- }
- private int computeRelevanceForMissingElements(boolean hasProblems) {
- if (!hasProblems) {
- return R_NO_PROBLEMS;
- }
- return 0;
}
- int computeRelevanceForQualification(boolean prefixRequired) {
- if(!prefixRequired && !this.insideQualifiedReference) {
- return R_UNQUALIFIED;
- }
+
+ private void findInterfacesMethods(
+ char[] selector,
+ TypeBinding[] typeArgTypes,
+ TypeBinding[] argTypes,
+ ReferenceBinding receiverType,
+ ReferenceBinding[] itsInterfaces,
+ Scope scope,
+ ObjectVector methodsFound,
+ boolean onlyStaticMethods,
+ boolean exactMatch,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean superCall,
+ boolean canBePrefixed,
+ Binding[] missingElements,
+ int[] missingElementssStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems,
+ char[] castedReceiver,
+ int receiverStart,
+ int receiverEnd) {
- if(prefixRequired && this.insideQualifiedReference) {
- return R_QUALIFIED;
+ if (selector == null)
+ return;
+
+ if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ ReferenceBinding[] interfacesToVisit = itsInterfaces;
+ int nextPosition = interfacesToVisit.length;
+
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding currentType = interfacesToVisit[i];
+ MethodBinding[] methods = currentType.availableMethods();
+ if(methods != null) {
+ findLocalMethods(
+ selector,
+ typeArgTypes,
+ argTypes,
+ methods,
+ scope,
+ methodsFound,
+ onlyStaticMethods,
+ exactMatch,
+ receiverType,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
+ canBePrefixed,
+ missingElements,
+ missingElementssStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+ }
+
+ itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
}
- return 0;
}
- int computeRelevanceForRestrictions(int accessRuleKind) {
- if(accessRuleKind == IAccessRule.K_ACCESSIBLE) {
- return R_NON_RESTRICTED;
+ /*
+ * Find javadoc block tags for a given completion javadoc tag node
+ */
+ private void findJavadocBlockTags(CompletionOnJavadocTag javadocTag) {
+ char[][] possibleTags = javadocTag.getPossibleBlockTags();
+ if (possibleTags == null) return;
+ int length = possibleTags.length;
+ for (int i=0; i') : argName;
+ proposal.setCompletion(completion);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(--relevance);
+ this.requestor.accept(proposal);
+ if (DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
}
}
- return 0;
}
- private int computeRelevanceForException(){
- if (this.assistNodeIsException) {
- return R_EXCEPTION;
- }
- return 0;
+
+ // what about onDemand types? Ignore them since it does not happen!
+ // import p1.p2.A.*;
+ private void findKeywords(char[] keyword, char[][] choices, boolean canCompleteEmptyToken, boolean staticFieldsAndMethodOnly) {
+ if(choices == null || choices.length == 0) return;
+
+ int length = keyword.length;
+ if (canCompleteEmptyToken || length > 0)
+ for (int i = 0; i < choices.length; i++)
+ if (length <= choices[i].length
+ && CharOperation.prefixEquals(keyword, choices[i], false /* ignore case */
+ )){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(keyword, choices[i]);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+ if (staticFieldsAndMethodOnly && this.insideQualifiedReference) relevance += R_NON_INHERITED;
+
+ if(CharOperation.equals(choices[i], Keywords.TRUE) || CharOperation.equals(choices[i], Keywords.FALSE)) {
+ relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
+ relevance += computeRelevanceForQualification(false);
+ }
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+ proposal.setName(choices[i]);
+ proposal.setCompletion(choices[i]);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
}
- private int computeRelevanceForException(char[] proposalName){
+ private void findKeywordsForMember(char[] token, int modifiers) {
+ char[][] keywords = new char[Keywords.COUNT][];
+ int count = 0;
- if((this.assistNodeIsException || (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) != 0 )&&
- (CharOperation.match(EXCEPTION_PATTERN, proposalName, false) ||
- CharOperation.match(ERROR_PATTERN, proposalName, false))) {
- return R_EXCEPTION;
+ // visibility
+ if((modifiers & ClassFileConstants.AccPrivate) == 0
+ && (modifiers & ClassFileConstants.AccProtected) == 0
+ && (modifiers & ClassFileConstants.AccPublic) == 0) {
+ keywords[count++] = Keywords.PROTECTED;
+ keywords[count++] = Keywords.PUBLIC;
+ if((modifiers & ClassFileConstants.AccAbstract) == 0) {
+ keywords[count++] = Keywords.PRIVATE;
+ }
}
- return 0;
- }
- private int computeRelevanceForExpectingType(TypeBinding proposalType){
- if(this.expectedTypes != null && proposalType != null) {
- int relevance = 0;
- for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if((this.expectedTypesFilter & SUBTYPE) != 0
- && proposalType.isCompatibleWith(this.expectedTypes[i])) {
- if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
- CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
- return R_EXACT_EXPECTED_TYPE;
- }
+ if((modifiers & ClassFileConstants.AccAbstract) == 0) {
+ // abtract
+ if((modifiers & ~(ExtraCompilerModifiers.AccVisibilityMASK | ClassFileConstants.AccStatic)) == 0) {
+ keywords[count++] = Keywords.ABSTRACT;
+ }
- relevance = R_EXPECTED_TYPE;
- }
- if((this.expectedTypesFilter & SUPERTYPE) != 0
- && this.expectedTypes[i].isCompatibleWith(proposalType)) {
+ // final
+ if((modifiers & ClassFileConstants.AccFinal) == 0) {
+ keywords[count++] = Keywords.FINAL;
+ }
- if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), proposalType.qualifiedPackageName()) &&
- CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), proposalType.qualifiedSourceName())) {
- return R_EXACT_EXPECTED_TYPE;
- }
+ // static
+ if((modifiers & ClassFileConstants.AccStatic) == 0) {
+ keywords[count++] = Keywords.STATIC;
+ }
- relevance = R_EXPECTED_TYPE;
+ boolean canBeField = true;
+ boolean canBeMethod = true;
+ boolean canBeType = true;
+ if((modifiers & ClassFileConstants.AccNative) != 0
+ || (modifiers & ClassFileConstants.AccStrictfp) != 0
+ || (modifiers & ClassFileConstants.AccSynchronized) != 0) {
+ canBeField = false;
+ canBeType = false;
+ }
+
+ if((modifiers & ClassFileConstants.AccTransient) != 0
+ || (modifiers & ClassFileConstants.AccVolatile) != 0) {
+ canBeMethod = false;
+ canBeType = false;
+ }
+
+ if(canBeField) {
+ // transient
+ if((modifiers & ClassFileConstants.AccTransient) == 0) {
+ keywords[count++] = Keywords.TRANSIENT;
+ }
+
+ // volatile
+ if((modifiers & ClassFileConstants.AccVolatile) == 0) {
+ keywords[count++] = Keywords.VOLATILE;
}
}
- return relevance;
- }
- return 0;
- }
- private int computeRelevanceForExpectingType(char[] packageName, char[] typeName){
- if(this.expectedTypes != null) {
- for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if(CharOperation.equals(this.expectedTypes[i].qualifiedPackageName(), packageName) &&
- CharOperation.equals(this.expectedTypes[i].qualifiedSourceName(), typeName)) {
- return R_EXACT_EXPECTED_TYPE;
+
+ if(canBeMethod) {
+ // native
+ if((modifiers & ClassFileConstants.AccNative) == 0) {
+ keywords[count++] = Keywords.NATIVE;
+ }
+
+ // strictfp
+ if((modifiers & ClassFileConstants.AccStrictfp) == 0) {
+ keywords[count++] = Keywords.STRICTFP;
+ }
+
+ // synchronized
+ if((modifiers & ClassFileConstants.AccSynchronized) == 0) {
+ keywords[count++] = Keywords.SYNCHRONIZED;
}
}
- if(this.hasJavaLangObjectAsExpectedType) {
- return R_EXPECTED_TYPE;
- }
- }
- return 0;
- }
- private int computeRelevanceForInheritance(ReferenceBinding receiverType, ReferenceBinding declaringClass) {
- if (receiverType == declaringClass) return R_NON_INHERITED;
- return 0;
- }
+ if(canBeType) {
+ keywords[count++] = Keywords.CLASS;
+ keywords[count++] = Keywords.INTERFACE;
- int computeRelevanceForInterestingProposal(){
- return computeRelevanceForInterestingProposal(null);
- }
- private int computeRelevanceForInterestingProposal(Binding binding){
- if(this.uninterestingBindings != null) {
- for (int i = 0; i <= this.uninterestingBindingsPtr; i++) {
- if(this.uninterestingBindings[i] == binding) {
- return 0;
+ if((modifiers & ClassFileConstants.AccFinal) == 0) {
+ keywords[count++] = Keywords.ENUM;
}
}
+ } else {
+ // class
+ keywords[count++] = Keywords.CLASS;
+ keywords[count++] = Keywords.INTERFACE;
}
- return R_INTERESTING;
- }
- private void computeUninterestingBindings(ASTNode parent, Scope scope){
- if(parent instanceof LocalDeclaration) {
- addUninterestingBindings(((LocalDeclaration)parent).binding);
- } else if (parent instanceof FieldDeclaration) {
- addUninterestingBindings(((FieldDeclaration)parent).binding);
- }
- }
+ System.arraycopy(keywords, 0, keywords = new char[count][], 0, count);
+ findKeywords(token, keywords, false, false);
+ }
private void findLabels(char[] label, char[][] choices) {
if(choices == null || choices.length == 0) return;
@@ -7068,245 +6999,38 @@
}
proposal.setKey(method.computeUniqueKey());
proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
- proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
- proposal.setParameterPackageNames(parameterPackageNames);
- proposal.setParameterTypeNames(parameterFullTypeNames);
- proposal.setPackageName(method.returnType.qualifiedPackageName());
- proposal.setTypeName(method.returnType.qualifiedSourceName());
- proposal.setCompletion(completion.toString().toCharArray());
- proposal.setName(method.selector);
- proposal.setFlags(method.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- if(parameterNames != null) proposal.setParameterNames(parameterNames);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- methodsFound.addAll(newMethodsFound);
- }
-
- private void createTypeVariable(TypeVariableBinding typeVariable, Scope scope, StringBuffer completion) {
- completion.append(typeVariable.sourceName);
-
- if (typeVariable.superclass != null && typeVariable.firstBound == typeVariable.superclass) {
- completion.append(' ');
- completion.append(EXTENDS);
- completion.append(' ');
- createType(typeVariable.superclass, scope, completion);
- }
- if (typeVariable.superInterfaces != null && typeVariable.superInterfaces != Binding.NO_SUPERINTERFACES) {
- if (typeVariable.firstBound != typeVariable.superclass) {
- completion.append(' ');
- completion.append(EXTENDS);
- completion.append(' ');
- }
- for (int i = 0, length = typeVariable.superInterfaces.length; i < length; i++) {
- if (i > 0 || typeVariable.firstBound == typeVariable.superclass) {
- completion.append(' ');
- completion.append(EXTENDS);
- completion.append(' ');
- }
- createType(typeVariable.superInterfaces[i], scope, completion);
- }
- }
- }
-
- private void createType(TypeBinding type, Scope scope, StringBuffer completion) {
- switch (type.kind()) {
- case Binding.BASE_TYPE :
- completion.append(type.sourceName());
- break;
- case Binding.WILDCARD_TYPE :
- case Binding.INTERSECTION_TYPE : // TODO (david) need to handle intersection type specifically
- WildcardBinding wildcardBinding = (WildcardBinding) type;
- completion.append('?');
- switch (wildcardBinding.boundKind) {
- case Wildcard.EXTENDS:
- completion.append(' ');
- completion.append(EXTENDS);
- completion.append(' ');
- createType(wildcardBinding.bound, scope, completion);
- if(wildcardBinding.otherBounds != null) {
-
- int length = wildcardBinding.otherBounds.length;
- for (int i = 0; i < length; i++) {
- completion.append(' ');
- completion.append('&');
- completion.append(' ');
- createType(wildcardBinding.otherBounds[i], scope, completion);
- }
- }
- break;
- case Wildcard.SUPER:
- completion.append(' ');
- completion.append(SUPER);
- completion.append(' ');
- createType(wildcardBinding.bound, scope, completion);
- break;
- }
- break;
- case Binding.ARRAY_TYPE :
- createType(type.leafComponentType(), scope, completion);
- int dim = type.dimensions();
- for (int i = 0; i < dim; i++) {
- completion.append('[');
- completion.append(']');
- }
- break;
- case Binding.PARAMETERIZED_TYPE :
- ParameterizedTypeBinding parameterizedType = (ParameterizedTypeBinding) type;
- if (type.isMemberType()) {
- createType(parameterizedType.enclosingType(), scope, completion);
- completion.append('.');
- completion.append(parameterizedType.sourceName);
- } else {
- completion.append(CharOperation.concatWith(parameterizedType.genericType().compoundName, '.'));
- }
- if (parameterizedType.arguments != null) {
- completion.append('<');
- for (int i = 0, length = parameterizedType.arguments.length; i < length; i++) {
- if (i != 0) completion.append(',');
- createType(parameterizedType.arguments[i], scope, completion);
- }
- completion.append('>');
- }
- break;
- default :
- char[] packageName = type.qualifiedPackageName();
- char[] typeName = type.qualifiedSourceName();
- if(mustQualifyType(
- (ReferenceBinding)type,
- packageName,
- scope)) {
- completion.append(CharOperation.concat(packageName, typeName,'.'));
- } else {
- completion.append(type.sourceName());
- }
- break;
- }
- }
-
- private void createVargsType(TypeBinding type, Scope scope, StringBuffer completion) {
- if (type.isArrayType()) {
- createType(type.leafComponentType(), scope, completion);
- int dim = type.dimensions() - 1;
- for (int i = 0; i < dim; i++) {
- completion.append('[');
- completion.append(']');
- }
- completion.append(VARARGS);
- } else {
- createType(type, scope, completion);
- }
- }
- private char[] createImportCharArray(char[] importedElement, boolean isStatic, boolean onDemand) {
- char[] result = IMPORT;
- if (isStatic) {
- result = CharOperation.concat(result, STATIC, ' ');
- }
- result = CharOperation.concat(result, importedElement, ' ');
- if (onDemand) {
- result = CharOperation.concat(result, ON_DEMAND);
- }
- return CharOperation.concat(result, IMPORT_END);
- }
- private void createMethod(MethodBinding method, char[][] parameterPackageNames, char[][] parameterTypeNames, char[][] parameterNames, Scope scope, StringBuffer completion) {
- //// Modifiers
- // flush uninteresting modifiers
- int insertedModifiers = method.modifiers & ~(ClassFileConstants.AccNative | ClassFileConstants.AccAbstract);
- if(insertedModifiers != ClassFileConstants.AccDefault){
- ASTNode.printModifiers(insertedModifiers, completion);
- }
-
- //// Type parameters
-
- TypeVariableBinding[] typeVariableBindings = method.typeVariables;
- if(typeVariableBindings != null && typeVariableBindings.length != 0) {
- completion.append('<');
- for (int i = 0; i < typeVariableBindings.length; i++) {
- if(i != 0) {
- completion.append(',');
- completion.append(' ');
- }
- createTypeVariable(typeVariableBindings[i], scope, completion);
- }
- completion.append('>');
- completion.append(' ');
- }
-
- //// Return type
- createType(method.returnType, scope, completion);
- completion.append(' ');
-
- //// Selector
- completion.append(method.selector);
-
- completion.append('(');
-
- ////Parameters
- TypeBinding[] parameterTypes = method.parameters;
- int length = parameterTypes.length;
- for (int i = 0; i < length; i++) {
- if(i != 0) {
- completion.append(',');
- completion.append(' ');
- }
- createType(parameterTypes[i], scope, completion);
- completion.append(' ');
- if(parameterNames != null){
- completion.append(parameterNames[i]);
- } else {
- completion.append('%');
- }
- }
-
- completion.append(')');
-
- //// Exceptions
- ReferenceBinding[] exceptions = method.thrownExceptions;
-
- if (exceptions != null && exceptions.length > 0){
- completion.append(' ');
- completion.append(THROWS);
- completion.append(' ');
- for(int i = 0; i < exceptions.length ; i++){
- if(i != 0) {
- completion.append(' ');
- completion.append(',');
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterFullTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setCompletion(completion.toString().toCharArray());
+ proposal.setName(method.selector);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
- createType(exceptions[i], scope, completion);
}
}
+ methodsFound.addAll(newMethodsFound);
}
- private boolean isIgnored(int kind, boolean missingTypes) {
- return this.requestor.isIgnored(kind) ||
- (missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
- }
-
- private boolean isIgnored(int kind) {
- return this.requestor.isIgnored(kind);
- }
-
- private boolean isIgnored(int kind, int requiredProposalKind) {
- return this.requestor.isIgnored(kind) ||
- !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
- }
-
- private void findMethods(
- char[] selector,
+ // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+ private void findLocalMethods(
+ char[] methodName,
TypeBinding[] typeArgTypes,
TypeBinding[] argTypes,
- ReferenceBinding receiverType,
+ MethodBinding[] methods,
Scope scope,
ObjectVector methodsFound,
boolean onlyStaticMethods,
boolean exactMatch,
- boolean isCompletingDeclaration,
+ ReferenceBinding receiverType,
InvocationSite invocationSite,
Scope invocationScope,
boolean implicitCall,
@@ -7320,2703 +7044,3277 @@
int receiverStart,
int receiverEnd) {
- boolean notInJavadoc = this.assistNodeInJavadoc == 0;
- if (selector == null && notInJavadoc) {
- return;
- }
+ ObjectVector newMethodsFound = new ObjectVector();
+ // Inherited methods which are hidden by subclasses are filtered out
+ // No visibility checks can be performed without the scope & invocationSite
- if(isCompletingDeclaration) {
- MethodBinding[] methods = receiverType.availableMethods();
- if (methods != null){
- for (int i = 0; i < methods.length; i++) {
- if(!methods[i].isDefaultAbstract()) {
- methodsFound.add(methods[i]);
- }
- }
+ int methodLength = methodName.length;
+ int minTypeArgLength = typeArgTypes == null ? 0 : typeArgTypes.length;
+ int minArgLength = argTypes == null ? 0 : argTypes.length;
+
+ next : for (int f = methods.length; --f >= 0;) {
+ MethodBinding method = methods[f];
+
+ if (method.isSynthetic()) continue next;
+
+ if (method.isDefaultAbstract()) continue next;
+
+ if (method.isConstructor()) continue next;
+
+ if (this.options.checkDeprecation &&
+ method.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(method.declaringClass))
+ continue next;
+
+ //TODO (david) perhaps the relevance of a void method must be lesser than other methods
+ //if (expectedTypesPtr > -1 && method.returnType == BaseTypes.VoidBinding) continue next;
+
+ if (onlyStaticMethods && !method.isStatic()) continue next;
+
+ if (this.options.checkVisibility
+ && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
+
+ if(superCall && method.isAbstract()) {
+ methodsFound.add(new Object[]{method, receiverType});
+ continue next;
}
- }
- ReferenceBinding currentType = receiverType;
- if (notInJavadoc) {
- if (receiverType.isInterface()) {
- if (isCompletingDeclaration) {
- findInterfacesMethods(
- selector,
- typeArgTypes,
- argTypes,
- receiverType,
- currentType.superInterfaces(),
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- } else {
- findInterfacesMethods(
- selector,
- typeArgTypes,
- argTypes,
- receiverType,
- new ReferenceBinding[]{currentType},
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
+ if (exactMatch) {
+ if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)) {
+ continue next;
}
-
- currentType = scope.getJavaLangObject();
} else {
- if (isCompletingDeclaration){
- findInterfacesMethods(
- selector,
- typeArgTypes,
- argTypes,
- receiverType,
- currentType.superInterfaces(),
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
-
- currentType = receiverType.superclass();
+ if (methodLength > method.selector.length) continue next;
+ if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
+ continue next;
}
}
- }
- boolean hasPotentialDefaultAbstractMethods = true;
- while (currentType != null) {
- MethodBinding[] methods = currentType.availableMethods();
- if (methods != null) {
- if (isCompletingDeclaration){
- findLocalMethodDeclarations(
- selector,
- methods,
- scope,
- methodsFound,
- exactMatch,
- receiverType);
- } else{
- findLocalMethods(
- selector,
- typeArgTypes,
- argTypes,
- methods,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- receiverType,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- }
+ if (minTypeArgLength != 0 && minTypeArgLength != method.typeVariables.length)
+ continue next;
+
+ if (minTypeArgLength != 0) {
+ method = scope.environment().createParameterizedGenericMethod(method, typeArgTypes);
}
- if (hasPotentialDefaultAbstractMethods &&
- (currentType.isAbstract() ||
- currentType.isTypeVariable() ||
- currentType.isIntersectionType() ||
- currentType.isEnum())){
+ if (minArgLength > method.parameters.length)
+ continue next;
- ReferenceBinding[] superInterfaces = currentType.superInterfaces();
- if (superInterfaces != null && currentType.isIntersectionType()) {
- for (int i = 0; i < superInterfaces.length; i++) {
- superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
+ for (int a = minArgLength; --a >= 0;){
+ if (argTypes[a] != null) { // can be null if it could not be resolved properly
+ if (!argTypes[a].isCompatibleWith(method.parameters[a])) {
+ continue next;
}
}
+ }
- findInterfacesMethods(
- selector,
- typeArgTypes,
- argTypes,
- receiverType,
- superInterfaces,
- scope,
- methodsFound,
- onlyStaticMethods,
- exactMatch,
- isCompletingDeclaration,
- invocationSite,
- invocationScope,
- implicitCall,
- superCall,
- canBePrefixed,
- missingElements,
- missingElementsStarts,
- missingElementsEnds,
- missingElementsHaveProblems,
- castedReceiver,
- receiverStart,
- receiverEnd);
- } else {
- hasPotentialDefaultAbstractMethods = false;
+ boolean prefixRequired = false;
+
+ for (int i = methodsFound.size; --i >= 0;) {
+ Object[] other = (Object[]) methodsFound.elementAt(i);
+ MethodBinding otherMethod = (MethodBinding) other[0];
+ ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+ if (method == otherMethod && receiverType == otherReceiverType)
+ continue next;
+
+ if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+ if (receiverType == otherReceiverType) {
+ if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+ if (!superCall || !otherMethod.declaringClass.isInterface()) {
+ continue next;
+ }
+ }
+ } else {
+ if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+ if(receiverType.isAnonymousType()) continue next;
+
+ if(!superCall) {
+ if(!canBePrefixed) continue next;
+
+ prefixRequired = true;
+ }
+ }
+ }
+ }
}
- currentType = currentType.superclass();
- }
- }
- private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
- TypeBinding erasure = method.declaringClass.erasure();
- if(!(erasure instanceof ReferenceBinding)) return null;
- char[][] parameterNames = null;
+ newMethodsFound.add(new Object[]{method, receiverType});
- int length = parameterTypeNames.length;
+ ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
+ if (method.declaringClass != superTypeWithSameErasure) {
+ MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
+ for (int i = 0; i < otherMethods.length; i++) {
+ if(otherMethods[i].original() == method.original()) {
+ method = otherMethods[i];
+ }
+ }
+ }
- if (length == 0){
- return CharOperation.NO_CHAR_CHAR;
- }
- // look into the corresponding unit if it is available
- if (erasure instanceof SourceTypeBinding){
- SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
+ int length = method.parameters.length;
+ char[][] parameterPackageNames = new char[length][];
+ char[][] parameterTypeNames = new char[length][];
- if (sourceType.scope != null){
- TypeDeclaration parsedType;
+ for (int i = 0; i < length; i++) {
+ TypeBinding type = method.original().parameters[i];
+ parameterPackageNames[i] = type.qualifiedPackageName();
+ parameterTypeNames[i] = type.qualifiedSourceName();
+ }
+ char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
- if ((parsedType = sourceType.scope.referenceContext) != null){
- AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
+ char[] completion = CharOperation.NO_CHAR;
- if (methodDecl != null){
- Argument[] arguments = methodDecl.arguments;
- parameterNames = new char[length][];
+ int previousStartPosition = this.startPosition;
+ int previousTokenStart = this.tokenStart;
- for(int i = 0 ; i < length ; i++){
- parameterNames[i] = arguments[i].name;
+ // Special case for completion in javadoc
+ if (this.assistNodeInJavadoc > 0) {
+ Expression receiver = null;
+ if (invocationSite instanceof CompletionOnJavadocMessageSend) {
+ CompletionOnJavadocMessageSend msg = (CompletionOnJavadocMessageSend) invocationSite;
+ receiver = msg.receiver;
+ } else if (invocationSite instanceof CompletionOnJavadocFieldReference) {
+ CompletionOnJavadocFieldReference fieldRef = (CompletionOnJavadocFieldReference) invocationSite;
+ receiver = fieldRef.receiver;
+ }
+ if (receiver != null) {
+ StringBuffer javadocCompletion = new StringBuffer();
+ if (receiver.isThis()) {
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+ javadocCompletion.append('#');
+ }
+ } else if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0) {
+ if (receiver instanceof JavadocSingleTypeReference) {
+ JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) receiver;
+ javadocCompletion.append(typeRef.token);
+ javadocCompletion.append('#');
+ } else if (receiver instanceof JavadocQualifiedTypeReference) {
+ JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) receiver;
+ completion = CharOperation.concat(CharOperation.concatWith(typeRef.tokens, '.'), method.selector, '#');
+ for (int t=0,nt =typeRef.tokens.length; t0) javadocCompletion.append('.');
+ javadocCompletion.append(typeRef.tokens[t]);
+ }
+ javadocCompletion.append('#');
+ }
+ }
+ javadocCompletion.append(method.selector);
+ // Append parameters types
+ javadocCompletion.append('(');
+ if (method.parameters != null) {
+ boolean isVarargs = method.isVarargs();
+ for (int p=0, ln=method.parameters.length; p0) javadocCompletion.append(", "); //$NON-NLS-1$
+ TypeBinding argTypeBinding = method.parameters[p];
+ if (isVarargs && p == ln - 1) {
+ createVargsType(argTypeBinding.erasure(), scope, javadocCompletion);
+ } else {
+ createType(argTypeBinding.erasure(), scope,javadocCompletion);
+ }
}
}
+ javadocCompletion.append(')');
+ completion = javadocCompletion.toString().toCharArray();
}
- }
- }
- // look into the model
- if(parameterNames == null){
-
- ReferenceBinding bindingType = (ReferenceBinding)erasure;
-
- char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
- Object type = this.typeCache.get(compoundName);
+ } else {
+ // nothing to insert - do not want to replace the existing selector & arguments
+ if (!exactMatch) {
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(')
+ completion = method.selector;
+ else
+ completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
- ISourceType sourceType = null;
- if(type != null) {
- if(type instanceof ISourceType) {
- sourceType = (ISourceType) type;
+ if (castedReceiver != null) {
+ completion = CharOperation.concat(castedReceiver, completion);
+ }
+ } else {
+ if(prefixRequired && (this.source != null)) {
+ completion = CharOperation.subarray(this.source, this.startPosition, this.endPosition);
+ } else {
+ this.startPosition = this.endPosition;
+ }
+ this.tokenStart = this.tokenEnd;
}
- } else {
- NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
- if(answer != null && answer.isSourceType()) {
- sourceType = answer.getSourceTypes()[0];
- this.typeCache.put(compoundName, sourceType);
+
+ if(prefixRequired || this.options.forceImplicitQualification){
+ char[] prefix = computePrefix(scope.enclosingSourceType(), invocationScope.enclosingSourceType(), method.isStatic());
+ completion = CharOperation.concat(prefix,completion,'.');
}
}
- if(sourceType != null) {
- IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+ relevance += computeRelevanceForExpectingType(method.returnType);
+ relevance += computeRelevanceForEnumConstant(method.returnType);
+ relevance += computeRelevanceForStatic(onlyStaticMethods, method.isStatic());
+ relevance += computeRelevanceForQualification(prefixRequired);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ if (onlyStaticMethods && this.insideQualifiedReference) {
+ relevance += computeRelevanceForInheritance(receiverType, method.declaringClass);
+ }
+ if (missingElements != null) {
+ relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+ }
- String[] parameterTypeSignatures = new String[length];
- for (int i = 0; i < length; i++) {
- parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
+ this.noProposal = false;
+
+ if (castedReceiver == null) {
+ // Standard proposal
+ if(!this.isIgnored(CompletionProposal.METHOD_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
+ }
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
- IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
- IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
- if(foundMethods != null) {
- int len = foundMethods.length;
- if(len == 1) {
- try {
- SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
- parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
- } catch (JavaModelException e) {
- // method doesn't exist: ignore
+ // Javadoc proposal
+ if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_METHOD_REF)) {
+ char[] javadocCompletion = inlineTagCompletion(completion, JavadocTagConstants.TAG_LINK);
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.JAVADOC_METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ proposal.setCompletion(javadocCompletion);
+ proposal.setFlags(method.modifiers);
+ int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
+ proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance+R_INLINE_TAG);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ if(!this.isIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, missingElements != null)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setReceiverSignature(getSignature(receiverType));
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ if (missingElements != null) {
+ CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
+ for (int i = 0; i < missingElements.length; i++) {
+ subProposals[i] =
+ createRequiredTypeProposal(
+ missingElements[i],
+ missingElementsStarts[i],
+ missingElementsEnds[i],
+ relevance);
}
+ proposal.setRequiredProposals(subProposals);
+ }
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setReceiverRange(receiverStart - this.offset, receiverEnd - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
}
}
+ this.startPosition = previousStartPosition;
+ this.tokenStart = previousTokenStart;
}
- return parameterNames;
+
+ methodsFound.addAll(newMethodsFound);
}
+ private void findLocalMethodsFromFavorites(
+ char[] methodName,
+ MethodBinding[] methods,
+ Scope scope,
+ ObjectVector methodsFound,
+ ObjectVector methodsFoundFromFavorites,
+ ReferenceBinding receiverType,
+ InvocationSite invocationSite,
+ Scope invocationScope) {
- private void findNestedTypes(
- char[] typeName,
- SourceTypeBinding currentType,
- Scope scope,
- boolean proposeAllMemberTypes,
- ObjectVector typesFound) {
- if (typeName == null)
- return;
+ char[] typeName = CharOperation.concatWith(receiverType.compoundName, '.');
- int typeLength = typeName.length;
+ int methodLength = methodName.length;
- SourceTypeBinding nextTypeToIgnore = null;
- while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+ next : for (int f = methods.length; --f >= 0;) {
+ MethodBinding method = methods[f];
- switch (scope.kind) {
+ if (method.isSynthetic()) continue next;
- case Scope.METHOD_SCOPE :
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) scope;
+ if (method.isDefaultAbstract()) continue next;
- next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
+ if (method.isConstructor()) continue next;
- if (blockScope.subscopes[i] instanceof ClassScope) {
- SourceTypeBinding localType =
- ((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
+ if (this.options.checkDeprecation &&
+ method.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(method.declaringClass))
+ continue next;
- if (!localType.isAnonymousType()) {
- if (isForbidden(localType))
- continue next;
+ if (!method.isStatic()) continue next;
- if (typeLength > localType.sourceName.length)
- continue next;
- if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
- continue next;
+ if (this.options.checkVisibility
+ && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
- for (int j = typesFound.size; --j >= 0;) {
- ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+ if (methodLength > method.selector.length) continue next;
- if (localType == otherType)
- continue next;
- }
+ if (!CharOperation.prefixEquals(methodName, method.selector, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector))) {
+ continue next;
+ }
- if(this.assistNodeIsClass) {
- if(!localType.isClass()) continue next;
- } else if(this.assistNodeIsInterface) {
- if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
- } else if (this.assistNodeIsAnnotation) {
- if(!localType.isAnnotationType()) continue next;
- }
+ for (int i = methodsFoundFromFavorites.size; --i >= 0;) {
+ Object[] other = (Object[]) methodsFoundFromFavorites.elementAt(i);
+ MethodBinding otherMethod = (MethodBinding) other[0];
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
- relevance += computeRelevanceForExpectingType(localType);
- relevance += computeRelevanceForException(localType.sourceName);
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
- relevance += computeRelevanceForAnnotationTarget(localType);
+ if (method == otherMethod) continue next;
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(
- localType,
- localType.sourceName,
- IAccessRule.K_ACCESSIBLE,
- localType.sourceName,
- relevance,
- null,
- null,
- null,
- false);
- }
- }
+ if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+ if (otherMethod.declaringClass == method.declaringClass &&
+ this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+ continue next;
}
}
- break;
-
- case Scope.CLASS_SCOPE :
- SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
- findMemberTypes(
- typeName,
- enclosingSourceType,
- scope,
- currentType,
- false,
- false,
- false,
- false,
- proposeAllMemberTypes,
- nextTypeToIgnore,
- typesFound,
- null,
- null,
- null,
- false);
- nextTypeToIgnore = enclosingSourceType;
- if (typeLength == 0)
- return; // do not search outside the class scope if no prefix was provided
- break;
-
- case Scope.COMPILATION_UNIT_SCOPE :
- return;
- }
- scope = scope.parent;
- }
- }
-
- private void findPackages(CompletionOnPackageReference packageStatement) {
-
- this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
- if (this.completionToken.length == 0)
- return;
-
- setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
- long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
- setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
- this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
- }
-
- private void findParameterizedType(TypeReference ref, Scope scope) {
- ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
- if(refBinding != null) {
- if (this.options.checkDeprecation &&
- refBinding.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(refBinding))
- return;
-
- int accessibility = IAccessRule.K_ACCESSIBLE;
- if(refBinding.hasRestrictedAccess()) {
- AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
- if(accessRestriction != null) {
- switch (accessRestriction.getProblemId()) {
- case IProblem.ForbiddenReference:
- if (this.options.checkForbiddenReference) {
- return;
- }
- accessibility = IAccessRule.K_NON_ACCESSIBLE;
- break;
- case IProblem.DiscouragedReference:
- if (this.options.checkDiscouragedReference) {
- return;
- }
- accessibility = IAccessRule.K_DISCOURAGED;
- break;
- }
}
- }
-
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
- relevance += computeRelevanceForExpectingType(refBinding);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
-
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeProposal(
- refBinding,
- refBinding.qualifiedSourceName(),
- IAccessRule.K_ACCESSIBLE,
- CharOperation.NO_CHAR,
- relevance,
- null,
- null,
- null,
- false);
- }
- }
- }
- private void findTypeParameters(char[] token, Scope scope) {
- if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
-
- TypeParameter[] typeParameters = null;
- while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
- typeParameters = null;
- switch (scope.kind) {
- case Scope.METHOD_SCOPE :
- MethodScope methodScope = (MethodScope) scope;
- if(methodScope.referenceContext instanceof MethodDeclaration) {
- MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
- typeParameters = methodDeclaration.typeParameters;
- } else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
- ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
- typeParameters = methodDeclaration.typeParameters;
- }
- break;
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) scope;
- typeParameters = classScope.referenceContext.typeParameters;
- break;
- case Scope.COMPILATION_UNIT_SCOPE :
- return;
- }
- if(typeParameters != null) {
- for (int i = 0; i < typeParameters.length; i++) {
- int typeLength = token.length;
- TypeParameter typeParameter = typeParameters[i];
- if(typeParameter.binding == null) continue;
+ for (int i = methodsFound.size; --i >= 0;) {
+ Object[] other = (Object[]) methodsFound.elementAt(i);
+ MethodBinding otherMethod = (MethodBinding) other[0];
- if (typeLength > typeParameter.name.length) continue;
+ if (method == otherMethod) continue next;
- if (!CharOperation.prefixEquals(token, typeParameter.name, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
+ if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+ if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+ continue next;
+ }
+ }
+ }
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
- relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForException(typeParameter.name);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
+ boolean proposeStaticImport = !(this.compilerOptions.complianceLevel < ClassFileConstants.JDK1_5) &&
+ this.options.suggestStaticImport;
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- createTypeParameterProposal(typeParameter, relevance);
+ boolean isAlreadyImported = false;
+ if (!proposeStaticImport) {
+ if(!this.importCachesInitialized) {
+ initializeImportCaches();
+ }
+ for (int j = 0; j < this.importCacheCount; j++) {
+ char[][] importName = this.importsCache[j];
+ if(CharOperation.equals(receiverType.sourceName, importName[0])) {
+ if (!CharOperation.equals(typeName, importName[1])) {
+ continue next;
+ } else {
+ isAlreadyImported = true;
+ }
+ }
}
}
- }
- scope = scope.parent;
- }
- }
- private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
- if (token == null)
- return;
+ methodsFoundFromFavorites.add(new Object[]{method, receiverType});
- // do not propose type if completion token is empty
- boolean skip = false;
- if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
- if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
- return;
- }
- skip = true;
- }
+ ReferenceBinding superTypeWithSameErasure = (ReferenceBinding)receiverType.findSuperTypeOriginatingFrom(method.declaringClass);
+ if (method.declaringClass != superTypeWithSameErasure) {
+ MethodBinding[] otherMethods = superTypeWithSameErasure.getMethods(method.selector);
+ for (int i = 0; i < otherMethods.length; i++) {
+ if(otherMethods[i].original() == method.original()) {
+ method = otherMethods[i];
+ }
+ }
+ }
- boolean proposeType =
- !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
- ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
+ int length = method.parameters.length;
+ char[][] parameterPackageNames = new char[length][];
+ char[][] parameterTypeNames = new char[length][];
- boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
+ for (int i = 0; i < length; i++) {
+ TypeBinding type = method.original().parameters[i];
+ parameterPackageNames[i] = type.qualifiedPackageName();
+ parameterTypeNames[i] = type.qualifiedSourceName();
+ }
+ char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
- if (!skip && proposeType && scope.enclosingSourceType() != null) {
- findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
- if(!this.assistNodeIsInterface &&
- !this.assistNodeIsConstructor &&
- !this.assistNodeIsAnnotation &&
- this.assistNodeInJavadoc == 0) {
- // don't propose type parameters if the completion is a constructor ('new |')
- findTypeParameters(token, scope);
- }
- }
+ char[] completion = CharOperation.NO_CHAR;
- boolean isEmptyPrefix = token.length == 0;
+ int previousStartPosition = this.startPosition;
+ int previousTokenStart = this.tokenStart;
- if (!skip && proposeType && this.unitScope != null) {
- ReferenceBinding outerInvocationType = scope.enclosingSourceType();
- if(outerInvocationType != null) {
- ReferenceBinding temp = outerInvocationType.enclosingType();
- while(temp != null) {
- outerInvocationType = temp;
- temp = temp.enclosingType();
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = method.selector;
+ } else {
+ completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
}
- }
- int typeLength = token.length;
- SourceTypeBinding[] types = this.unitScope.topLevelTypes;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ if (methodName != null) relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+ relevance += computeRelevanceForExpectingType(method.returnType);
+ relevance += computeRelevanceForEnumConstant(method.returnType);
+ relevance += computeRelevanceForStatic(true, method.isStatic());
+ relevance += computeRelevanceForQualification(true);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- next : for (int i = 0, length = types.length; i < length; i++) {
- SourceTypeBinding sourceType = types[i];
+ CompilationUnitDeclaration cu = this.unitScope.referenceContext;
+ int importStart = cu.types[0].declarationSourceStart;
+ int importEnd = importStart;
- if(isForbidden(sourceType)) continue next;
+ this.noProposal = false;
- if(proposeAllMemberTypes &&
- sourceType != outerInvocationType) {
- findSubMemberTypes(
- token,
- sourceType,
- scope,
- scope.enclosingSourceType(),
- false,
- false,
- false,
- typesFound);
- }
+ if (!proposeStaticImport) {
+ if (isAlreadyImported) {
+ if (!isIgnored(CompletionProposal.METHOD_REF)) {
+ completion = CharOperation.concat(receiverType.sourceName, completion, '.');
- if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
- if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
- if (typeLength > sourceType.sourceName.length) continue next;
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.TYPE_IMPORT)) {
+ completion = CharOperation.concat(receiverType.sourceName, completion, '.');
- if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
- if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
- continue next;
- }
+ char[] typeImportCompletion = createImportCharArray(typeName, false, false);
- for (int j = typesFound.size; --j >= 0;) {
- ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+ InternalCompletionProposal typeImportProposal = createProposal(CompletionProposal.TYPE_IMPORT, this.actualCompletionPosition);
+ typeImportProposal.nameLookup = this.nameEnvironment.nameLookup;
+ typeImportProposal.completionEngine = this;
+ char[] packageName = receiverType.qualifiedPackageName();
+ typeImportProposal.setDeclarationSignature(packageName);
+ typeImportProposal.setSignature(getSignature(receiverType));
+ typeImportProposal.setPackageName(packageName);
+ typeImportProposal.setTypeName(receiverType.qualifiedSourceName());
+ typeImportProposal.setCompletion(typeImportCompletion);
+ typeImportProposal.setFlags(receiverType.modifiers);
+ typeImportProposal.setAdditionalFlags(CompletionFlags.Default);
+ typeImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+ typeImportProposal.setRelevance(relevance);
- if (sourceType == otherType) continue next;
- }
+ proposal.setRequiredProposals(new CompletionProposal[]{typeImportProposal});
- this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ } else {
+ if (!this.isIgnored(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+
+ char[] methodImportCompletion = createImportCharArray(CharOperation.concat(typeName, method.selector, '.'), true, false);
+
+ InternalCompletionProposal methodImportProposal = createProposal(CompletionProposal.METHOD_IMPORT, this.actualCompletionPosition);
+ methodImportProposal.setDeclarationSignature(getSignature(method.declaringClass));
+ methodImportProposal.setSignature(getSignature(method));
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ methodImportProposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ methodImportProposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ methodImportProposal.setParameterPackageNames(parameterPackageNames);
+ methodImportProposal.setParameterTypeNames(parameterTypeNames);
+ methodImportProposal.setPackageName(method.returnType.qualifiedPackageName());
+ methodImportProposal.setTypeName(method.returnType.qualifiedSourceName());
+ methodImportProposal.setName(method.selector);
+ methodImportProposal.setCompletion(methodImportCompletion);
+ methodImportProposal.setFlags(method.modifiers);
+ methodImportProposal.setAdditionalFlags(CompletionFlags.StaticImport);
+ methodImportProposal.setReplaceRange(importStart - this.offset, importEnd - this.offset);
+ methodImportProposal.setTokenRange(importStart - this.offset, importEnd - this.offset);
+ methodImportProposal.setRelevance(relevance);
+ if(parameterNames != null) methodImportProposal.setParameterNames(parameterNames);
+
+ proposal.setRequiredProposals(new CompletionProposal[]{methodImportProposal});
- if(this.assistNodeIsClass) {
- if(!sourceType.isClass()) continue next;
- } else if(this.assistNodeIsInterface) {
- if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
- } else if (this.assistNodeIsAnnotation) {
- if(!sourceType.isAnnotationType()) continue next;
- } else if (isEmptyPrefix && this.assistNodeIsException) {
- if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
- continue next;
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
}
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
- relevance += computeRelevanceForExpectingType(sourceType);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
-
- if (sourceType.isAnnotationType()) {
- relevance += computeRelevanceForAnnotation();
- relevance += computeRelevanceForAnnotationTarget(sourceType);
- } else if (sourceType.isInterface()) {
- relevance += computeRelevanceForInterface();
- } else if(sourceType.isClass()){
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(sourceType.sourceName);
- }
- this.noProposal = false;
- if(proposeType) {
- char[] typeName = sourceType.sourceName();
- createTypeProposal(
- sourceType,
- typeName,
- IAccessRule.K_ACCESSIBLE,
- typeName,
- relevance,
- null,
- null,
- null,
- false);
- }
+ this.startPosition = previousStartPosition;
+ this.tokenStart = previousTokenStart;
}
}
- if(!skip && proposeType) {
- findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
- }
+ // Helper method for findMethods(char[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, boolean)
+ private void findLocalMethodsFromStaticImports(
+ char[] methodName,
+ MethodBinding[] methods,
+ Scope scope,
+ boolean exactMatch,
+ ObjectVector methodsFound,
+ ReferenceBinding receiverType,
+ InvocationSite invocationSite) {
- if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
- if(proposeType && this.expectedTypesPtr > -1) {
- next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if(this.expectedTypes[i] instanceof ReferenceBinding) {
- ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
+ ObjectVector newMethodsFound = new ObjectVector();
- if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
- // don't propose type variable if the completion is a constructor ('new |')
- continue next;
- }
- if (this.options.checkDeprecation &&
- refBinding.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(refBinding))
- continue next;
+ next : for (int f = methods.length; --f >= 0;) {
+ MethodBinding method = methods[f];
- int accessibility = IAccessRule.K_ACCESSIBLE;
- if(refBinding.hasRestrictedAccess()) {
- AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
- if(accessRestriction != null) {
- switch (accessRestriction.getProblemId()) {
- case IProblem.ForbiddenReference:
- if (this.options.checkForbiddenReference) {
- continue next;
- }
- accessibility = IAccessRule.K_NON_ACCESSIBLE;
- break;
- case IProblem.DiscouragedReference:
- if (this.options.checkDiscouragedReference) {
- continue next;
- }
- accessibility = IAccessRule.K_DISCOURAGED;
- break;
- }
- }
- }
+ if (method.isSynthetic()) continue next;
- for (int j = 0; j < typesFound.size(); j++) {
- ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
- if (typeFound == refBinding) {
- continue next;
- }
- }
+ if (method.isDefaultAbstract()) continue next;
- boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
+ if (method.isConstructor()) continue next;
- // top level types of the current unit are already proposed.
- if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
- char[] packageName = refBinding.qualifiedPackageName();
- char[] typeName = refBinding.sourceName();
- char[] completionName = typeName;
+ if (!method.isStatic()) continue next;
- boolean isQualified = false;
- if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
- if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
- if (packageName == null || packageName.length == 0)
- if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
- continue next; // ignore types from the default package from outside it
- completionName = CharOperation.concat(packageName, typeName, '.');
- isQualified = true;
- }
- }
+ if (this.options.checkDeprecation &&
+ method.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(method.declaringClass))
+ continue next;
- if(this.assistNodeIsClass) {
- if(!refBinding.isClass()) continue next;
- } else if(this.assistNodeIsInterface) {
- if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
- } else if (this.assistNodeIsAnnotation) {
- if(!refBinding.isAnnotationType()) continue next;
- }
+ if (this.options.checkVisibility
+ && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, typeName);
- relevance += computeRelevanceForExpectingType(refBinding);
- relevance += computeRelevanceForQualification(isQualified);
- relevance += computeRelevanceForRestrictions(accessibility);
+ if (!CharOperation.equals(methodName, method.selector, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(methodName, method.selector)))
+ continue next;
- if(refBinding.isClass()) {
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(typeName);
- } else if(refBinding.isEnum()) {
- relevance += computeRelevanceForEnum();
- } else if(refBinding.isInterface()) {
- relevance += computeRelevanceForInterface();
- }
+ for (int i = methodsFound.size; --i >= 0;) {
+ Object[] other = (Object[]) methodsFound.elementAt(i);
+ MethodBinding otherMethod = (MethodBinding) other[0];
+ ReferenceBinding otherReceiverType = (ReferenceBinding) other[1];
+ if (method == otherMethod && receiverType == otherReceiverType)
+ continue next;
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(packageName);
- proposal.setSignature(getSignature(refBinding));
- proposal.setPackageName(packageName);
- proposal.setTypeName(typeName);
- proposal.setCompletion(completionName);
- proposal.setFlags(refBinding.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- proposal.setAccessibility(accessibility);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- }
- }
- }
- } else {
- if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
- if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
- if (proposeBaseTypes) {
- if (proposeVoidType) {
- findKeywords(token, BASE_TYPE_NAMES, false, false);
- } else {
- findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
- }
+ if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
+ if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
+ continue next;
}
}
}
- if(proposeType) {
- int l = typesFound.size();
- for (int i = 0; i < l; i++) {
- ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
- char[] fullyQualifiedTypeName =
- CharOperation.concat(
- typeFound.qualifiedPackageName(),
- typeFound.qualifiedSourceName(),
- '.');
- this.knownTypes.put(fullyQualifiedTypeName, this);
- }
- int searchFor = IJavaSearchConstants.TYPE;
- if(this.assistNodeIsClass) {
- searchFor = IJavaSearchConstants.CLASS;
- } else if(this.assistNodeIsInterface) {
- searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
- } else if(this.assistNodeIsEnum) {
- searchFor = IJavaSearchConstants.ENUM;
- } else if(this.assistNodeIsAnnotation) {
- searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
- }
- this.nameEnvironment.findTypes(
- token,
- proposeAllMemberTypes,
- this.options.camelCaseMatch,
- searchFor,
- this);
- acceptTypes(scope);
- }
- if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
- this.nameEnvironment.findPackages(token, this);
- }
- }
- }
-
- private void findTypesAndSubpackages(
- char[] token,
- PackageBinding packageBinding,
- Scope scope) {
-
- boolean proposeType =
- !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
- ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
- char[] qualifiedName =
- CharOperation.concatWith(packageBinding.compoundName, token, '.');
+ newMethodsFound.add(new Object[]{method, receiverType});
- if (token == null || token.length == 0) {
- int length = qualifiedName.length;
- System.arraycopy(
- qualifiedName,
- 0,
- qualifiedName = new char[length + 1],
- 0,
- length);
- qualifiedName[length] = '.';
- }
+ int length = method.parameters.length;
+ char[][] parameterPackageNames = new char[length][];
+ char[][] parameterTypeNames = new char[length][];
- this.qualifiedCompletionToken = qualifiedName;
+ for (int i = 0; i < length; i++) {
+ TypeBinding type = method.original().parameters[i];
+ parameterPackageNames[i] = type.qualifiedPackageName();
+ parameterTypeNames[i] = type.qualifiedSourceName();
+ }
+ char[][] parameterNames = findMethodParameterNames(method,parameterTypeNames);
- if (proposeType && this.unitScope != null) {
- int typeLength = qualifiedName.length;
- SourceTypeBinding[] types = this.unitScope.topLevelTypes;
+ char[] completion = CharOperation.NO_CHAR;
- for (int i = 0, length = types.length; i < length; i++) {
- SourceTypeBinding sourceType = types[i];
+ int previousStartPosition = this.startPosition;
+ int previousTokenStart = this.tokenStart;
- char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
+ if (!exactMatch) {
+ if (this.source != null
+ && this.source.length > this.endPosition
+ && this.source[this.endPosition] == '(') {
+ completion = method.selector;
+ } else {
+ completion = CharOperation.concat(method.selector, new char[] { '(', ')' });
+ }
+ } else {
+ this.startPosition = this.endPosition;
+ this.tokenStart = this.tokenEnd;
+ }
- if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
- if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
- if (typeLength > qualifiedSourceTypeName.length) continue;
- if (!(packageBinding == sourceType.getPackage())) continue;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(methodName, method.selector);
+ relevance += computeRelevanceForExpectingType(method.returnType);
+ relevance += computeRelevanceForEnumConstant(method.returnType);
+ relevance += computeRelevanceForStatic(true, method.isStatic());
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
- if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.METHOD_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(method.declaringClass));
+ proposal.setSignature(getSignature(method));
+ MethodBinding original = method.original();
+ if(original != method) {
+ proposal.setOriginalSignature(getSignature(original));
+ }
+ proposal.setDeclarationPackageName(method.declaringClass.qualifiedPackageName());
+ proposal.setDeclarationTypeName(method.declaringClass.qualifiedSourceName());
+ proposal.setParameterPackageNames(parameterPackageNames);
+ proposal.setParameterTypeNames(parameterTypeNames);
+ proposal.setPackageName(method.returnType.qualifiedPackageName());
+ proposal.setTypeName(method.returnType.qualifiedSourceName());
+ proposal.setName(method.selector);
+ proposal.setCompletion(completion);
+ proposal.setFlags(method.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ if(parameterNames != null) proposal.setParameterNames(parameterNames);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ this.startPosition = previousStartPosition;
+ this.tokenStart = previousTokenStart;
+ }
- if (this.options.checkDeprecation &&
- sourceType.isViewedAsDeprecated() &&
- !scope.isDefinedInSameUnit(sourceType))
- continue;
+ methodsFound.addAll(newMethodsFound);
+ }
- int accessibility = IAccessRule.K_ACCESSIBLE;
- if(sourceType.hasRestrictedAccess()) {
- AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
- if(accessRestriction != null) {
- switch (accessRestriction.getProblemId()) {
- case IProblem.ForbiddenReference:
- if (this.options.checkForbiddenReference) {
- continue;
- }
- accessibility = IAccessRule.K_NON_ACCESSIBLE;
- break;
- case IProblem.DiscouragedReference:
- if (this.options.checkDiscouragedReference) {
- continue;
- }
- accessibility = IAccessRule.K_DISCOURAGED;
- break;
- }
- }
- }
+ private void findLocalMethodsFromStaticImports(
+ char[] token,
+ Scope scope,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean exactMatch,
+ ObjectVector methodsFound,
+ boolean proposeMethod) {
+ findFieldsAndMethodsFromStaticImports(
+ token,
+ scope,
+ invocationSite,
+ invocationScope,
+ exactMatch,
+ false,
+ new ObjectVector(),
+ new ObjectVector(),
+ methodsFound,
+ false,
+ proposeMethod);
+ }
+ protected void findMembers(
+ char[] token,
+ ReferenceBinding receiverType,
+ Scope scope,
+ InvocationSite invocationSite,
+ boolean isInsideAnnotationAttribute,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
- this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
+ if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ findMemberTypes(
+ token,
+ receiverType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ true,
+ new ObjectVector(),
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ }
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ findClassField(
+ token,
+ receiverType,
+ scope,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ }
+ MethodScope methodScope = null;
+ if (!isInsideAnnotationAttribute &&
+ !this.requestor.isIgnored(CompletionProposal.KEYWORD) &&
+ ((scope instanceof MethodScope && !((MethodScope)scope).isStatic)
+ || ((methodScope = scope.enclosingMethodScope()) != null && !methodScope.isStatic))) {
+ if (token.length > 0) {
+ findKeywords(token, new char[][]{Keywords.THIS}, false, true);
+ } else {
int relevance = computeBaseRelevance();
relevance += computeRelevanceForResolution();
relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
- relevance += computeRelevanceForExpectingType(sourceType);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(accessibility);
+ relevance += computeRelevanceForCaseMatching(this.completionToken, Keywords.THIS);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywords
+ relevance += R_NON_INHERITED;
- if (sourceType.isAnnotationType()) {
- relevance += computeRelevanceForAnnotation();
- } else if (sourceType.isInterface()) {
- relevance += computeRelevanceForInterface();
- } else if (sourceType.isClass()) {
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(sourceType.sourceName);
- }
this.noProposal = false;
- if(proposeType) {
- char[] typeName = sourceType.sourceName();
- createTypeProposal(
- sourceType,
- typeName,
- IAccessRule.K_ACCESSIBLE,
- typeName,
- relevance,
- null,
- null,
- null,
- false);
+ if (!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+ proposal.setName(Keywords.THIS);
+ proposal.setCompletion(Keywords.THIS);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if (DEBUG) {
+ this.printDebug(proposal);
+ }
}
}
}
- if(proposeType) {
- int searchFor = IJavaSearchConstants.TYPE;
- if(this.assistNodeIsClass) {
- searchFor = IJavaSearchConstants.CLASS;
- } else if(this.assistNodeIsInterface) {
- searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
- } else if(this.assistNodeIsEnum) {
- searchFor = IJavaSearchConstants.ENUM;
- } else if(this.assistNodeIsAnnotation) {
- searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
- }
- this.nameEnvironment.findTypes(
- qualifiedName,
- false,
- this.options.camelCaseMatch,
- searchFor,
- this);
- acceptTypes(scope);
+ if (!this.requestor.isIgnored(CompletionProposal.FIELD_REF)) {
+ findFields(
+ token,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ new ObjectVector(),
+ true,
+ invocationSite,
+ scope,
+ false,
+ false,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ null,
+ -1,
+ -1);
}
- if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
- this.nameEnvironment.findPackages(qualifiedName, this);
+
+ if (!isInsideAnnotationAttribute && !this.requestor.isIgnored(CompletionProposal.METHOD_REF)) {
+ findMethods(
+ token,
+ null,
+ null,
+ receiverType,
+ scope,
+ new ObjectVector(),
+ true,
+ false,
+ invocationSite,
+ scope,
+ false,
+ false,
+ false,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ null,
+ -1,
+ -1);
}
}
- private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
- ImportBinding[] importBindings = scope.compilationUnitScope().imports;
- for (int i = 0; i < importBindings.length; i++) {
- ImportBinding importBinding = importBindings[i];
- if(importBinding.isValidBinding() && importBinding.isStatic()) {
- Binding binding = importBinding.resolvedImport;
- if(binding != null && binding.isValidBinding()) {
- if(importBinding.onDemand) {
- if((binding.kind() & Binding.TYPE) != 0) {
- this.findMemberTypes(
- token,
- (ReferenceBinding) binding,
- scope,
- scope.enclosingSourceType(),
- true,
- false,
- true,
- true,
- proposeAllMemberTypes,
- null,
- typesFound,
- null,
- null,
- null,
- false);
- }
- } else {
- if ((binding.kind() & Binding.TYPE) != 0) {
- ReferenceBinding typeBinding = (ReferenceBinding) binding;
- int typeLength = token.length;
+ private void findMembersFromMissingType(
+ final char[] token,
+ final long pos,
+ TypeBinding resolveType,
+ final Scope scope,
+ final InvocationSite invocationSite,
+ final boolean isInsideAnnotationAttribute) {
+ MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+ MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+ new MissingTypesGuesser.GuessedTypeRequestor() {
+ public void accept(
+ TypeBinding guessedType,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean hasProblems) {
+ if (guessedType instanceof ReferenceBinding) {
+ findMembers(
+ CompletionEngine.this.completionToken,
+ (ReferenceBinding)guessedType,
+ scope,
+ invocationSite,
+ isInsideAnnotationAttribute,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ hasProblems);
+ }
+ }
+ };
+ SingleTypeReference typeRef = new SingleTypeReference(token, pos);
+ typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ token }, null, ProblemReasons.NotFound);
+ missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+ }
- if (!typeBinding.isStatic()) continue;
+ private void findMemberTypes(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ SourceTypeBinding typeInvocation,
+ boolean staticOnly,
+ boolean staticFieldsAndMethodOnly,
+ boolean fromStaticImport,
+ boolean checkQualification,
+ boolean proposeAllMemberTypes,
+ SourceTypeBinding typeToIgnore,
+ ObjectVector typesFound,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
- if (typeLength > typeBinding.sourceName.length) continue;
+ ReferenceBinding currentType = receiverType;
+ if (typeName == null)
+ return;
- if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue;
+ if (this.insideQualifiedReference
+ || typeName.length == 0) { // do not search up the hierarchy
- if (typesFound.contains(typeBinding)) continue;
+ findMemberTypes(
+ typeName,
+ currentType.memberTypes(),
+ typesFound,
+ receiverType,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ checkQualification,
+ scope,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ return;
+ }
- typesFound.add(typeBinding);
+ ReferenceBinding[] interfacesToVisit = null;
+ int nextPosition = 0;
- if(this.assistNodeIsClass) {
- if(!typeBinding.isClass()) continue;
- } else if(this.assistNodeIsInterface) {
- if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
- } else if (this.assistNodeIsAnnotation) {
- if(!typeBinding.isAnnotationType()) continue;
- }
+ do {
+ ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
+ if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ if (interfacesToVisit == null) {
+ interfacesToVisit = itsInterfaces;
+ nextPosition = interfacesToVisit.length;
+ } else {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
+ }
+ }
+ }
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
- relevance += computeRelevanceForExpectingType(typeBinding);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ findMemberTypes(
+ typeName,
+ currentType.memberTypes(),
+ typesFound,
+ receiverType,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ checkQualification,
+ scope,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
- if (typeBinding.isClass()) {
- relevance += computeRelevanceForClass();
- relevance += computeRelevanceForException(typeBinding.sourceName);
- } else if(typeBinding.isEnum()) {
- relevance += computeRelevanceForEnum();
- } else if(typeBinding.isInterface()) {
- relevance += computeRelevanceForInterface();
- }
+ currentType = currentType.superclass();
+ } while (currentType != null);
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
- proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
- proposal.setSignature(getSignature(typeBinding));
- proposal.setPackageName(typeBinding.qualifiedPackageName());
- proposal.setTypeName(typeBinding.qualifiedSourceName());
- proposal.setCompletion(typeBinding.sourceName());
- proposal.setFlags(typeBinding.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
+ if(proposeAllMemberTypes) {
+ ReferenceBinding[] memberTypes = receiverType.memberTypes();
+ for (int i = 0; i < memberTypes.length; i++) {
+ if(memberTypes[i] != typeToIgnore) {
+ findSubMemberTypes(
+ typeName,
+ memberTypes[i],
+ scope,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ typesFound);
+ }
+ }
+ }
+
+ if (interfacesToVisit != null) {
+ for (int i = 0; i < nextPosition; i++) {
+ ReferenceBinding anInterface = interfacesToVisit[i];
+ findMemberTypes(
+ typeName,
+ anInterface.memberTypes(),
+ typesFound,
+ receiverType,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ checkQualification,
+ scope,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+
+ ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
+ if (itsInterfaces != null && itsInterfaces != Binding.NO_SUPERINTERFACES) {
+ int itsLength = itsInterfaces.length;
+ if (nextPosition + itsLength >= interfacesToVisit.length)
+ System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
+ nextInterface : for (int a = 0; a < itsLength; a++) {
+ ReferenceBinding next = itsInterfaces[a];
+ for (int b = 0; b < nextPosition; b++)
+ if (next == interfacesToVisit[b]) continue nextInterface;
+ interfacesToVisit[nextPosition++] = next;
}
}
}
}
}
- private void findVariablesAndMethods(
- char[] token,
+
+ protected void findMemberTypes(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ SourceTypeBinding typeInvocation,
+ boolean staticOnly,
+ boolean staticFieldsAndMethodOnly,
+ ObjectVector typesFound,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
+ findMemberTypes(
+ typeName,
+ receiverType,
+ scope,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ false,
+ false,
+ false,
+ null,
+ typesFound,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ }
+ // Helper method for findMemberTypes(char[], ReferenceBinding, Scope)
+ private void findMemberTypes(
+ char[] typeName,
+ ReferenceBinding[] memberTypes,
+ ObjectVector typesFound,
+ ReferenceBinding receiverType,
+ SourceTypeBinding invocationType,
+ boolean staticOnly,
+ boolean staticFieldsAndMethodOnly,
+ boolean fromStaticImport,
+ boolean checkQualification,
Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean insideTypeAnnotation,
- boolean insideAnnotationAttribute) {
-
- if (token == null)
- return;
-
- // Should local variables hide fields from the receiver type or any of its enclosing types?
- // we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
-
- boolean staticsOnly = false;
- // need to know if we're in a static context (or inside a constructor)
- int tokenLength = token.length;
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
- ObjectVector localsFound = new ObjectVector();
- ObjectVector fieldsFound = new ObjectVector();
- ObjectVector methodsFound = new ObjectVector();
+ // Inherited member types which are hidden by subclasses are filtered out
+ // No visibility checks can be performed without the scope & invocationSite
+ int typeLength = typeName.length;
+ next : for (int m = memberTypes.length; --m >= 0;) {
+ ReferenceBinding memberType = memberTypes[m];
+ // if (!wantClasses && memberType.isClass()) continue next;
+ // if (!wantInterfaces && memberType.isInterface()) continue next;
- Scope currentScope = scope;
+ if (staticOnly && !memberType.isStatic()) continue next;
- if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
- done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+ if (isForbidden(memberType)) continue next;
- switch (currentScope.kind) {
+ if (typeLength > memberType.sourceName.length)
+ continue next;
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+ if (!CharOperation.prefixEquals(typeName, memberType.sourceName, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, memberType.sourceName)))
+ continue next;
- //$FALL-THROUGH$
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) currentScope;
+ if (this.options.checkDeprecation &&
+ memberType.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(memberType))
+ continue next;
- next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
- LocalVariableBinding local = blockScope.locals[i];
+ if (this.options.checkVisibility) {
+ if (invocationType != null && !memberType.canBeSeenBy(receiverType, invocationType)) {
+ continue next;
+ } else if(invocationType == null && !memberType.canBeSeenBy(this.unitScope.fPackage)) {
+ continue next;
+ }
+ }
- if (local == null)
- break next;
+ if (this.insideQualifiedReference &&
+ receiverType.isParameterizedType() &&
+ memberType.isStatic()) {
+ continue next;
+ }
- if (tokenLength > local.name.length)
- continue next;
+ for (int i = typesFound.size; --i >= 0;) {
+ ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(i);
- if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
- && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
- continue next;
+ if (memberType == otherType)
+ continue next;
- if (local.isSecret())
- continue next;
+ if (CharOperation.equals(memberType.sourceName, otherType.sourceName, true)) {
- for (int f = 0; f < localsFound.size; f++) {
- LocalVariableBinding otherLocal =
- (LocalVariableBinding) localsFound.elementAt(f);
- if (CharOperation.equals(otherLocal.name, local.name, true))
- continue next;
- }
- localsFound.add(local);
+ if (memberType.enclosingType().isSuperclassOf(otherType.enclosingType()))
+ continue next;
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal(local);
- relevance += computeRelevanceForCaseMatching(token, local.name);
- relevance += computeRelevanceForExpectingType(local.type);
- relevance += computeRelevanceForEnumConstant(local.type);
- relevance += computeRelevanceForQualification(false);
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
- this.noProposal = false;
- if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
- InternalCompletionProposal proposal = createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
- proposal.setSignature(
- local.type == null
- ? createTypeSignature(
- CharOperation.NO_CHAR,
- local.declaration.type.toString().toCharArray())
- : getSignature(local.type));
- if(local.type == null) {
- //proposal.setPackageName(null);
- proposal.setTypeName(local.declaration.type.toString().toCharArray());
- } else {
- proposal.setPackageName(local.type.qualifiedPackageName());
- proposal.setTypeName(local.type.qualifiedSourceName());
- }
- proposal.setName(local.name);
- proposal.setCompletion(local.name);
- proposal.setFlags(local.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
- break;
+ if (otherType.enclosingType().isInterface())
+ if (memberType.enclosingType()
+ .implementsInterface(otherType.enclosingType(), true))
+ continue next;
- case Scope.COMPILATION_UNIT_SCOPE :
- break done1;
+ if (memberType.enclosingType().isInterface())
+ if (otherType.enclosingType()
+ .implementsInterface(memberType.enclosingType(), true))
+ continue next;
}
- currentScope = currentScope.parent;
}
- }
-
- boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
- boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
- staticsOnly = false;
- currentScope = scope;
+ typesFound.add(memberType);
- if(proposeField || proposeMethod) {
- done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
+ if(!this.insideQualifiedReference) {
+ if(this.assistNodeIsClass) {
+ if(!memberType.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!memberType.isInterface() && !memberType.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!memberType.isAnnotationType()) continue next;
+ }
+ }
- switch (currentScope.kind) {
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- break;
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- /* if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
- findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
- findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
- break done;
- } else { */
- if(!insideTypeAnnotation) {
- if(proposeField) {
- findFields(
- token,
- enclosingType,
- classScope,
- fieldsFound,
- localsFound,
- staticsOnly,
- invocationSite,
- invocationScope,
- true,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- if(proposeMethod && !insideAnnotationAttribute) {
- findMethods(
- token,
- null,
- null,
- enclosingType,
- classScope,
- methodsFound,
- staticsOnly,
- false,
- false,
- invocationSite,
- invocationScope,
- true,
- false,
- true,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- }
- staticsOnly |= enclosingType.isStatic();
- insideTypeAnnotation = false;
- // }
- break;
+ char[] completionName = memberType.sourceName();
- case Scope.COMPILATION_UNIT_SCOPE :
- break done2;
+ boolean isQualified = false;
+ if(checkQualification && !fromStaticImport) {
+ char[] memberPackageName = memberType.qualifiedPackageName();
+ char[] memberTypeName = memberType.sourceName();
+ char[] memberEnclosingTypeNames = memberType.enclosingType().qualifiedSourceName();
+ if (mustQualifyType(memberPackageName, memberTypeName, memberEnclosingTypeNames, memberType.modifiers)) {
+ if (memberPackageName == null || memberPackageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ break next; // ignore types from the default package from outside it
+ isQualified = true;
+ completionName =
+ CharOperation.concat(
+ memberPackageName,
+ CharOperation.concat(
+ memberEnclosingTypeNames,
+ memberTypeName,
+ '.'),
+ '.');
}
- currentScope = currentScope.parent;
}
- findFieldsAndMethodsFromStaticImports(
- token,
- scope,
- invocationSite,
- invocationScope,
- false,
- insideAnnotationAttribute,
- localsFound,
- fieldsFound,
- methodsFound,
- proposeField,
- proposeMethod);
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(typeName, memberType.sourceName);
+ relevance += computeRelevanceForExpectingType(memberType);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+ if(!this.insideQualifiedReference) {
+ relevance += computeRelevanceForQualification(isQualified);
+ }
+ 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.
- if (this.assistNodeInJavadoc == 0) {
- // search in favorites import
- findFieldsAndMethodsFromFavorites(
- token,
- scope,
- invocationSite,
- invocationScope,
- localsFound,
- fieldsFound,
- methodsFound);
+ if (memberType.isAnnotationType()) {
+ relevance += computeRelevanceForAnnotation();
+ relevance += computeRelevanceForAnnotationTarget(memberType);
+ } else if (memberType.isClass()) {
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(memberType.sourceName);
+ } else if(memberType.isEnum()) {
+ relevance += computeRelevanceForEnum();
+ } else if(memberType.isInterface()) {
+ relevance += computeRelevanceForInterface();
}
- findEnumConstantsFromExpectedTypes(
- token,
- invocationScope,
- fieldsFound);
+ if (missingElements != null) {
+ relevance += computeRelevanceForMissingElements(missingElementsHaveProblems);
+ }
+
+ this.noProposal = false;
+ createTypeProposal(
+ memberType,
+ memberType.qualifiedSourceName(),
+ IAccessRule.K_ACCESSIBLE,
+ completionName,
+ relevance,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
}
}
-
- private void findLocalMethodsFromStaticImports(
- char[] token,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean exactMatch,
- ObjectVector methodsFound,
- boolean proposeMethod) {
- findFieldsAndMethodsFromStaticImports(
- token,
- scope,
- invocationSite,
- invocationScope,
- exactMatch,
- false,
- new ObjectVector(),
- new ObjectVector(),
- methodsFound,
- false,
- proposeMethod);
+ private void findMemberTypesFromMissingType(
+ char[] typeName,
+ final long pos,
+ final Scope scope) {
+ MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+ MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+ new MissingTypesGuesser.GuessedTypeRequestor() {
+ public void accept(
+ TypeBinding guessedType,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean hasProblems) {
+ if (guessedType instanceof ReferenceBinding) {
+ findMemberTypes(
+ CompletionEngine.this.completionToken,
+ (ReferenceBinding)guessedType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ hasProblems);
+ }
+ }
+ };
+ SingleTypeReference typeRef = new SingleTypeReference(typeName, pos);
+ typeRef.resolvedType = new ProblemReferenceBinding(new char[][]{ typeName }, null, ProblemReasons.NotFound);
+ missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
}
-
- private void findFieldsAndMethodsFromStaticImports(
- char[] token,
- Scope scope,
- InvocationSite invocationSite,
- Scope invocationScope,
- boolean exactMatch,
- boolean insideAnnotationAttribute,
- ObjectVector localsFound,
- ObjectVector fieldsFound,
- ObjectVector methodsFound,
- boolean proposeField,
- boolean proposeMethod) {
- // search in static import
- ImportBinding[] importBindings = scope.compilationUnitScope().imports;
- for (int i = 0; i < importBindings.length; i++) {
- ImportBinding importBinding = importBindings[i];
- if(importBinding.isValidBinding() && importBinding.isStatic()) {
- Binding binding = importBinding.resolvedImport;
- if(binding != null && binding.isValidBinding()) {
- if(importBinding.onDemand) {
- if((binding.kind() & Binding.TYPE) != 0) {
- if(proposeField) {
- findFields(
- token,
- (ReferenceBinding)binding,
- scope,
- fieldsFound,
- localsFound,
- true,
- invocationSite,
- invocationScope,
- true,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- if(proposeMethod && !insideAnnotationAttribute) {
- findMethods(
- token,
- null,
- null,
- (ReferenceBinding)binding,
- scope,
- methodsFound,
- true,
- exactMatch,
- false,
- invocationSite,
- invocationScope,
- true,
- false,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- }
- } else {
- if ((binding.kind() & Binding.FIELD) != 0) {
- if(proposeField) {
- findFields(
- token,
- new FieldBinding[]{(FieldBinding)binding},
- scope,
- fieldsFound,
- localsFound,
- true,
- ((FieldBinding)binding).declaringClass,
- invocationSite,
- invocationScope,
- true,
- false,
- null,
- null,
- null,
- false,
- null,
- -1,
- -1);
- }
- } else if ((binding.kind() & Binding.METHOD) != 0) {
- if(proposeMethod && !insideAnnotationAttribute) {
- MethodBinding methodBinding = (MethodBinding)binding;
- if ((exactMatch && CharOperation.equals(token, methodBinding.selector)) ||
- !exactMatch && CharOperation.prefixEquals(token, methodBinding.selector)) {
-
- findLocalMethodsFromStaticImports(
- methodBinding.selector,
- methodBinding.declaringClass.methods(),
- scope,
- exactMatch,
- methodsFound,
- methodBinding.declaringClass,
- invocationSite);
- }
- }
- }
+
+ private void findMemberTypesFromMissingType(
+ TypeReference typeRef,
+ final long pos,
+ final Scope scope) {
+ MissingTypesGuesser missingTypesConverter = new MissingTypesGuesser(this);
+ MissingTypesGuesser.GuessedTypeRequestor substitutionRequestor =
+ new MissingTypesGuesser.GuessedTypeRequestor() {
+ public void accept(
+ TypeBinding guessedType,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean hasProblems) {
+ if (guessedType instanceof ReferenceBinding) {
+ findMemberTypes(
+ CompletionEngine.this.completionToken,
+ (ReferenceBinding)guessedType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ new ObjectVector(),
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ hasProblems);
}
}
+ };
+ missingTypesConverter.guess(typeRef, scope, substitutionRequestor);
+ }
+
+ private void findMethodDeclarations(
+ char[] selector,
+ ReferenceBinding receiverType,
+ Scope scope,
+ ObjectVector methodsFound,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems) {
+
+ if (selector == null) {
+ return;
+ }
+
+ MethodBinding[] receiverTypeMethods = receiverType.availableMethods();
+ if (receiverTypeMethods != null){
+ for (int i = 0; i < receiverTypeMethods.length; i++) {
+ if(!receiverTypeMethods[i].isDefaultAbstract()) {
+ methodsFound.add(receiverTypeMethods[i]);
+ }
+ }
+ }
+
+ ReferenceBinding currentType = receiverType;
+
+ findInterfacesMethodDeclarations(
+ selector,
+ receiverType,
+ currentType.superInterfaces(),
+ scope,
+ methodsFound,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+
+ if (receiverType.isInterface()) {
+ currentType = scope.getJavaLangObject();
+ } else {
+ currentType = receiverType.superclass();
+ }
+
+ boolean hasPotentialDefaultAbstractMethods = true;
+ while (currentType != null) {
+
+ MethodBinding[] methods = currentType.availableMethods();
+ if (methods != null) {
+ findLocalMethodDeclarations(
+ selector,
+ methods,
+ scope,
+ methodsFound,
+ false,
+ receiverType);
+ }
+
+ if (hasPotentialDefaultAbstractMethods &&
+ (currentType.isAbstract() ||
+ currentType.isTypeVariable() ||
+ currentType.isIntersectionType() ||
+ currentType.isEnum())){
+
+ ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+
+ findInterfacesMethodDeclarations(
+ selector,
+ receiverType,
+ superInterfaces,
+ scope,
+ methodsFound,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems);
+ } else {
+ hasPotentialDefaultAbstractMethods = false;
}
+ currentType = currentType.superclass();
}
}
- private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
- final TypeReference type = variable.type;
- if(type != null &&
- type.resolvedType != null &&
- type.resolvedType.problemId() == ProblemReasons.NoError){
+
+ private char[][] findMethodParameterNames(MethodBinding method, char[][] parameterTypeNames){
+ TypeBinding erasure = method.declaringClass.erasure();
+ if(!(erasure instanceof ReferenceBinding)) return null;
- final ArrayList proposedNames = new ArrayList();
+ char[][] parameterNames = null;
- UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
- new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
- public void acceptName(char[] name) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
- relevance += R_NAME_FIRST_PREFIX;
- relevance += R_NAME_FIRST_SUFFIX;
- relevance += R_NAME_LESS_NEW_CHARACTERS;
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
+ int length = parameterTypeNames.length;
- // accept result
- CompletionEngine.this.noProposal = false;
- if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
- InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
- proposal.setSignature(getSignature(type.resolvedType));
- proposal.setPackageName(type.resolvedType.qualifiedPackageName());
- proposal.setTypeName(type.resolvedType.qualifiedSourceName());
- proposal.setName(name);
- proposal.setCompletion(name);
- //proposal.setFlags(Flags.AccDefault);
- proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
- proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
- proposal.setRelevance(relevance);
- CompletionEngine.this.requestor.accept(proposal);
- if(DEBUG) {
- CompletionEngine.this.printDebug(proposal);
- }
+ if (length == 0){
+ return CharOperation.NO_CHAR_CHAR;
+ }
+ // look into the corresponding unit if it is available
+ if (erasure instanceof SourceTypeBinding){
+ SourceTypeBinding sourceType = (SourceTypeBinding) erasure;
+
+ if (sourceType.scope != null){
+ TypeDeclaration parsedType;
+
+ if ((parsedType = sourceType.scope.referenceContext) != null){
+ AbstractMethodDeclaration methodDecl = parsedType.declarationOf(method.original());
+
+ if (methodDecl != null){
+ Argument[] arguments = methodDecl.arguments;
+ parameterNames = new char[length][];
+
+ for(int i = 0 ; i < length ; i++){
+ parameterNames[i] = arguments[i].name;
}
- proposedNames.add(name);
}
- };
+ }
+ }
+ }
+ // look into the model
+ if(parameterNames == null){
- ReferenceContext referenceContext = scope.referenceContext();
- if (referenceContext instanceof AbstractMethodDeclaration) {
- AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+ ReferenceBinding bindingType = (ReferenceBinding)erasure;
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.find(
- this.completionToken,
- md,
- variable.declarationSourceEnd + 1,
- discouragedNames,
- nameRequestor);
- } else if (referenceContext instanceof TypeDeclaration) {
- TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
- FieldDeclaration[] fields = typeDeclaration.fields;
- if (fields != null) {
- done : for (int i = 0; i < fields.length; i++) {
- if (fields[i] instanceof Initializer) {
- Initializer initializer = (Initializer) fields[i];
- if (initializer.bodyStart <= variable.sourceStart &&
- variable.sourceStart < initializer.bodyEnd) {
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.find(
- this.completionToken,
- initializer,
- typeDeclaration.scope,
- variable.declarationSourceEnd + 1,
- discouragedNames,
- nameRequestor);
- break done;
- }
+ char[] compoundName = CharOperation.concatWith(bindingType.compoundName, '.');
+ Object type = this.typeCache.get(compoundName);
+
+ ISourceType sourceType = null;
+ if(type != null) {
+ if(type instanceof ISourceType) {
+ sourceType = (ISourceType) type;
+ }
+ } else {
+ NameEnvironmentAnswer answer = this.nameEnvironment.findType(bindingType.compoundName);
+ if(answer != null && answer.isSourceType()) {
+ sourceType = answer.getSourceTypes()[0];
+ this.typeCache.put(compoundName, sourceType);
+ }
+ }
+
+ if(sourceType != null) {
+ IType typeHandle = ((SourceTypeElementInfo) sourceType).getHandle();
+
+ String[] parameterTypeSignatures = new String[length];
+ for (int i = 0; i < length; i++) {
+ parameterTypeSignatures[i] = Signature.createTypeSignature(parameterTypeNames[i], false);
+ }
+ IMethod searchedMethod = typeHandle.getMethod(String.valueOf(method.selector), parameterTypeSignatures);
+ IMethod[] foundMethods = typeHandle.findMethods(searchedMethod);
+
+ if(foundMethods != null) {
+ int len = foundMethods.length;
+ if(len == 1) {
+ try {
+ SourceMethod sourceMethod = (SourceMethod) foundMethods[0];
+ parameterNames = ((SourceMethodElementInfo) sourceMethod.getElementInfo()).getArgumentNames();
+ } catch (JavaModelException e) {
+ // method doesn't exist: ignore
}
}
}
}
+ }
+ return parameterNames;
+ }
- int proposedNamesCount = proposedNames.size();
- if (proposedNamesCount > 0) {
- return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+ private void findMethods(
+ char[] selector,
+ TypeBinding[] typeArgTypes,
+ TypeBinding[] argTypes,
+ ReferenceBinding receiverType,
+ Scope scope,
+ ObjectVector methodsFound,
+ boolean onlyStaticMethods,
+ boolean exactMatch,
+ InvocationSite invocationSite,
+ Scope invocationScope,
+ boolean implicitCall,
+ boolean superCall,
+ boolean canBePrefixed,
+ Binding[] missingElements,
+ int[] missingElementsStarts,
+ int[] missingElementsEnds,
+ boolean missingElementsHaveProblems,
+ char[] castedReceiver,
+ int receiverStart,
+ int receiverEnd) {
+
+ boolean notInJavadoc = this.assistNodeInJavadoc == 0;
+ if (selector == null && notInJavadoc) {
+ return;
+ }
+
+ ReferenceBinding currentType = receiverType;
+ if (notInJavadoc) {
+ if (receiverType.isInterface()) {
+ findInterfacesMethods(
+ selector,
+ typeArgTypes,
+ argTypes,
+ receiverType,
+ new ReferenceBinding[]{currentType},
+ scope,
+ methodsFound,
+ onlyStaticMethods,
+ exactMatch,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
+ canBePrefixed,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+
+ currentType = scope.getJavaLangObject();
+ }
+ }
+ boolean hasPotentialDefaultAbstractMethods = true;
+ while (currentType != null) {
+
+ MethodBinding[] methods = currentType.availableMethods();
+ if (methods != null) {
+ findLocalMethods(
+ selector,
+ typeArgTypes,
+ argTypes,
+ methods,
+ scope,
+ methodsFound,
+ onlyStaticMethods,
+ exactMatch,
+ receiverType,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
+ canBePrefixed,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
}
- }
-
- return null;
- }
-
- private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
- final ArrayList proposedNames = new ArrayList();
-
- UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
- new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
- public void acceptName(char[] name) {
- CompletionEngine.this.acceptUnresolvedName(name);
- proposedNames.add(name);
- }
- };
- ReferenceContext referenceContext = scope.referenceContext();
- if (referenceContext instanceof AbstractMethodDeclaration) {
- AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+ if (hasPotentialDefaultAbstractMethods &&
+ (currentType.isAbstract() ||
+ currentType.isTypeVariable() ||
+ currentType.isIntersectionType() ||
+ currentType.isEnum())){
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.findAfter(
- this.completionToken,
- md.scope,
- md.scope.classScope(),
- from,
- md.bodyEnd,
- discouragedNames,
- nameRequestor);
- } else if (referenceContext instanceof TypeDeclaration) {
- TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
- FieldDeclaration[] fields = typeDeclaration.fields;
- if (fields != null) {
- done : for (int i = 0; i < fields.length; i++) {
- if (fields[i] instanceof Initializer) {
- Initializer initializer = (Initializer) fields[i];
- if (initializer.block.sourceStart <= from &&
- from < initializer.bodyEnd) {
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.findAfter(
- this.completionToken,
- typeDeclaration.scope,
- typeDeclaration.scope,
- from,
- initializer.bodyEnd,
- discouragedNames,
- nameRequestor);
- break done;
- }
+ ReferenceBinding[] superInterfaces = currentType.superInterfaces();
+ if (superInterfaces != null && currentType.isIntersectionType()) {
+ for (int i = 0; i < superInterfaces.length; i++) {
+ superInterfaces[i] = (ReferenceBinding)superInterfaces[i].capture(invocationScope, invocationSite.sourceEnd());
}
}
+
+ findInterfacesMethods(
+ selector,
+ typeArgTypes,
+ argTypes,
+ receiverType,
+ superInterfaces,
+ scope,
+ methodsFound,
+ onlyStaticMethods,
+ exactMatch,
+ invocationSite,
+ invocationScope,
+ implicitCall,
+ superCall,
+ canBePrefixed,
+ missingElements,
+ missingElementsStarts,
+ missingElementsEnds,
+ missingElementsHaveProblems,
+ castedReceiver,
+ receiverStart,
+ receiverEnd);
+ } else {
+ hasPotentialDefaultAbstractMethods = false;
}
+ currentType = currentType.superclass();
}
+ }
- int proposedNamesCount = proposedNames.size();
- if (proposedNamesCount > 0) {
- return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
- }
+ private void findNestedTypes(
+ char[] typeName,
+ SourceTypeBinding currentType,
+ Scope scope,
+ boolean proposeAllMemberTypes,
+ ObjectVector typesFound) {
+
+ if (typeName == null)
+ return;
- return null;
- }
+ int typeLength = typeName.length;
- private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
- char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
- if (foundNames != null && foundNames.length > 1) {
- int discouragedNamesLength = discouragedNames.length;
- int foundNamesLength = foundNames.length;
- int newLength = discouragedNamesLength + foundNamesLength;
- System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
- System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
- }
- findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
- }
+ SourceTypeBinding nextTypeToIgnore = null;
+ while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
- private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
- final ArrayList proposedNames = new ArrayList();
+ switch (scope.kind) {
- UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
- new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
- public void acceptName(char[] name) {
- CompletionEngine.this.acceptUnresolvedName(name);
- proposedNames.add(name);
- }
- };
+ case Scope.METHOD_SCOPE :
+ case Scope.BLOCK_SCOPE :
+ BlockScope blockScope = (BlockScope) scope;
- BlockScope upperScope = scope;
- while (upperScope.enclosingMethodScope() != null) {
- upperScope = upperScope.enclosingMethodScope();
- }
+ next : for (int i = 0, length = blockScope.subscopeCount; i < length; i++) {
- ReferenceContext referenceContext = upperScope.referenceContext();
- if (referenceContext instanceof AbstractMethodDeclaration) {
- AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+ if (blockScope.subscopes[i] instanceof ClassScope) {
+ SourceTypeBinding localType =
+ ((ClassScope) blockScope.subscopes[i]).referenceContext.binding;
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.findBefore(
- this.completionToken,
- md.scope,
- md.scope.classScope(),
- md.bodyStart,
- recordTo,
- parseTo,
- discouragedNames,
- nameRequestor);
- } else if (referenceContext instanceof TypeDeclaration) {
- TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+ if (!localType.isAnonymousType()) {
+ if (isForbidden(localType))
+ continue next;
+ if (typeLength > localType.sourceName.length)
+ continue next;
+ if (!CharOperation.prefixEquals(typeName, localType.sourceName, false/* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(typeName, localType.sourceName)))
+ continue next;
- done : {
- FieldDeclaration[] fields = typeDeclaration.fields;
- if (fields != null) {
- for (int i = 0; i < fields.length; i++) {
- if (fields[i] instanceof Initializer) {
- Initializer initializer = (Initializer) fields[i];
- if (initializer.block.sourceStart <= recordTo &&
- recordTo < initializer.bodyEnd) {
+ for (int j = typesFound.size; --j >= 0;) {
+ ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
- UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
- nameFinder.findBefore(
- this.completionToken,
- typeDeclaration.scope,
- typeDeclaration.scope,
- initializer.block.sourceStart,
- recordTo,
- parseTo,
- discouragedNames,
- nameRequestor);
- break done;
- }
- }
- }
- }
- }
- }
+ if (localType == otherType)
+ continue next;
+ }
- int proposedNamesCount = proposedNames.size();
- if (proposedNamesCount > 0) {
- return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
- }
+ if(this.assistNodeIsClass) {
+ if(!localType.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!localType.isInterface() && !localType.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!localType.isAnnotationType()) continue next;
+ }
- return null;
- }
- // Helper method for private void findVariableNames(char[] name, TypeReference type )
- private void findVariableName(
- char[] token,
- char[] qualifiedPackageName,
- char[] qualifiedSourceName,
- char[] sourceName,
- final TypeBinding typeBinding,
- char[][] discouragedNames,
- final char[][] forbiddenNames,
- int dim,
- int kind,
- int modifiers){
- findVariableName(
- token,
- qualifiedPackageName,
- qualifiedSourceName,
- sourceName,
- typeBinding,
- discouragedNames,
- forbiddenNames,
- false,
- dim,
- kind,
- modifiers);
- }
- private void findVariableName(
- char[] token,
- char[] qualifiedPackageName,
- char[] qualifiedSourceName,
- char[] sourceName,
- final TypeBinding typeBinding,
- char[][] discouragedNames,
- final char[][] forbiddenNames,
- boolean forCollection,
- int dim,
- int kind,
- int modifiers){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(typeName, localType.sourceName);
+ relevance += computeRelevanceForExpectingType(localType);
+ relevance += computeRelevanceForException(localType.sourceName);
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for nested type
+ relevance += computeRelevanceForAnnotationTarget(localType);
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(
+ localType,
+ localType.sourceName,
+ IAccessRule.K_ACCESSIBLE,
+ localType.sourceName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
+ }
+ }
+ }
+ break;
- if(sourceName == null || sourceName.length == 0)
- return;
+ case Scope.CLASS_SCOPE :
+ SourceTypeBinding enclosingSourceType = scope.enclosingSourceType();
+ findMemberTypes(
+ typeName,
+ enclosingSourceType,
+ scope,
+ currentType,
+ false,
+ false,
+ false,
+ false,
+ proposeAllMemberTypes,
+ nextTypeToIgnore,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ nextTypeToIgnore = enclosingSourceType;
+ if (typeLength == 0)
+ return; // do not search outside the class scope if no prefix was provided
+ break;
- // compute variable name for non base type
- final char[] displayName;
- if (!forCollection) {
- if (dim > 0){
- int l = qualifiedSourceName.length;
- displayName = new char[l+(2*dim)];
- System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
- for(int i = 0; i < dim; i++){
- displayName[l+(i*2)] = '[';
- displayName[l+(i*2)+1] = ']';
- }
- } else {
- displayName = qualifiedSourceName;
+ case Scope.COMPILATION_UNIT_SCOPE :
+ return;
}
- } else {
- displayName = typeBinding.qualifiedSourceName();
+ scope = scope.parent;
}
+ }
- final char[] t = token;
- final char[] q = qualifiedPackageName;
- INamingRequestor namingRequestor = new INamingRequestor() {
- public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
- accept(
- name,
- (isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
- reusedCharacters);
- }
-
- public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
- accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX, reusedCharacters);
- }
+ private void findPackages(CompletionOnPackageReference packageStatement) {
- public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
- accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
- }
+ this.completionToken = CharOperation.concatWith(packageStatement.tokens, '.');
+ if (this.completionToken.length == 0)
+ return;
- public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
- accept(name, 0, reusedCharacters);
- }
- void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
- int l = forbiddenNames == null ? 0 : forbiddenNames.length;
- for (int i = 0; i < l; i++) {
- if (CharOperation.equals(forbiddenNames[i], name, false)) return;
- }
+ setSourceRange(packageStatement.sourceStart, packageStatement.sourceEnd);
+ long completionPosition = packageStatement.sourcePositions[packageStatement.sourcePositions.length - 1];
+ setTokenRange((int) (completionPosition >>> 32), (int) completionPosition);
+ this.nameEnvironment.findPackages(CharOperation.toLowerCase(this.completionToken), this);
+ }
- if (CharOperation.prefixEquals(t, name, false)) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForCaseMatching(t, name);
- relevance += prefixAndSuffixRelevance;
- if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
+ private void findParameterizedType(TypeReference ref, Scope scope) {
+ ReferenceBinding refBinding = (ReferenceBinding) ref.resolvedType;
+ if(refBinding != null) {
+ if (this.options.checkDeprecation &&
+ refBinding.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(refBinding))
+ return;
- // accept result
- CompletionEngine.this.noProposal = false;
- if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
- InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
- proposal.setSignature(getSignature(typeBinding));
- proposal.setPackageName(q);
- proposal.setTypeName(displayName);
- proposal.setName(name);
- proposal.setCompletion(name);
- //proposal.setFlags(Flags.AccDefault);
- proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
- proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
- proposal.setRelevance(relevance);
- CompletionEngine.this.requestor.accept(proposal);
- if(DEBUG) {
- CompletionEngine.this.printDebug(proposal);
- }
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(refBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ return;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
}
}
}
- };
- switch (kind) {
- case FIELD :
- InternalNamingConventions.suggestFieldNames(
- this.javaProject,
- qualifiedPackageName,
- qualifiedSourceName,
- dim,
- modifiers,
- token,
- discouragedNames,
- namingRequestor);
- break;
- case LOCAL :
- InternalNamingConventions.suggestLocalVariableNames(
- this.javaProject,
- qualifiedPackageName,
- qualifiedSourceName,
- dim,
- token,
- discouragedNames,
- namingRequestor);
- break;
- case ARGUMENT :
- InternalNamingConventions.suggestArgumentNames(
- this.javaProject,
- qualifiedPackageName,
- qualifiedSourceName,
- dim,
- token,
- discouragedNames,
- namingRequestor);
- break;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(refBinding.sourceName, refBinding.sourceName);
+ relevance += computeRelevanceForExpectingType(refBinding);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(accessibility); // no access restriction for type in the current unit
+
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(
+ refBinding,
+ refBinding.qualifiedSourceName(),
+ IAccessRule.K_ACCESSIBLE,
+ CharOperation.NO_CHAR,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
}
}
-
- private void findVariableNameForCollection(
- char[] token,
- char[] qualifiedPackageName,
- char[] qualifiedSourceName,
- char[] sourceName,
- final TypeBinding typeBinding,
- char[][] discouragedNames,
- final char[][] forbiddenNames,
- int kind,
- int modifiers){
- findVariableName(
- token,
- qualifiedPackageName,
- qualifiedSourceName,
- sourceName,
- typeBinding,
- discouragedNames,
- forbiddenNames,
- false,
- 1,
- kind,
- modifiers);
+ private void findSubMemberTypes(
+ char[] typeName,
+ ReferenceBinding receiverType,
+ Scope scope,
+ SourceTypeBinding typeInvocation,
+ boolean staticOnly,
+ boolean staticFieldsAndMethodOnly,
+ boolean fromStaticImport,
+ ObjectVector typesFound) {
+
+ ReferenceBinding currentType = receiverType;
+ if (typeName == null || typeName.length == 0)
+ return;
+
+ if (this.assistNodeIsSuperType && !this.insideQualifiedReference && isForbidden(currentType)) return; // we're trying to find a supertype
+
+ findMemberTypes(
+ typeName,
+ currentType.memberTypes(),
+ typesFound,
+ receiverType,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ true,
+ scope,
+ null,
+ null,
+ null,
+ false);
+
+ ReferenceBinding[] memberTypes = receiverType.memberTypes();
+ next : for (int i = 0; i < memberTypes.length; i++) {
+ if (this.options.checkVisibility) {
+ if (typeInvocation != null && !memberTypes[i].canBeSeenBy(receiverType, typeInvocation)) {
+ continue next;
+ } else if(typeInvocation == null && !memberTypes[i].canBeSeenBy(this.unitScope.fPackage)) {
+ continue next;
+ }
+ }
+ findSubMemberTypes(
+ typeName,
+ memberTypes[i],
+ scope,
+ typeInvocation,
+ staticOnly,
+ staticFieldsAndMethodOnly,
+ fromStaticImport,
+ typesFound);
+ }
}
- private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
- if(type != null &&
- type.resolvedType != null) {
- TypeBinding tb = type.resolvedType;
+ private void findTrueOrFalseKeywords(char[][] choices) {
+ if(choices == null || choices.length == 0) return;
- if (tb.problemId() == ProblemReasons.NoError &&
- tb != Scope.getBaseType(VOID)) {
- findVariableName(
- name,
- tb.leafComponentType().qualifiedPackageName(),
- tb.leafComponentType().qualifiedSourceName(),
- tb.leafComponentType().sourceName(),
- tb,
- discouragedNames,
- forbiddenNames,
- type.dimensions(),
- kind,
- modifiers);
-
- if (tb.isParameterizedType() &&
- tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
- ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
- TypeBinding[] arguments = ptb.arguments;
- if (arguments != null && arguments.length == 1) {
- TypeBinding argument = arguments[0];
- findVariableNameForCollection(
- name,
- argument.leafComponentType().qualifiedPackageName(),
- argument.leafComponentType().qualifiedSourceName(),
- argument.leafComponentType().sourceName(),
- tb,
- discouragedNames,
- forbiddenNames,
- kind,
- modifiers);
+ if(this.expectedTypesPtr != 0 || this.expectedTypes[0] != TypeBinding.BOOLEAN) return;
+
+ for (int i = 0; i < choices.length; i++) {
+ if (CharOperation.equals(choices[i], Keywords.TRUE) ||
+ CharOperation.equals(choices[i], Keywords.FALSE)
+ ){
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(CharOperation.NO_CHAR, choices[i]);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for keywors
+ relevance += computeRelevanceForExpectingType(TypeBinding.BOOLEAN);
+ relevance += computeRelevanceForQualification(false);
+ relevance += R_TRUE_OR_FALSE;
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.KEYWORD, this.actualCompletionPosition);
+ proposal.setName(choices[i]);
+ proposal.setCompletion(choices[i]);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
}
}
}
}
-
}
- private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
- if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
-
- String[] favoriteReferences = this.requestor.getFavoriteReferences();
+ private void findTypeParameters(char[] token, Scope scope) {
+ if (this.compilerOptions.sourceLevel < ClassFileConstants.JDK1_5) return;
- if (favoriteReferences == null || favoriteReferences.length == 0) return null;
+ TypeParameter[] typeParameters = null;
+ while (scope != null) { // done when a COMPILATION_UNIT_SCOPE is found
+ typeParameters = null;
+ switch (scope.kind) {
+ case Scope.METHOD_SCOPE :
+ MethodScope methodScope = (MethodScope) scope;
+ if(methodScope.referenceContext instanceof MethodDeclaration) {
+ MethodDeclaration methodDeclaration = (MethodDeclaration) methodScope.referenceContext;
+ typeParameters = methodDeclaration.typeParameters;
+ } else if(methodScope.referenceContext instanceof ConstructorDeclaration) {
+ ConstructorDeclaration methodDeclaration = (ConstructorDeclaration) methodScope.referenceContext;
+ typeParameters = methodDeclaration.typeParameters;
+ }
+ break;
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) scope;
+ typeParameters = classScope.referenceContext.typeParameters;
+ break;
+ case Scope.COMPILATION_UNIT_SCOPE :
+ return;
+ }
+ if(typeParameters != null) {
+ for (int i = 0; i < typeParameters.length; i++) {
+ int typeLength = token.length;
+ TypeParameter typeParameter = typeParameters[i];
- ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
+ if(typeParameter.binding == null) continue;
- int count = 0;
- next : for (int i = 0; i < favoriteReferences.length; i++) {
- String favoriteReference = favoriteReferences[i];
+ if (typeLength > typeParameter.name.length) continue;
- int length;
- if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
+ if (!CharOperation.prefixEquals(token, typeParameter.name, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeParameter.name))) continue;
- boolean onDemand = favoriteReference.charAt(length - 1) == '*';
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, typeParameter.name);
+ relevance += computeRelevanceForExpectingType(typeParameter.type == null ? null :typeParameter.type.resolvedType);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForException(typeParameter.name);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction fot type parameter
- char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
- if (onDemand) {
- compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeParameterProposal(typeParameter, relevance);
+ }
+ }
}
+ scope = scope.parent;
+ }
+ }
- // remove duplicate and conflicting
- for (int j = 0; j < count; j++) {
- ImportReference f = resolvedImports[j].reference;
+ private void findTypesAndPackages(char[] token, Scope scope, boolean proposeBaseTypes, boolean proposeVoidType, ObjectVector typesFound) {
- if (CharOperation.equals(f.tokens, compoundName)) continue next;
+ if (token == null)
+ return;
- if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
- if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
- continue next;
- }
+ // do not propose type if completion token is empty
+ boolean skip = false;
+ if (token.length == 0 && NO_TYPE_COMPLETION_ON_EMPTY_TOKEN) {
+ if(!this.assistNodeIsConstructor && (this.assistNodeInJavadoc & CompletionOnJavadoc.EXCEPTION) == 0) {
+ return;
}
+ skip = true;
+ }
- boolean isStatic = true;
-
- ImportReference importReference =
- new ImportReference(
- compoundName,
- new long[compoundName.length],
- onDemand,
- isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
+ boolean proposeType =
+ !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+ ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
- Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
+ boolean proposeAllMemberTypes = !this.assistNodeIsConstructor;
- if (!importBinding.isValidBinding()) {
- continue next;
+ if (!skip && proposeType && scope.enclosingSourceType() != null) {
+
+ checkTimeout();
+
+ findNestedTypes(token, scope.enclosingSourceType(), scope, proposeAllMemberTypes, typesFound);
+ if(!this.assistNodeIsInterface &&
+ !this.assistNodeIsConstructor &&
+ !this.assistNodeIsAnnotation &&
+ this.assistNodeInJavadoc == 0) {
+
+ checkTimeout();
+
+ // don't propose type parameters if the completion is a constructor ('new |')
+ findTypeParameters(token, scope);
}
+ }
- if (importBinding instanceof PackageBinding) {
- continue next;
+ boolean isEmptyPrefix = token.length == 0;
+
+ if (!skip && proposeType && this.unitScope != null) {
+
+ ReferenceBinding outerInvocationType = scope.enclosingSourceType();
+ if(outerInvocationType != null) {
+ ReferenceBinding temp = outerInvocationType.enclosingType();
+ while(temp != null) {
+ outerInvocationType = temp;
+ temp = temp.enclosingType();
+ }
}
- resolvedImports[count++] =
- new ImportBinding(compoundName, onDemand, importBinding, importReference);
- }
+ int typeLength = token.length;
+ SourceTypeBinding[] types = this.unitScope.topLevelTypes;
- if (resolvedImports.length > count)
- System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
+ next : for (int i = 0, length = types.length; i < length; i++) {
+
+ checkTimeout();
+
+ SourceTypeBinding sourceType = types[i];
- return this.favoriteReferenceBindings = resolvedImports;
- }
+ if(isForbidden(sourceType)) continue next;
- public AssistParser getParser() {
+ if(proposeAllMemberTypes &&
+ sourceType != outerInvocationType) {
+ findSubMemberTypes(
+ token,
+ sourceType,
+ scope,
+ scope.enclosingSourceType(),
+ false,
+ false,
+ false,
+ typesFound);
+ }
- return this.parser;
- }
+ if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue next;
+ if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue next;
- private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
- char[] result = null;
- StringBuffer sig = new StringBuffer(10);
- if (!referenceBinding.isMemberType()) {
- char[] typeSig = referenceBinding.genericTypeSignature();
- sig.append(typeSig, 0, typeSig.length);
- } else if (!this.insideQualifiedReference) {
- if (referenceBinding.isStatic()) {
- char[] typeSig = referenceBinding.signature();
- sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+ if (typeLength > sourceType.sourceName.length) continue next;
- TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
- if (typeVariables != Binding.NO_TYPE_VARIABLES) {
- sig.append(Signature.C_GENERIC_START);
- for (int i = 0, length = typeVariables.length; i < length; i++) {
- sig.append(typeVariables[i].genericTypeSignature());
- }
- sig.append(Signature.C_GENERIC_END);
+ if (!CharOperation.prefixEquals(token, sourceType.sourceName, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
+
+ if (this.assistNodeIsAnnotation && !hasPossibleAnnotationTarget(sourceType, scope)) {
+ continue next;
}
- sig.append(Signature.C_SEMICOLON);
- } else {
- char[] typeSig = referenceBinding.genericTypeSignature();
- sig.append(typeSig, 0, typeSig.length);
- }
- } else {
- ReferenceBinding enclosingType = referenceBinding.enclosingType();
- if (enclosingType.isParameterizedType()) {
- char[] typeSig = referenceBinding.genericTypeSignature();
- sig.append(typeSig, 0, typeSig.length-1);
- TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
- if (typeVariables != Binding.NO_TYPE_VARIABLES) {
- sig.append(Signature.C_GENERIC_START);
- for (int i = 0, length = typeVariables.length; i < length; i++) {
- sig.append(typeVariables[i].genericTypeSignature());
- }
- sig.append(Signature.C_GENERIC_END);
+ for (int j = typesFound.size; --j >= 0;) {
+ ReferenceBinding otherType = (ReferenceBinding) typesFound.elementAt(j);
+
+ if (sourceType == otherType) continue next;
}
- } else {
- char[] typeSig = referenceBinding.signature();
- sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
- if (referenceBinding.isStatic()) {
- TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
- if (typeVariables != Binding.NO_TYPE_VARIABLES) {
- sig.append(Signature.C_GENERIC_START);
- for (int i = 0, length = typeVariables.length; i < length; i++) {
- sig.append(typeVariables[i].genericTypeSignature());
- }
- sig.append(Signature.C_GENERIC_END);
+ this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
+
+ if(this.assistNodeIsClass) {
+ if(!sourceType.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!sourceType.isInterface() && !sourceType.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!sourceType.isAnnotationType()) continue next;
+ } else if (isEmptyPrefix && this.assistNodeIsException) {
+ if (sourceType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
+ continue next;
}
}
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, sourceType.sourceName);
+ relevance += computeRelevanceForExpectingType(sourceType);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for type in the current unit
+
+ if (sourceType.isAnnotationType()) {
+ relevance += computeRelevanceForAnnotation();
+ relevance += computeRelevanceForAnnotationTarget(sourceType);
+ } else if (sourceType.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ } else if(sourceType.isClass()){
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(sourceType.sourceName);
+ }
+ this.noProposal = false;
+ if(proposeType) {
+ char[] typeName = sourceType.sourceName();
+ createTypeProposal(
+ sourceType,
+ typeName,
+ IAccessRule.K_ACCESSIBLE,
+ typeName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
+ }
}
- sig.append(Signature.C_SEMICOLON);
}
- int sigLength = sig.length();
- result = new char[sigLength];
- sig.getChars(0, sigLength, result, 0);
- result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
- return result;
- }
- private static char[] getRequiredTypeSignature(TypeBinding typeBinding) {
- char[] result = null;
- StringBuffer sig = new StringBuffer(10);
+ if(!skip && proposeType) {
+
+ checkTimeout();
+
+ findTypesFromStaticImports(token, scope, proposeAllMemberTypes, typesFound);
+ }
- sig.append(typeBinding.signature());
+ if (isEmptyPrefix && !this.assistNodeIsAnnotation) {
+ if(proposeType && this.expectedTypesPtr > -1) {
+ next : for (int i = 0; i <= this.expectedTypesPtr; i++) {
+
+ checkTimeout();
+
+ if(this.expectedTypes[i] instanceof ReferenceBinding) {
+ ReferenceBinding refBinding = (ReferenceBinding)this.expectedTypes[i];
- int sigLength = sig.length();
- result = new char[sigLength];
- sig.getChars(0, sigLength, result, 0);
- result = CharOperation.replaceOnCopy(result, '/', '.');
- return result;
- }
+ if(refBinding.isTypeVariable() && this.assistNodeIsConstructor) {
+ // don't propose type variable if the completion is a constructor ('new |')
+ continue next;
+ }
+ if (this.options.checkDeprecation &&
+ refBinding.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(refBinding))
+ continue next;
- protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
- if (this.targetedElement == TagBits.AnnotationForPackage) {
- long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
- if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
- return false;
- }
- } else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
- if (scope.parent != null &&
- scope.parent.parent != null &&
- scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
- scope.parent.parent instanceof CompilationUnitScope) {
- long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
- if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
- if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
- return false;
- }
- } else {
- if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
- return false;
- }
- }
- }
- }
- return true;
- }
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(refBinding.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(refBinding);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ continue next;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
+ }
+ }
- protected void reset() {
+ for (int j = 0; j < typesFound.size(); j++) {
+ ReferenceBinding typeFound = (ReferenceBinding)typesFound.elementAt(j);
+ if (typeFound == refBinding) {
+ continue next;
+ }
+ }
- super.reset(false);
- this.knownPkgs = new HashtableOfObject(10);
- this.knownTypes = new HashtableOfObject(10);
- }
+ boolean inSameUnit = this.unitScope.isDefinedInSameUnit(refBinding);
- private void setSourceAndTokenRange(int start, int end) {
- this.setSourceAndTokenRange(start, end, true);
- }
+ // top level types of the current unit are already proposed.
+ if(skip || !inSameUnit || (inSameUnit && refBinding.isMemberType())) {
+ char[] packageName = refBinding.qualifiedPackageName();
+ char[] typeName = refBinding.sourceName();
+ char[] completionName = typeName;
- private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
- this.setSourceRange(start, end, emptyTokenAdjstment);
- this.setTokenRange(start, end, emptyTokenAdjstment);
- }
+ boolean isQualified = false;
+ if (!this.insideQualifiedReference && !refBinding.isMemberType()) {
+ if (mustQualifyType(packageName, typeName, null, refBinding.modifiers)) {
+ if (packageName == null || packageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ continue next; // ignore types from the default package from outside it
+ completionName = CharOperation.concat(packageName, typeName, '.');
+ isQualified = true;
+ }
+ }
- private void setSourceRange(int start, int end) {
- this.setSourceRange(start, end, true);
- }
+ if(this.assistNodeIsClass) {
+ if(!refBinding.isClass()) continue next;
+ } else if(this.assistNodeIsInterface) {
+ if(!refBinding.isInterface() && !refBinding.isAnnotationType()) continue next;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!refBinding.isAnnotationType()) continue next;
+ }
- private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
- this.startPosition = start;
- if(emptyTokenAdjstment) {
- int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
- this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
- } else {
- this.endPosition = end + 1;
- }
- }
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, typeName);
+ relevance += computeRelevanceForExpectingType(refBinding);
+ relevance += computeRelevanceForQualification(isQualified);
+ relevance += computeRelevanceForRestrictions(accessibility);
- private void setTokenRange(int start, int end) {
- this.setTokenRange(start, end, true);
- }
+ if(refBinding.isClass()) {
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(typeName);
+ } else if(refBinding.isEnum()) {
+ relevance += computeRelevanceForEnum();
+ } else if(refBinding.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ }
- private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
- this.tokenStart = start;
- if(emptyTokenAdjstment) {
- int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
- this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(packageName);
+ proposal.setSignature(getSignature(refBinding));
+ proposal.setPackageName(packageName);
+ proposal.setTypeName(typeName);
+ proposal.setCompletion(completionName);
+ proposal.setFlags(refBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ proposal.setAccessibility(accessibility);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ }
+ }
+ }
} else {
- this.tokenEnd = end + 1;
+ if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.KEYWORD)) {
+ if (this.assistNodeInJavadoc == 0 || (this.assistNodeInJavadoc & CompletionOnJavadoc.BASE_TYPES) != 0) {
+ if (proposeBaseTypes) {
+ if (proposeVoidType) {
+ findKeywords(token, BASE_TYPE_NAMES, false, false);
+ } else {
+ findKeywords(token, BASE_TYPE_NAMES_WITHOUT_VOID, false, false);
+ }
+ }
+ }
+ }
+ if(proposeType) {
+ int l = typesFound.size();
+ for (int i = 0; i < l; i++) {
+ ReferenceBinding typeFound = (ReferenceBinding) typesFound.elementAt(i);
+ char[] fullyQualifiedTypeName =
+ CharOperation.concat(
+ typeFound.qualifiedPackageName(),
+ typeFound.qualifiedSourceName(),
+ '.');
+ this.knownTypes.put(fullyQualifiedTypeName, this);
+ }
+ int searchFor = IJavaSearchConstants.TYPE;
+ if(this.assistNodeIsClass) {
+ searchFor = IJavaSearchConstants.CLASS;
+ } else if(this.assistNodeIsInterface) {
+ searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
+ } else if(this.assistNodeIsEnum) {
+ searchFor = IJavaSearchConstants.ENUM;
+ } else if(this.assistNodeIsAnnotation) {
+ searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
+ }
+
+ checkTimeout();
+
+ this.nameEnvironment.findTypes(
+ token,
+ proposeAllMemberTypes,
+ this.options.camelCaseMatch,
+ searchFor,
+ this);
+ acceptTypes(scope);
+ }
+ if(!isEmptyPrefix && !this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+
+ checkTimeout();
+
+ this.nameEnvironment.findPackages(token, this);
+ }
}
}
- private char[][] computeAlreadyDefinedName(
- BlockScope scope,
- InvocationSite invocationSite) {
- ArrayList result = new ArrayList();
-
- boolean staticsOnly = false;
-
- Scope currentScope = scope;
-
- done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
-
- switch (currentScope.kind) {
-
- case Scope.METHOD_SCOPE :
- // handle the error case inside an explicit constructor call (see MethodScope>>findField)
- MethodScope methodScope = (MethodScope) currentScope;
- staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+ private void findTypesAndSubpackages(
+ char[] token,
+ PackageBinding packageBinding,
+ Scope scope) {
- //$FALL-THROUGH$
- case Scope.BLOCK_SCOPE :
- BlockScope blockScope = (BlockScope) currentScope;
+ boolean proposeType =
+ !this.requestor.isIgnored(CompletionProposal.TYPE_REF) ||
+ ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF));
- next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
- LocalVariableBinding local = blockScope.locals[i];
+ char[] qualifiedName =
+ CharOperation.concatWith(packageBinding.compoundName, token, '.');
- if (local == null)
- break next;
+ if (token == null || token.length == 0) {
+ int length = qualifiedName.length;
+ System.arraycopy(
+ qualifiedName,
+ 0,
+ qualifiedName = new char[length + 1],
+ 0,
+ length);
+ qualifiedName[length] = '.';
+ }
- if (local.isSecret())
- continue next;
+ this.qualifiedCompletionToken = qualifiedName;
- result.add(local.name);
- }
- break;
+ if (proposeType && this.unitScope != null) {
+ int typeLength = qualifiedName.length;
+ SourceTypeBinding[] types = this.unitScope.topLevelTypes;
- case Scope.CLASS_SCOPE :
- ClassScope classScope = (ClassScope) currentScope;
- SourceTypeBinding enclosingType = classScope.referenceContext.binding;
- computeAlreadyDefinedName(
- enclosingType,
- classScope,
- staticsOnly,
- invocationSite,
- result);
- staticsOnly |= enclosingType.isStatic();
- break;
+ for (int i = 0, length = types.length; i < length; i++) {
+
+ checkTimeout();
+
+ SourceTypeBinding sourceType = types[i];
- case Scope.COMPILATION_UNIT_SCOPE :
- break done1;
- }
- currentScope = currentScope.parent;
- }
+ char[] qualifiedSourceTypeName = CharOperation.concatWith(sourceType.compoundName, '.');
- if (result.size() == 0) return CharOperation.NO_CHAR_CHAR;
+ if (sourceType.sourceName == CompletionParser.FAKE_TYPE_NAME) continue;
+ if (sourceType.sourceName == TypeConstants.PACKAGE_INFO_NAME) continue;
+ if (typeLength > qualifiedSourceTypeName.length) continue;
+ if (!(packageBinding == sourceType.getPackage())) continue;
- return (char[][])result.toArray(new char[result.size()][]);
- }
+ if (!CharOperation.prefixEquals(qualifiedName, qualifiedSourceTypeName, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, sourceType.sourceName))) continue;
- private void computeAlreadyDefinedName(
- SourceTypeBinding receiverType,
- ClassScope scope,
- boolean onlyStaticFields,
- InvocationSite invocationSite,
- ArrayList result) {
+ if (this.options.checkDeprecation &&
+ sourceType.isViewedAsDeprecated() &&
+ !scope.isDefinedInSameUnit(sourceType))
+ continue;
- ReferenceBinding currentType = receiverType;
- ReferenceBinding[] interfacesToVisit = null;
- int nextPosition = 0;
- do {
- ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- if (interfacesToVisit == null) {
- interfacesToVisit = itsInterfaces;
- nextPosition = interfacesToVisit.length;
- } else {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
+ int accessibility = IAccessRule.K_ACCESSIBLE;
+ if(sourceType.hasRestrictedAccess()) {
+ AccessRestriction accessRestriction = this.lookupEnvironment.getAccessRestriction(sourceType);
+ if(accessRestriction != null) {
+ switch (accessRestriction.getProblemId()) {
+ case IProblem.ForbiddenReference:
+ if (this.options.checkForbiddenReference) {
+ continue;
+ }
+ accessibility = IAccessRule.K_NON_ACCESSIBLE;
+ break;
+ case IProblem.DiscouragedReference:
+ if (this.options.checkDiscouragedReference) {
+ continue;
+ }
+ accessibility = IAccessRule.K_DISCOURAGED;
+ break;
+ }
}
}
- }
- FieldBinding[] fields = currentType.availableFields();
- if(fields != null && fields.length > 0) {
- computeAlreadyDefinedName(
- fields,
- scope,
- onlyStaticFields,
- receiverType,
- invocationSite,
- result);
- }
- currentType = currentType.superclass();
- } while ( currentType != null);
+ this.knownTypes.put(CharOperation.concat(sourceType.qualifiedPackageName(), sourceType.sourceName(), '.'), this);
- if (interfacesToVisit != null) {
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding anInterface = interfacesToVisit[i];
- FieldBinding[] fields = anInterface.availableFields();
- if(fields != null) {
- computeAlreadyDefinedName(
- fields,
- scope,
- onlyStaticFields,
- receiverType,
- invocationSite,
- result);
- }
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(qualifiedName, qualifiedSourceTypeName);
+ relevance += computeRelevanceForExpectingType(sourceType);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(accessibility);
- ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
- }
+ if (sourceType.isAnnotationType()) {
+ relevance += computeRelevanceForAnnotation();
+ } else if (sourceType.isInterface()) {
+ relevance += computeRelevanceForInterface();
+ } else if (sourceType.isClass()) {
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(sourceType.sourceName);
+ }
+ this.noProposal = false;
+ if(proposeType) {
+ char[] typeName = sourceType.sourceName();
+ createTypeProposal(
+ sourceType,
+ typeName,
+ IAccessRule.K_ACCESSIBLE,
+ typeName,
+ relevance,
+ null,
+ null,
+ null,
+ false);
}
}
}
- }
-
- private void computeAlreadyDefinedName(
- FieldBinding[] fields,
- Scope scope,
- boolean onlyStaticFields,
- ReferenceBinding receiverType,
- InvocationSite invocationSite,
- ArrayList result) {
-
- next : for (int f = fields.length; --f >= 0;) {
- FieldBinding field = fields[f];
-
- if (field.isSynthetic()) continue next;
-
- if (onlyStaticFields && !field.isStatic()) continue next;
- if (!field.canBeSeenBy(receiverType, invocationSite, scope)) continue next;
-
- result.add(field.name);
+ if(proposeType) {
+ int searchFor = IJavaSearchConstants.TYPE;
+ if(this.assistNodeIsClass) {
+ searchFor = IJavaSearchConstants.CLASS;
+ } else if(this.assistNodeIsInterface) {
+ searchFor = IJavaSearchConstants.INTERFACE_AND_ANNOTATION;
+ } else if(this.assistNodeIsEnum) {
+ searchFor = IJavaSearchConstants.ENUM;
+ } else if(this.assistNodeIsAnnotation) {
+ searchFor = IJavaSearchConstants.ANNOTATION_TYPE;
+ }
+
+ checkTimeout();
+
+ this.nameEnvironment.findTypes(
+ qualifiedName,
+ false,
+ this.options.camelCaseMatch,
+ searchFor,
+ this);
+ acceptTypes(scope);
}
- }
-
- int computeBaseRelevance(){
- return R_DEFAULT;
- }
- int computeRelevanceForResolution(){
- return computeRelevanceForResolution(true);
- }
- int computeRelevanceForResolution(boolean isResolved){
- if (isResolved) {
- return R_RESOLVED;
+ if(!this.requestor.isIgnored(CompletionProposal.PACKAGE_REF)) {
+ this.nameEnvironment.findPackages(qualifiedName, this);
}
- return 0;
}
- private void computeExpectedTypes(ASTNode parent, ASTNode node, Scope scope){
- // default filter
- this.expectedTypesFilter = SUBTYPE;
- this.hasJavaLangObjectAsExpectedType = false;
+ private void findTypesFromStaticImports(char[] token, Scope scope, boolean proposeAllMemberTypes, ObjectVector typesFound) {
+ ImportBinding[] importBindings = scope.compilationUnitScope().imports;
+ for (int i = 0; i < importBindings.length; i++) {
+ ImportBinding importBinding = importBindings[i];
+ if(importBinding.isValidBinding() && importBinding.isStatic()) {
+ Binding binding = importBinding.resolvedImport;
+ if(binding != null && binding.isValidBinding()) {
+ if(importBinding.onDemand) {
+ if((binding.kind() & Binding.TYPE) != 0) {
+ this.findMemberTypes(
+ token,
+ (ReferenceBinding) binding,
+ scope,
+ scope.enclosingSourceType(),
+ true,
+ false,
+ true,
+ true,
+ proposeAllMemberTypes,
+ null,
+ typesFound,
+ null,
+ null,
+ null,
+ false);
+ }
+ } else {
+ if ((binding.kind() & Binding.TYPE) != 0) {
+ ReferenceBinding typeBinding = (ReferenceBinding) binding;
+ int typeLength = token.length;
- // find types from parent
- if(parent instanceof AbstractVariableDeclaration) {
- AbstractVariableDeclaration variable = (AbstractVariableDeclaration)parent;
- TypeBinding binding = variable.type.resolvedType;
- if(binding != null) {
- if(!(variable.initialization instanceof ArrayInitializer)) {
- addExpectedType(binding, scope);
- }
- }
- } else if(parent instanceof Assignment) {
- TypeBinding binding = ((Assignment)parent).lhs.resolvedType;
- if(binding != null) {
- addExpectedType(binding, scope);
- }
- } else if(parent instanceof ReturnStatement) {
- if(scope.methodScope().referenceContext instanceof AbstractMethodDeclaration) {
- MethodBinding methodBinding = ((AbstractMethodDeclaration) scope.methodScope().referenceContext).binding;
- TypeBinding binding = methodBinding == null ? null : methodBinding.returnType;
- if(binding != null) {
- addExpectedType(binding, scope);
- }
- }
- } else if(parent instanceof CastExpression) {
- Expression e = ((CastExpression)parent).type;
- TypeBinding binding = e.resolvedType;
- if(binding != null){
- addExpectedType(binding, scope);
- this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
- }
- } else if(parent instanceof MessageSend) {
- MessageSend messageSend = (MessageSend) parent;
+ if (!typeBinding.isStatic()) continue;
- if(messageSend.actualReceiverType instanceof ReferenceBinding) {
- ReferenceBinding binding = (ReferenceBinding)messageSend.actualReceiverType;
- boolean isStatic = messageSend.receiver.isTypeReference();
+ if (typeLength > typeBinding.sourceName.length) continue;
- while(binding != null) {
- computeExpectedTypesForMessageSend(
- binding,
- messageSend.selector,
- messageSend.arguments,
- (ReferenceBinding)messageSend.actualReceiverType,
- scope,
- messageSend,
- isStatic);
- computeExpectedTypesForMessageSendForInterface(
- binding,
- messageSend.selector,
- messageSend.arguments,
- (ReferenceBinding)messageSend.actualReceiverType,
- scope,
- messageSend,
- isStatic);
- binding = binding.superclass();
- }
- }
- } else if(parent instanceof AllocationExpression) {
- AllocationExpression allocationExpression = (AllocationExpression) parent;
+ if (!CharOperation.prefixEquals(token, typeBinding.sourceName, false)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, typeBinding.sourceName))) continue;
- ReferenceBinding binding = (ReferenceBinding)allocationExpression.type.resolvedType;
+ if (typesFound.contains(typeBinding)) continue;
- if(binding != null) {
- computeExpectedTypesForAllocationExpression(
- binding,
- allocationExpression.arguments,
- scope,
- allocationExpression);
- }
- } else if(parent instanceof OperatorExpression) {
- int operator = (parent.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
- if(parent instanceof ConditionalExpression) {
- // for future use
- } else if(parent instanceof InstanceOfExpression) {
- InstanceOfExpression e = (InstanceOfExpression) parent;
- TypeBinding binding = e.expression.resolvedType;
- if(binding != null){
- addExpectedType(binding, scope);
- this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
- }
- } else if(parent instanceof BinaryExpression) {
- BinaryExpression binaryExpression = (BinaryExpression) parent;
- switch(operator) {
- case OperatorIds.EQUAL_EQUAL :
- // expected type is not relevant in this case
- TypeBinding binding = binaryExpression.left.resolvedType;
- if (binding != null) {
- addExpectedType(binding, scope);
- this.expectedTypesFilter = SUBTYPE | SUPERTYPE;
- }
- break;
- case OperatorIds.PLUS :
- addExpectedType(TypeBinding.SHORT, scope);
- addExpectedType(TypeBinding.INT, scope);
- addExpectedType(TypeBinding.LONG, scope);
- addExpectedType(TypeBinding.FLOAT, scope);
- addExpectedType(TypeBinding.DOUBLE, scope);
- addExpectedType(TypeBinding.CHAR, scope);
- addExpectedType(TypeBinding.BYTE, scope);
- addExpectedType(scope.getJavaLangString(), scope);
- break;
- case OperatorIds.AND_AND :
- case OperatorIds.OR_OR :
- case OperatorIds.XOR :
- addExpectedType(TypeBinding.BOOLEAN, scope);
- break;
- default :
- addExpectedType(TypeBinding.SHORT, scope);
- addExpectedType(TypeBinding.INT, scope);
- addExpectedType(TypeBinding.LONG, scope);
- addExpectedType(TypeBinding.FLOAT, scope);
- addExpectedType(TypeBinding.DOUBLE, scope);
- addExpectedType(TypeBinding.CHAR, scope);
- addExpectedType(TypeBinding.BYTE, scope);
- break;
- }
- if(operator == OperatorIds.LESS) {
- if(binaryExpression.left instanceof SingleNameReference){
- SingleNameReference name = (SingleNameReference) binaryExpression.left;
- Binding b = scope.getBinding(name.token, Binding.VARIABLE | Binding.TYPE, name, false);
- if(b instanceof ReferenceBinding) {
- TypeVariableBinding[] typeVariableBindings =((ReferenceBinding)b).typeVariables();
- if(typeVariableBindings != null && typeVariableBindings.length > 0) {
- addExpectedType(typeVariableBindings[0].firstBound, scope);
+ typesFound.add(typeBinding);
+
+ if(this.assistNodeIsClass) {
+ if(!typeBinding.isClass()) continue;
+ } else if(this.assistNodeIsInterface) {
+ if(!typeBinding.isInterface() && !typeBinding.isAnnotationType()) continue;
+ } else if (this.assistNodeIsAnnotation) {
+ if(!typeBinding.isAnnotationType()) continue;
+ }
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(token, typeBinding.sourceName);
+ relevance += computeRelevanceForExpectingType(typeBinding);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE);
+
+ if (typeBinding.isClass()) {
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(typeBinding.sourceName);
+ } else if(typeBinding.isEnum()) {
+ relevance += computeRelevanceForEnum();
+ } else if(typeBinding.isInterface()) {
+ relevance += computeRelevanceForInterface();
}
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.TYPE_REF, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(typeBinding.qualifiedPackageName());
+ proposal.setSignature(getSignature(typeBinding));
+ proposal.setPackageName(typeBinding.qualifiedPackageName());
+ proposal.setTypeName(typeBinding.qualifiedSourceName());
+ proposal.setCompletion(typeBinding.sourceName());
+ proposal.setFlags(typeBinding.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
}
}
}
- } else if(parent instanceof UnaryExpression) {
- switch(operator) {
- case OperatorIds.NOT :
- addExpectedType(TypeBinding.BOOLEAN, scope);
- break;
- case OperatorIds.TWIDDLE :
- addExpectedType(TypeBinding.SHORT, scope);
- addExpectedType(TypeBinding.INT, scope);
- addExpectedType(TypeBinding.LONG, scope);
- addExpectedType(TypeBinding.CHAR, scope);
- addExpectedType(TypeBinding.BYTE, scope);
- break;
- case OperatorIds.PLUS :
- case OperatorIds.MINUS :
- case OperatorIds.PLUS_PLUS :
- case OperatorIds.MINUS_MINUS :
- addExpectedType(TypeBinding.SHORT, scope);
- addExpectedType(TypeBinding.INT, scope);
- addExpectedType(TypeBinding.LONG, scope);
- addExpectedType(TypeBinding.FLOAT, scope);
- addExpectedType(TypeBinding.DOUBLE, scope);
- addExpectedType(TypeBinding.CHAR, scope);
- addExpectedType(TypeBinding.BYTE, scope);
- break;
+ }
+ }
+ }
+
+ private void findUnresolvedReference(int completedNameStart, int completedNameEnd, BlockScope scope, char[][] discouragedNames) {
+ char[][] foundNames = findUnresolvedReferenceBefore(completedNameStart - 1, completedNameEnd, scope, discouragedNames);
+ if (foundNames != null && foundNames.length > 1) {
+ int discouragedNamesLength = discouragedNames.length;
+ int foundNamesLength = foundNames.length;
+ int newLength = discouragedNamesLength + foundNamesLength;
+ System.arraycopy(discouragedNames, 0, discouragedNames = new char[newLength][], 0, discouragedNamesLength);
+ System.arraycopy(foundNames, 0, discouragedNames, discouragedNamesLength, foundNamesLength);
+ }
+ findUnresolvedReferenceAfter(completedNameEnd + 1, scope, discouragedNames);
+ }
+
+ private char[][] findUnresolvedReferenceAfter(int from, BlockScope scope, final char[][] discouragedNames) {
+ final ArrayList proposedNames = new ArrayList();
+
+ UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+ new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+ public void acceptName(char[] name) {
+ CompletionEngine.this.acceptUnresolvedName(name);
+ proposedNames.add(name);
}
- }
- } else if(parent instanceof ArrayReference) {
- addExpectedType(TypeBinding.SHORT, scope);
- addExpectedType(TypeBinding.INT, scope);
- addExpectedType(TypeBinding.LONG, scope);
- } else if(parent instanceof ParameterizedSingleTypeReference) {
- ParameterizedSingleTypeReference ref = (ParameterizedSingleTypeReference) parent;
- TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
- int length = ref.typeArguments == null ? 0 : ref.typeArguments.length;
- if(typeVariables != null && typeVariables.length >= length) {
- int index = length - 1;
- while(index > -1 && ref.typeArguments[index] != node) index--;
+ };
- TypeBinding bound = typeVariables[index].firstBound;
- addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
- }
- } else if(parent instanceof ParameterizedQualifiedTypeReference) {
- ParameterizedQualifiedTypeReference ref = (ParameterizedQualifiedTypeReference) parent;
- TypeVariableBinding[] typeVariables = ((ReferenceBinding)ref.resolvedType).typeVariables();
- TypeReference[][] arguments = ref.typeArguments;
- if(typeVariables != null) {
- int iLength = arguments == null ? 0 : arguments.length;
- done: for (int i = 0; i < iLength; i++) {
- int jLength = arguments[i] == null ? 0 : arguments[i].length;
- for (int j = 0; j < jLength; j++) {
- if(arguments[i][j] == node && typeVariables.length > j) {
- TypeBinding bound = typeVariables[j].firstBound;
- addExpectedType(bound == null ? scope.getJavaLangObject() : bound, scope);
+ ReferenceContext referenceContext = scope.referenceContext();
+ if (referenceContext instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.findAfter(
+ this.completionToken,
+ md.scope,
+ md.scope.classScope(),
+ from,
+ md.bodyEnd,
+ discouragedNames,
+ nameRequestor);
+ } else if (referenceContext instanceof TypeDeclaration) {
+ TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+ FieldDeclaration[] fields = typeDeclaration.fields;
+ if (fields != null) {
+ done : for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof Initializer) {
+ Initializer initializer = (Initializer) fields[i];
+ if (initializer.block.sourceStart <= from &&
+ from < initializer.bodyEnd) {
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.findAfter(
+ this.completionToken,
+ typeDeclaration.scope,
+ typeDeclaration.scope,
+ from,
+ initializer.bodyEnd,
+ discouragedNames,
+ nameRequestor);
break done;
}
}
}
}
- } else if(parent instanceof MemberValuePair) {
- MemberValuePair memberValuePair = (MemberValuePair) parent;
- if(memberValuePair.binding != null) {
- addExpectedType(memberValuePair.binding.returnType, scope);
- }
- } else if (parent instanceof NormalAnnotation) {
- NormalAnnotation annotation = (NormalAnnotation) parent;
- MemberValuePair[] memberValuePairs = annotation.memberValuePairs();
- if(memberValuePairs == null || memberValuePairs.length == 0) {
- if(annotation.resolvedType instanceof ReferenceBinding) {
- MethodBinding[] methodBindings =
- ((ReferenceBinding)annotation.resolvedType).availableMethods();
- if (methodBindings != null &&
- methodBindings.length > 0 &&
- CharOperation.equals(methodBindings[0].selector, VALUE)) {
- boolean canBeSingleMemberAnnotation = true;
- done : for (int i = 1; i < methodBindings.length; i++) {
- if((methodBindings[i].modifiers & ClassFileConstants.AccAnnotationDefault) == 0) {
- canBeSingleMemberAnnotation = false;
+ }
+
+ int proposedNamesCount = proposedNames.size();
+ if (proposedNamesCount > 0) {
+ return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+ }
+
+ return null;
+ }
+
+ private char[][] findUnresolvedReferenceBefore(int recordTo, int parseTo, BlockScope scope, final char[][] discouragedNames) {
+ final ArrayList proposedNames = new ArrayList();
+
+ UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+ new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+ public void acceptName(char[] name) {
+ CompletionEngine.this.acceptUnresolvedName(name);
+ proposedNames.add(name);
+ }
+ };
+
+ BlockScope upperScope = scope;
+ while (upperScope.enclosingMethodScope() != null) {
+ upperScope = upperScope.enclosingMethodScope();
+ }
+
+ ReferenceContext referenceContext = upperScope.referenceContext();
+ if (referenceContext instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.findBefore(
+ this.completionToken,
+ md.scope,
+ md.scope.classScope(),
+ md.bodyStart,
+ recordTo,
+ parseTo,
+ discouragedNames,
+ nameRequestor);
+ } else if (referenceContext instanceof TypeDeclaration) {
+ TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+
+
+ done : {
+ FieldDeclaration[] fields = typeDeclaration.fields;
+ if (fields != null) {
+ for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof Initializer) {
+ Initializer initializer = (Initializer) fields[i];
+ if (initializer.block.sourceStart <= recordTo &&
+ recordTo < initializer.bodyEnd) {
+
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.findBefore(
+ this.completionToken,
+ typeDeclaration.scope,
+ typeDeclaration.scope,
+ initializer.block.sourceStart,
+ recordTo,
+ parseTo,
+ discouragedNames,
+ nameRequestor);
break done;
}
}
- if (canBeSingleMemberAnnotation) {
- this.assistNodeCanBeSingleMemberAnnotation = canBeSingleMemberAnnotation;
- addExpectedType(methodBindings[0].returnType, scope);
- }
}
}
}
- } else if (parent instanceof TryStatement) {
- boolean isException = false;
- if (node instanceof CompletionOnSingleTypeReference) {
- isException = ((CompletionOnSingleTypeReference)node).isException();
- } else if (node instanceof CompletionOnQualifiedTypeReference) {
- isException = ((CompletionOnQualifiedTypeReference)node).isException();
- } else if (node instanceof CompletionOnParameterizedQualifiedTypeReference) {
- isException = ((CompletionOnParameterizedQualifiedTypeReference)node).isException();
- }
- if (isException) {
- ThrownExceptionFinder thrownExceptionFinder = new ThrownExceptionFinder();
- ReferenceBinding[] bindings = thrownExceptionFinder.find((TryStatement) parent, (BlockScope)scope);
- if (bindings != null && bindings.length > 0) {
- for (int i = 0; i < bindings.length; i++) {
- addExpectedType(bindings[i], scope);
+ }
+
+ int proposedNamesCount = proposedNames.size();
+ if (proposedNamesCount > 0) {
+ return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+ }
+
+ return null;
+ }
+
+ private char[][] findVariableFromUnresolvedReference(LocalDeclaration variable, BlockScope scope, final char[][] discouragedNames) {
+ final TypeReference type = variable.type;
+ if(type != null &&
+ type.resolvedType != null &&
+ type.resolvedType.problemId() == ProblemReasons.NoError){
+
+ final ArrayList proposedNames = new ArrayList();
+
+ UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor nameRequestor =
+ new UnresolvedReferenceNameFinder.UnresolvedReferenceNameRequestor() {
+ public void acceptName(char[] name) {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(CompletionEngine.this.completionToken, name);
+ relevance += R_NAME_FIRST_PREFIX;
+ relevance += R_NAME_FIRST_SUFFIX;
+ relevance += R_NAME_LESS_NEW_CHARACTERS;
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
+
+ // accept result
+ CompletionEngine.this.noProposal = false;
+ if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
+ proposal.setSignature(getSignature(type.resolvedType));
+ proposal.setPackageName(type.resolvedType.qualifiedPackageName());
+ proposal.setTypeName(type.resolvedType.qualifiedSourceName());
+ proposal.setName(name);
+ proposal.setCompletion(name);
+ //proposal.setFlags(Flags.AccDefault);
+ proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
+ proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
+ proposal.setRelevance(relevance);
+ CompletionEngine.this.requestor.accept(proposal);
+ if(DEBUG) {
+ CompletionEngine.this.printDebug(proposal);
+ }
+ }
+ proposedNames.add(name);
}
- this.expectedTypesFilter = SUPERTYPE;
- }
- }
- } else if (parent instanceof SwitchStatement) {
- SwitchStatement switchStatement = (SwitchStatement) parent;
- if (switchStatement.expression != null &&
- switchStatement.expression.resolvedType != null) {
- addExpectedType(switchStatement.expression.resolvedType, scope);
- }
+ };
- // Expected types for javadoc
- } else if (parent instanceof Javadoc) {
- if (scope.kind == Scope.METHOD_SCOPE) {
- MethodScope methodScope = (MethodScope) scope;
- AbstractMethodDeclaration methodDecl = methodScope.referenceMethod();
- if (methodDecl != null && methodDecl.binding != null) {
- ReferenceBinding[] exceptions = methodDecl.binding.thrownExceptions;
- if (exceptions != null) {
- for (int i = 0; i < exceptions.length; i++) {
- addExpectedType(exceptions[i], scope);
+ ReferenceContext referenceContext = scope.referenceContext();
+ if (referenceContext instanceof AbstractMethodDeclaration) {
+ AbstractMethodDeclaration md = (AbstractMethodDeclaration)referenceContext;
+
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.find(
+ this.completionToken,
+ md,
+ variable.declarationSourceEnd + 1,
+ discouragedNames,
+ nameRequestor);
+ } else if (referenceContext instanceof TypeDeclaration) {
+ TypeDeclaration typeDeclaration = (TypeDeclaration) referenceContext;
+ FieldDeclaration[] fields = typeDeclaration.fields;
+ if (fields != null) {
+ done : for (int i = 0; i < fields.length; i++) {
+ if (fields[i] instanceof Initializer) {
+ Initializer initializer = (Initializer) fields[i];
+ if (initializer.bodyStart <= variable.sourceStart &&
+ variable.sourceStart < initializer.bodyEnd) {
+ UnresolvedReferenceNameFinder nameFinder = new UnresolvedReferenceNameFinder(this);
+ nameFinder.find(
+ this.completionToken,
+ initializer,
+ typeDeclaration.scope,
+ variable.declarationSourceEnd + 1,
+ discouragedNames,
+ nameRequestor);
+ break done;
+ }
}
}
}
}
- }
- if(this.expectedTypesPtr + 1 != this.expectedTypes.length) {
- System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[this.expectedTypesPtr + 1], 0, this.expectedTypesPtr + 1);
+ int proposedNamesCount = proposedNames.size();
+ if (proposedNamesCount > 0) {
+ return (char[][])proposedNames.toArray(new char[proposedNamesCount][]);
+ }
}
+
+ return null;
}
- private void computeExpectedTypesForAllocationExpression(
- ReferenceBinding binding,
- Expression[] arguments,
- Scope scope,
- InvocationSite invocationSite) {
+ private void findVariableName(
+ char[] token,
+ char[] qualifiedPackageName,
+ char[] qualifiedSourceName,
+ char[] sourceName,
+ final TypeBinding typeBinding,
+ char[][] discouragedNames,
+ final char[][] forbiddenNames,
+ boolean forCollection,
+ int dim,
+ int kind,
+ int modifiers){
- MethodBinding[] methods = binding.availableMethods();
- nextMethod : for (int i = 0; i < methods.length; i++) {
- MethodBinding method = methods[i];
+ if(sourceName == null || sourceName.length == 0)
+ return;
- if (!method.isConstructor()) continue nextMethod;
+ // compute variable name for non base type
+ final char[] displayName;
+ if (!forCollection) {
+ if (dim > 0){
+ int l = qualifiedSourceName.length;
+ displayName = new char[l+(2*dim)];
+ System.arraycopy(qualifiedSourceName, 0, displayName, 0, l);
+ for(int i = 0; i < dim; i++){
+ displayName[l+(i*2)] = '[';
+ displayName[l+(i*2)+1] = ']';
+ }
+ } else {
+ displayName = qualifiedSourceName;
+ }
+ } else {
+ displayName = typeBinding.qualifiedSourceName();
+ }
- if (method.isSynthetic()) continue nextMethod;
+ final char[] t = token;
+ final char[] q = qualifiedPackageName;
+ INamingRequestor namingRequestor = new INamingRequestor() {
+ void accept(char[] name, int prefixAndSuffixRelevance, int reusedCharacters){
+ int l = forbiddenNames == null ? 0 : forbiddenNames.length;
+ for (int i = 0; i < l; i++) {
+ if (CharOperation.equals(forbiddenNames[i], name, false)) return;
+ }
- if (this.options.checkVisibility && !method.canBeSeenBy(invocationSite, scope)) continue nextMethod;
+ if (CharOperation.prefixEquals(t, name, false)) {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForCaseMatching(t, name);
+ relevance += prefixAndSuffixRelevance;
+ if(reusedCharacters > 0) relevance += R_NAME_LESS_NEW_CHARACTERS;
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for variable name
- TypeBinding[] parameters = method.parameters;
- if(parameters.length < arguments.length)
- continue nextMethod;
+ // accept result
+ CompletionEngine.this.noProposal = false;
+ if(!CompletionEngine.this.requestor.isIgnored(CompletionProposal.VARIABLE_DECLARATION)) {
+ InternalCompletionProposal proposal = CompletionEngine.this.createProposal(CompletionProposal.VARIABLE_DECLARATION, CompletionEngine.this.actualCompletionPosition);
+ proposal.setSignature(getSignature(typeBinding));
+ proposal.setPackageName(q);
+ proposal.setTypeName(displayName);
+ proposal.setName(name);
+ proposal.setCompletion(name);
+ //proposal.setFlags(Flags.AccDefault);
+ proposal.setReplaceRange(CompletionEngine.this.startPosition - CompletionEngine.this.offset, CompletionEngine.this.endPosition - CompletionEngine.this.offset);
+ proposal.setTokenRange(CompletionEngine.this.tokenStart - CompletionEngine.this.offset, CompletionEngine.this.tokenEnd - CompletionEngine.this.offset);
+ proposal.setRelevance(relevance);
+ CompletionEngine.this.requestor.accept(proposal);
+ if(DEBUG) {
+ CompletionEngine.this.printDebug(proposal);
+ }
+ }
+ }
+ }
- int length = arguments.length - 1;
+ public void acceptNameWithoutPrefixAndSuffix(char[] name,int reusedCharacters) {
+ accept(name, 0, reusedCharacters);
+ }
- for (int j = 0; j < length; j++) {
- Expression argument = arguments[j];
- TypeBinding argType = argument.resolvedType;
- if(argType != null && !argType.isCompatibleWith(parameters[j]))
- continue nextMethod;
+ public void acceptNameWithPrefix(char[] name, boolean isFirstPrefix, int reusedCharacters) {
+ accept(name, isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX, reusedCharacters);
}
- TypeBinding expectedType = method.parameters[arguments.length - 1];
- if(expectedType != null) {
- addExpectedType(expectedType, scope);
+ public void acceptNameWithPrefixAndSuffix(char[] name, boolean isFirstPrefix, boolean isFirstSuffix, int reusedCharacters) {
+ accept(
+ name,
+ (isFirstPrefix ? R_NAME_FIRST_PREFIX : R_NAME_PREFIX) + (isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX),
+ reusedCharacters);
+ }
+ public void acceptNameWithSuffix(char[] name, boolean isFirstSuffix, int reusedCharacters) {
+ accept(name, isFirstSuffix ? R_NAME_FIRST_SUFFIX : R_NAME_SUFFIX, reusedCharacters);
}
+ };
+
+ switch (kind) {
+ case FIELD :
+ InternalNamingConventions.suggestFieldNames(
+ this.javaProject,
+ qualifiedPackageName,
+ qualifiedSourceName,
+ dim,
+ modifiers,
+ token,
+ discouragedNames,
+ namingRequestor);
+ break;
+ case LOCAL :
+ InternalNamingConventions.suggestLocalVariableNames(
+ this.javaProject,
+ qualifiedPackageName,
+ qualifiedSourceName,
+ dim,
+ token,
+ discouragedNames,
+ namingRequestor);
+ break;
+ case ARGUMENT :
+ InternalNamingConventions.suggestArgumentNames(
+ this.javaProject,
+ qualifiedPackageName,
+ qualifiedSourceName,
+ dim,
+ token,
+ discouragedNames,
+ namingRequestor);
+ break;
}
}
- private void computeExpectedTypesForMessageSendForInterface(
- ReferenceBinding binding,
- char[] selector,
- Expression[] arguments,
- ReferenceBinding receiverType,
- Scope scope,
- InvocationSite invocationSite,
- boolean isStatic) {
-
- ReferenceBinding[] itsInterfaces = binding.superInterfaces();
- if (itsInterfaces != Binding.NO_SUPERINTERFACES) {
- ReferenceBinding[] interfacesToVisit = itsInterfaces;
- int nextPosition = interfacesToVisit.length;
+ // Helper method for private void findVariableNames(char[] name, TypeReference type )
+ private void findVariableName(
+ char[] token,
+ char[] qualifiedPackageName,
+ char[] qualifiedSourceName,
+ char[] sourceName,
+ final TypeBinding typeBinding,
+ char[][] discouragedNames,
+ final char[][] forbiddenNames,
+ int dim,
+ int kind,
+ int modifiers){
+ findVariableName(
+ token,
+ qualifiedPackageName,
+ qualifiedSourceName,
+ sourceName,
+ typeBinding,
+ discouragedNames,
+ forbiddenNames,
+ false,
+ dim,
+ kind,
+ modifiers);
+ }
+ private void findVariableNameForCollection(
+ char[] token,
+ char[] qualifiedPackageName,
+ char[] qualifiedSourceName,
+ char[] sourceName,
+ final TypeBinding typeBinding,
+ char[][] discouragedNames,
+ final char[][] forbiddenNames,
+ int kind,
+ int modifiers){
- for (int i = 0; i < nextPosition; i++) {
- ReferenceBinding currentType = interfacesToVisit[i];
- computeExpectedTypesForMessageSend(
- currentType,
- selector,
- arguments,
- receiverType,
- scope,
- invocationSite,
- isStatic);
+ findVariableName(
+ token,
+ qualifiedPackageName,
+ qualifiedSourceName,
+ sourceName,
+ typeBinding,
+ discouragedNames,
+ forbiddenNames,
+ false,
+ 1,
+ kind,
+ modifiers);
+ }
+ private void findVariableNames(char[] name, TypeReference type , char[][] discouragedNames, char[][] forbiddenNames, int kind, int modifiers){
+ if(type != null &&
+ type.resolvedType != null) {
+ TypeBinding tb = type.resolvedType;
- if ((itsInterfaces = currentType.superInterfaces()) != Binding.NO_SUPERINTERFACES) {
- int itsLength = itsInterfaces.length;
- if (nextPosition + itsLength >= interfacesToVisit.length)
- System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[nextPosition + itsLength + 5], 0, nextPosition);
- nextInterface : for (int a = 0; a < itsLength; a++) {
- ReferenceBinding next = itsInterfaces[a];
- for (int b = 0; b < nextPosition; b++)
- if (next == interfacesToVisit[b]) continue nextInterface;
- interfacesToVisit[nextPosition++] = next;
+ if (tb.problemId() == ProblemReasons.NoError &&
+ tb != Scope.getBaseType(VOID)) {
+ findVariableName(
+ name,
+ tb.leafComponentType().qualifiedPackageName(),
+ tb.leafComponentType().qualifiedSourceName(),
+ tb.leafComponentType().sourceName(),
+ tb,
+ discouragedNames,
+ forbiddenNames,
+ type.dimensions(),
+ kind,
+ modifiers);
+
+ if (tb.isParameterizedType() &&
+ tb.findSuperTypeOriginatingFrom(TypeIds.T_JavaUtilCollection, false) != null) {
+ ParameterizedTypeBinding ptb = ((ParameterizedTypeBinding) tb);
+ TypeBinding[] arguments = ptb.arguments;
+ if (arguments != null && arguments.length == 1) {
+ TypeBinding argument = arguments[0];
+ findVariableNameForCollection(
+ name,
+ argument.leafComponentType().qualifiedPackageName(),
+ argument.leafComponentType().qualifiedSourceName(),
+ argument.leafComponentType().sourceName(),
+ tb,
+ discouragedNames,
+ forbiddenNames,
+ kind,
+ modifiers);
}
}
}
}
- }
- private void computeExpectedTypesForMessageSend(
- ReferenceBinding binding,
- char[] selector,
- Expression[] arguments,
- ReferenceBinding receiverType,
+ }
+ private void findVariablesAndMethods(
+ char[] token,
Scope scope,
InvocationSite invocationSite,
- boolean isStatic) {
+ Scope invocationScope,
+ boolean insideTypeAnnotation,
+ boolean insideAnnotationAttribute) {
- MethodBinding[] methods = binding.availableMethods();
- nextMethod : for (int i = 0; i < methods.length; i++) {
- MethodBinding method = methods[i];
+ if (token == null)
+ return;
- if (method.isSynthetic()) continue nextMethod;
+ // Should local variables hide fields from the receiver type or any of its enclosing types?
+ // we know its an implicit field/method access... see BlockScope getBinding/getImplicitMethod
- if (method.isDefaultAbstract()) continue nextMethod;
+ boolean staticsOnly = false;
+ // need to know if we're in a static context (or inside a constructor)
+ int tokenLength = token.length;
- if (method.isConstructor()) continue nextMethod;
+ ObjectVector localsFound = new ObjectVector();
+ ObjectVector fieldsFound = new ObjectVector();
+ ObjectVector methodsFound = new ObjectVector();
- if (isStatic && !method.isStatic()) continue nextMethod;
+ Scope currentScope = scope;
- if (this.options.checkVisibility && !method.canBeSeenBy(receiverType, invocationSite, scope)) continue nextMethod;
+ if (!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ done1 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- if(!CharOperation.equals(method.selector, selector)) continue nextMethod;
+ switch (currentScope.kind) {
- TypeBinding[] parameters = method.parameters;
- if(parameters.length < arguments.length)
- continue nextMethod;
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) currentScope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
- int length = arguments.length - 1;
+ //$FALL-THROUGH$
+ case Scope.BLOCK_SCOPE :
+ BlockScope blockScope = (BlockScope) currentScope;
- for (int j = 0; j < length; j++) {
- Expression argument = arguments[j];
- TypeBinding argType = argument.resolvedType;
- if(argType != null && !argType.isCompatibleWith(parameters[j]))
- continue nextMethod;
- }
+ next : for (int i = 0, length = blockScope.locals.length; i < length; i++) {
+ LocalVariableBinding local = blockScope.locals[i];
- TypeBinding expectedType = method.parameters[arguments.length - 1];
- if(expectedType != null) {
- addExpectedType(expectedType, scope);
+ if (local == null)
+ break next;
+
+ if (tokenLength > local.name.length)
+ continue next;
+
+ if (!CharOperation.prefixEquals(token, local.name, false /* ignore case */)
+ && !(this.options.camelCaseMatch && CharOperation.camelCaseMatch(token, local.name)))
+ continue next;
+
+ if (local.isSecret())
+ continue next;
+
+ for (int f = 0; f < localsFound.size; f++) {
+ LocalVariableBinding otherLocal =
+ (LocalVariableBinding) localsFound.elementAt(f);
+ if (CharOperation.equals(otherLocal.name, local.name, true))
+ continue next;
+ }
+ localsFound.add(local);
+
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal(local);
+ relevance += computeRelevanceForCaseMatching(token, local.name);
+ relevance += computeRelevanceForExpectingType(local.type);
+ relevance += computeRelevanceForEnumConstant(local.type);
+ relevance += computeRelevanceForQualification(false);
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for local variable
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.LOCAL_VARIABLE_REF)) {
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.LOCAL_VARIABLE_REF, this.actualCompletionPosition);
+ proposal.setSignature(
+ local.type == null
+ ? createTypeSignature(
+ CharOperation.NO_CHAR,
+ local.declaration.type.toString().toCharArray())
+ : getSignature(local.type));
+ if(local.type == null) {
+ //proposal.setPackageName(null);
+ proposal.setTypeName(local.declaration.type.toString().toCharArray());
+ } else {
+ proposal.setPackageName(local.type.qualifiedPackageName());
+ proposal.setTypeName(local.type.qualifiedSourceName());
+ }
+ proposal.setName(local.name);
+ proposal.setCompletion(local.name);
+ proposal.setFlags(local.modifiers);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
+ }
+ }
+ break;
+
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done1;
+ }
+ currentScope = currentScope.parent;
}
}
- }
- private void addExpectedType(TypeBinding type, Scope scope){
- if (type == null || !type.isValidBinding() || type == TypeBinding.NULL) return;
+
+ checkTimeout();
- // do not add twice the same type
- for (int i = 0; i <= this.expectedTypesPtr; i++) {
- if (this.expectedTypes[i] == type) return;
- }
+ boolean proposeField = !this.requestor.isIgnored(CompletionProposal.FIELD_REF);
+ boolean proposeMethod = !this.requestor.isIgnored(CompletionProposal.METHOD_REF);
- int length = this.expectedTypes.length;
- if (++this.expectedTypesPtr >= length)
- System.arraycopy(this.expectedTypes, 0, this.expectedTypes = new TypeBinding[length * 2], 0, length);
- this.expectedTypes[this.expectedTypesPtr] = type;
+ staticsOnly = false;
+ currentScope = scope;
- if(type == scope.getJavaLangObject()) {
- this.hasJavaLangObjectAsExpectedType = true;
- }
- }
- private void addForbiddenBindings(Binding binding){
- if (binding == null) return;
+ if(proposeField || proposeMethod) {
+ done2 : while (true) { // done when a COMPILATION_UNIT_SCOPE is found
- int length = this.forbbidenBindings.length;
- if (++this.forbbidenBindingsPtr >= length)
- System.arraycopy(this.forbbidenBindings, 0, this.forbbidenBindings = new Binding[length * 2], 0, length);
- this.forbbidenBindings[this.forbbidenBindingsPtr] = binding;
+ switch (currentScope.kind) {
+ case Scope.METHOD_SCOPE :
+ // handle the error case inside an explicit constructor call (see MethodScope>>findField)
+ MethodScope methodScope = (MethodScope) currentScope;
+ staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
+ break;
+ case Scope.CLASS_SCOPE :
+ ClassScope classScope = (ClassScope) currentScope;
+ SourceTypeBinding enclosingType = classScope.referenceContext.binding;
+ /* if (tokenLength == 0) { // only search inside the type itself if no prefix was provided
+ findFields(token, enclosingType.fields(), classScope, fieldsFound, staticsOnly);
+ findMethods(token, enclosingType.methods(), classScope, methodsFound, staticsOnly, false);
+ break done;
+ } else { */
+ if(!insideTypeAnnotation) {
+ if(proposeField) {
+ findFields(
+ token,
+ enclosingType,
+ classScope,
+ fieldsFound,
+ localsFound,
+ staticsOnly,
+ invocationSite,
+ invocationScope,
+ true,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ if(proposeMethod && !insideAnnotationAttribute) {
+ findMethods(
+ token,
+ null,
+ null,
+ enclosingType,
+ classScope,
+ methodsFound,
+ staticsOnly,
+ false,
+ invocationSite,
+ invocationScope,
+ true,
+ false,
+ true,
+ null,
+ null,
+ null,
+ false,
+ null,
+ -1,
+ -1);
+ }
+ }
+ staticsOnly |= enclosingType.isStatic();
+ insideTypeAnnotation = false;
+ // }
+ break;
+
+ case Scope.COMPILATION_UNIT_SCOPE :
+ break done2;
+ }
+ currentScope = currentScope.parent;
+ }
+
+ checkTimeout();
+
+ findFieldsAndMethodsFromStaticImports(
+ token,
+ scope,
+ invocationSite,
+ invocationScope,
+ false,
+ insideAnnotationAttribute,
+ localsFound,
+ fieldsFound,
+ methodsFound,
+ proposeField,
+ proposeMethod);
+
+ if (this.assistNodeInJavadoc == 0) {
+
+ checkTimeout();
+
+ // search in favorites import
+ findFieldsAndMethodsFromFavorites(
+ token,
+ scope,
+ invocationSite,
+ invocationScope,
+ localsFound,
+ fieldsFound,
+ methodsFound);
+ }
+
+ checkTimeout();
+
+ findEnumConstantsFromExpectedTypes(
+ token,
+ invocationScope,
+ fieldsFound);
+ }
}
- private void addUninterestingBindings(Binding binding){
- if (binding == null) return;
- int length = this.uninterestingBindings.length;
- if (++this.uninterestingBindingsPtr >= length)
- System.arraycopy(this.uninterestingBindings, 0, this.uninterestingBindings = new Binding[length * 2], 0, length);
- this.uninterestingBindings[this.uninterestingBindingsPtr] = binding;
- }
+ private char[] getCompletedTypeSignature(ReferenceBinding referenceBinding) {
+ char[] result = null;
+ StringBuffer sig = new StringBuffer(10);
+ if (!referenceBinding.isMemberType()) {
+ char[] typeSig = referenceBinding.genericTypeSignature();
+ sig.append(typeSig, 0, typeSig.length);
+ } else if (!this.insideQualifiedReference) {
+ if (referenceBinding.isStatic()) {
+ char[] typeSig = referenceBinding.signature();
+ sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
- private Scope computeForbiddenBindings(ASTNode astNode, ASTNode astNodeParent, Scope scope) {
- this.forbbidenBindingsFilter = NONE;
- if(scope instanceof ClassScope) {
- TypeDeclaration typeDeclaration = ((ClassScope)scope).referenceContext;
- if(typeDeclaration.superclass == astNode) {
- addForbiddenBindings(typeDeclaration.binding);
- return scope.parent;
- }
- TypeReference[] superInterfaces = typeDeclaration.superInterfaces;
- int length = superInterfaces == null ? 0 : superInterfaces.length;
- for (int i = 0; i < length; i++) {
- if(superInterfaces[i] == astNode) {
- addForbiddenBindings(typeDeclaration.binding);
- return scope.parent;
+ TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+ if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+ sig.append(Signature.C_GENERIC_START);
+ for (int i = 0, length = typeVariables.length; i < length; i++) {
+ sig.append(typeVariables[i].genericTypeSignature());
+ }
+ sig.append(Signature.C_GENERIC_END);
}
+ sig.append(Signature.C_SEMICOLON);
+ } else {
+ char[] typeSig = referenceBinding.genericTypeSignature();
+ sig.append(typeSig, 0, typeSig.length);
}
} else {
- if (astNodeParent != null && astNodeParent instanceof TryStatement) {
- boolean isException = false;
- if (astNode instanceof CompletionOnSingleTypeReference) {
- isException = ((CompletionOnSingleTypeReference)astNode).isException();
- } else if (astNode instanceof CompletionOnQualifiedTypeReference) {
- isException = ((CompletionOnQualifiedTypeReference)astNode).isException();
- } else if (astNode instanceof CompletionOnParameterizedQualifiedTypeReference) {
- isException = ((CompletionOnParameterizedQualifiedTypeReference)astNode).isException();
+ ReferenceBinding enclosingType = referenceBinding.enclosingType();
+ if (enclosingType.isParameterizedType()) {
+ char[] typeSig = referenceBinding.genericTypeSignature();
+ sig.append(typeSig, 0, typeSig.length-1);
+
+ TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+ if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+ sig.append(Signature.C_GENERIC_START);
+ for (int i = 0, length = typeVariables.length; i < length; i++) {
+ sig.append(typeVariables[i].genericTypeSignature());
+ }
+ sig.append(Signature.C_GENERIC_END);
}
- if (isException) {
- Argument[] catchArguments = ((TryStatement) astNodeParent).catchArguments;
- int length = catchArguments == null ? 0 : catchArguments.length;
- for (int i = 0; i < length; i++) {
- TypeBinding caughtException = catchArguments[i].type.resolvedType;
- if (caughtException != null) {
- addForbiddenBindings(caughtException);
- this.knownTypes.put(CharOperation.concat(caughtException.qualifiedPackageName(), caughtException.qualifiedSourceName(), '.'), this);
- }
+ } else {
+ char[] typeSig = referenceBinding.signature();
+ sig.append(typeSig, 0, typeSig.length-1); // copy all but trailing semicolon
+
+ if (referenceBinding.isStatic()) {
+ TypeVariableBinding[] typeVariables = referenceBinding.typeVariables();
+ if (typeVariables != Binding.NO_TYPE_VARIABLES) {
+ sig.append(Signature.C_GENERIC_START);
+ for (int i = 0, length = typeVariables.length; i < length; i++) {
+ sig.append(typeVariables[i].genericTypeSignature());
+ }
+ sig.append(Signature.C_GENERIC_END);
}
- this.forbbidenBindingsFilter = SUBTYPE;
}
}
+ sig.append(Signature.C_SEMICOLON);
}
-// else if(scope instanceof MethodScope) {
-// MethodScope methodScope = (MethodScope) scope;
-// if(methodScope.insideTypeAnnotation) {
-// return methodScope.parent.parent;
-// }
-// }
- return scope;
+ int sigLength = sig.length();
+ result = new char[sigLength];
+ sig.getChars(0, sigLength, result, 0);
+ result = CharOperation.replaceOnCopy(result, '/', Signature.C_DOT);
+ return result;
}
- private char[] computePrefix(SourceTypeBinding declarationType, SourceTypeBinding invocationType, boolean isStatic){
- StringBuffer completion = new StringBuffer(10);
+ private ImportBinding[] getFavoriteReferenceBindings(Scope scope) {
+ if (this.favoriteReferenceBindings != null) return this.favoriteReferenceBindings;
- if (isStatic) {
- completion.append(declarationType.sourceName());
+ String[] favoriteReferences = this.requestor.getFavoriteReferences();
- } else if (declarationType == invocationType) {
- completion.append(THIS);
+ if (favoriteReferences == null || favoriteReferences.length == 0) return null;
- } else {
+ ImportBinding[] resolvedImports = new ImportBinding[favoriteReferences.length];
- if (!declarationType.isNestedType()) {
+ int count = 0;
+ next : for (int i = 0; i < favoriteReferences.length; i++) {
+ String favoriteReference = favoriteReferences[i];
- completion.append(declarationType.sourceName());
- completion.append('.');
- completion.append(THIS);
+ int length;
+ if (favoriteReference == null || (length = favoriteReference.length()) == 0) continue next;
- } else if (!declarationType.isAnonymousType()) {
+ boolean onDemand = favoriteReference.charAt(length - 1) == '*';
- completion.append(declarationType.sourceName());
- completion.append('.');
- completion.append(THIS);
+ char[][] compoundName = CharOperation.splitOn('.', favoriteReference.toCharArray());
+ if (onDemand) {
+ compoundName = CharOperation.subarray(compoundName, 0, compoundName.length - 1);
+ }
+
+ // remove duplicate and conflicting
+ for (int j = 0; j < count; j++) {
+ ImportReference f = resolvedImports[j].reference;
+
+ if (CharOperation.equals(f.tokens, compoundName)) continue next;
+
+ if (!onDemand && ((f.bits & ASTNode.OnDemand) == 0)) {
+ if (CharOperation.equals(f.tokens[f.tokens.length - 1], compoundName[compoundName.length - 1]))
+ continue next;
+ }
+ }
+
+ boolean isStatic = true;
+
+ ImportReference importReference =
+ new ImportReference(
+ compoundName,
+ new long[compoundName.length],
+ onDemand,
+ isStatic ? ClassFileConstants.AccStatic : ClassFileConstants.AccDefault);
+
+ Binding importBinding = this.unitScope.findImport(compoundName, isStatic, onDemand);
+
+ if (!importBinding.isValidBinding()) {
+ continue next;
+ }
+ if (importBinding instanceof PackageBinding) {
+ continue next;
}
+
+ resolvedImports[count++] =
+ new ImportBinding(compoundName, onDemand, importBinding, importReference);
}
- return completion.toString().toCharArray();
- }
+ if (resolvedImports.length > count)
+ System.arraycopy(resolvedImports, 0, resolvedImports = new ImportBinding[count], 0, count);
- private void proposeNewMethod(char[] token, ReferenceBinding reference) {
- if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
- int relevance = computeBaseRelevance();
- relevance += computeRelevanceForResolution();
- relevance += computeRelevanceForInterestingProposal();
- relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
+ return this.favoriteReferenceBindings = resolvedImports;
+ }
- InternalCompletionProposal proposal = createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
- proposal.setDeclarationSignature(getSignature(reference));
- proposal.setSignature(
- createMethodSignature(
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR_CHAR,
- CharOperation.NO_CHAR,
- VOID));
- proposal.setDeclarationPackageName(reference.qualifiedPackageName());
- proposal.setDeclarationTypeName(reference.qualifiedSourceName());
+ public AssistParser getParser() {
- //proposal.setPackageName(null);
- proposal.setTypeName(VOID);
- proposal.setName(token);
- //proposal.setParameterPackageNames(null);
- //proposal.setParameterTypeNames(null);
- //proposal.setPackageName(null);
- proposal.setCompletion(token);
- proposal.setFlags(Flags.AccPublic);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
+ return this.parser;
+ }
+ protected boolean hasPossibleAnnotationTarget(TypeBinding typeBinding, Scope scope) {
+ if (this.targetedElement == TagBits.AnnotationForPackage) {
+ long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+ if(target != 0 && (target & TagBits.AnnotationForPackage) == 0) {
+ return false;
+ }
+ } else if ((this.targetedElement & TagBits.AnnotationForType) != 0) {
+ if (scope.parent != null &&
+ scope.parent.parent != null &&
+ scope.parent.referenceContext() instanceof CompletionOnAnnotationOfType &&
+ scope.parent.parent instanceof CompilationUnitScope) {
+ long target = typeBinding.getAnnotationTagBits() & TagBits.AnnotationTargetMASK;
+ if ((this.targetedElement & TagBits.AnnotationForAnnotationType) != 0) {
+ if(target != 0 && (target &(TagBits.AnnotationForType | TagBits.AnnotationForAnnotationType)) == 0) {
+ return false;
+ }
+ } else {
+ if(target != 0 && (target &(TagBits.AnnotationForType)) == 0) {
+ return false;
+ }
+ }
}
}
+ return true;
+ }
+ /**
+ * Returns completion string inserted inside a specified inline tag.
+ * @param completionName
+ * @return char[] Completion text inclunding specified inline tag
+ */
+ private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
+ int tagLength= inlineTag.length;
+ int completionLength = completionName.length;
+ int inlineLength = 2+tagLength+1+completionLength+1;
+ char[] inlineCompletion = new char[inlineLength];
+ inlineCompletion[0] = '{';
+ inlineCompletion[1] = '@';
+ System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
+ inlineCompletion[tagLength+2] = ' ';
+ System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
+ // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
+ //inlineCompletion[inlineLength-2] = ' ';
+ inlineCompletion[inlineLength-1] = '}';
+ return inlineCompletion;
}
private boolean isForbidden(Binding binding) {
for (int i = 0; i <= this.forbbidenBindingsPtr; i++) {
@@ -10033,6 +10331,19 @@
}
return false;
}
+
+ private boolean isIgnored(int kind) {
+ return this.requestor.isIgnored(kind);
+ }
+ private boolean isIgnored(int kind, boolean missingTypes) {
+ return this.requestor.isIgnored(kind) ||
+ (missingTypes && !this.requestor.isAllowingRequiredProposals(kind, CompletionProposal.TYPE_REF));
+ }
+
+ private boolean isIgnored(int kind, int requiredProposalKind) {
+ return this.requestor.isIgnored(kind) ||
+ !this.requestor.isAllowingRequiredProposals(kind, requiredProposalKind);
+ }
private boolean isValidParent(ASTNode parent, ASTNode node, Scope scope){
if(parent instanceof ParameterizedSingleTypeReference) {
@@ -10112,260 +10423,41 @@
}
return true;
}
- public static char[] createNonGenericTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
- return Signature.createCharArrayTypeSignature(
- CharOperation.concat(
- qualifiedPackageName,
- CharOperation.replaceOnCopy(qualifiedTypeName, '.', '$'), '.'), true);
- }
- public static char[] createTypeSignature(char[] qualifiedPackageName, char[] qualifiedTypeName) {
- char[] name = new char[qualifiedTypeName.length];
- System.arraycopy(qualifiedTypeName, 0, name, 0, qualifiedTypeName.length);
-
- int depth = 0;
- int length = name.length;
- for (int i = length -1; i >= 0; i--) {
- switch (name[i]) {
- case '.':
- if (depth == 0 && name[i - 1] != '>') {
- name[i] = '$';
- }
- break;
- case '<':
- depth--;
- break;
- case '>':
- depth++;
- break;
- }
- }
- return Signature.createCharArrayTypeSignature(
- CharOperation.concat(
- qualifiedPackageName,
- name, '.'), true);
- }
-
- public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnPackagename, char[] returnTypeName) {
- char[] returnTypeSignature =
- returnTypeName == null || returnTypeName.length == 0
- ? Signature.createCharArrayTypeSignature(VOID, true)
- : Signature.createCharArrayTypeSignature(
- CharOperation.concat(
- returnPackagename,
- CharOperation.replaceOnCopy(returnTypeName, '.', '$'), '.'), true);
-
- return createMethodSignature(
- parameterPackageNames,
- parameterTypeNames,
- returnTypeSignature);
- }
-
- public static char[] createMethodSignature(char[][] parameterPackageNames, char[][] parameterTypeNames, char[] returnTypeSignature) {
- char[][] parameterTypeSignature = new char[parameterTypeNames.length][];
- for (int i = 0; i < parameterTypeSignature.length; i++) {
- parameterTypeSignature[i] =
- Signature.createCharArrayTypeSignature(
- CharOperation.concat(
- parameterPackageNames[i],
- CharOperation.replaceOnCopy(parameterTypeNames[i], '.', '$'), '.'), true);
- }
-
- return Signature.createMethodSignature(
- parameterTypeSignature,
- returnTypeSignature);
- }
-
- protected InternalCompletionProposal createProposal(int kind, int completionOffset) {
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(kind, completionOffset - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- return proposal;
- }
-
- /*
- * Create a completion proposal for a type.
- */
- private void createTypeProposal(char[] packageName, char[] typeName, int modifiers, int accessibility, char[] completionName, int relevance) {
-
- // Create standard type proposal
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setDeclarationSignature(packageName);
- proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
- proposal.setPackageName(packageName);
- proposal.setTypeName(typeName);
- proposal.setCompletion(completionName);
- proposal.setFlags(modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- proposal.setAccessibility(accessibility);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
-
- // Create javadoc text proposal if necessary
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
- char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setDeclarationSignature(packageName);
- proposal.setSignature(createNonGenericTypeSignature(packageName, typeName));
- proposal.setPackageName(packageName);
- proposal.setTypeName(typeName);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- proposal.setAccessibility(accessibility);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
-
- /*
- * Create a completion proposal for a member type.
- */
- private void createTypeProposal(
- ReferenceBinding refBinding,
- char[] typeName,
- int accessibility,
- char[] completionName,
- int relevance,
- Binding[] missingElements,
- int[] missingElementsStarts,
- int[] missingElementsEnds,
- boolean missingElementsHaveProblems) {
-
- // Create standard type proposal
- if(!this.isIgnored(CompletionProposal.TYPE_REF, missingElements != null) && (this.assistNodeInJavadoc & CompletionOnJavadoc.ONLY_INLINE_TAG) == 0) {
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
- proposal.setSignature(getCompletedTypeSignature(refBinding));
- proposal.setPackageName(refBinding.qualifiedPackageName());
- proposal.setTypeName(typeName);
- if (missingElements != null) {
- CompletionProposal[] subProposals = new CompletionProposal[missingElements.length];
- for (int i = 0; i < missingElements.length; i++) {
- subProposals[i] =
- createRequiredTypeProposal(
- missingElements[i],
- missingElementsStarts[i],
- missingElementsEnds[i],
- relevance);
- }
- proposal.setRequiredProposals(subProposals);
- }
- proposal.setCompletion(completionName);
- proposal.setFlags(refBinding.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
-
- // Create javadoc text proposal if necessary
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
- char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setDeclarationSignature(refBinding.qualifiedPackageName());
- proposal.setSignature(getCompletedTypeSignature(refBinding));
- proposal.setPackageName(refBinding.qualifiedPackageName());
- proposal.setTypeName(typeName);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(refBinding.modifiers);
- int start = (this.assistNodeInJavadoc & CompletionOnJavadoc.REPLACE_TAG) != 0 ? this.javadocTagPosition : this.startPosition;
- proposal.setReplaceRange(start - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
-
- /*
- * Create a completion proposal for a member type.
- */
- private void createTypeParameterProposal(TypeParameter typeParameter, int relevance) {
- char[] completionName = typeParameter.name;
-
- // Create standard type proposal
- if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setSignature(getSignature(typeParameter.binding));
- proposal.setTypeName(completionName);
- proposal.setCompletion(completionName);
- proposal.setFlags(typeParameter.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
-
- // Create javadoc text proposal if necessary
- if ((this.assistNodeInJavadoc & CompletionOnJavadoc.TEXT) != 0 && !this.requestor.isIgnored(CompletionProposal.JAVADOC_TYPE_REF)) {
- char[] javadocCompletion= inlineTagCompletion(completionName, JavadocTagConstants.TAG_LINK);
- InternalCompletionProposal proposal = (InternalCompletionProposal) CompletionProposal.create(CompletionProposal.JAVADOC_TYPE_REF, this.actualCompletionPosition - this.offset);
- proposal.nameLookup = this.nameEnvironment.nameLookup;
- proposal.completionEngine = this;
- proposal.setSignature(getSignature(typeParameter.binding));
- proposal.setTypeName(javadocCompletion);
- proposal.setCompletion(javadocCompletion);
- proposal.setFlags(typeParameter.modifiers);
- proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
- proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
- proposal.setRelevance(relevance+R_INLINE_TAG);
- this.requestor.accept(proposal);
- if(DEBUG) {
- this.printDebug(proposal);
- }
- }
- }
-
- /**
- * Returns completion string inserted inside a specified inline tag.
- * @param completionName
- * @return char[] Completion text inclunding specified inline tag
- */
- private char[] inlineTagCompletion(char[] completionName, char[] inlineTag) {
- int tagLength= inlineTag.length;
- int completionLength = completionName.length;
- int inlineLength = 2+tagLength+1+completionLength+1;
- char[] inlineCompletion = new char[inlineLength];
- inlineCompletion[0] = '{';
- inlineCompletion[1] = '@';
- System.arraycopy(inlineTag, 0, inlineCompletion, 2, tagLength);
- inlineCompletion[tagLength+2] = ' ';
- System.arraycopy(completionName, 0, inlineCompletion, tagLength+3, completionLength);
- // do not add space at end of inline tag (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121026)
- //inlineCompletion[inlineLength-2] = ' ';
- inlineCompletion[inlineLength-1] = '}';
- return inlineCompletion;
- }
+ private Initializer parseSnippeInitializer(char[] snippet, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic){
+ StringBuffer prefix = new StringBuffer();
+ prefix.append("public class FakeType {\n "); //$NON-NLS-1$
+ if(isStatic) {
+ prefix.append("static "); //$NON-NLS-1$
+ }
+ prefix.append("{\n"); //$NON-NLS-1$
+ for (int i = 0; i < localVariableTypeNames.length; i++) {
+ ASTNode.printModifiers(localVariableModifiers[i], prefix);
+ prefix.append(' ');
+ prefix.append(localVariableTypeNames[i]);
+ prefix.append(' ');
+ prefix.append(localVariableNames[i]);
+ prefix.append(';');
+ }
+
+ char[] fakeSource = CharOperation.concat(prefix.toString().toCharArray(), snippet, "}}".toCharArray());//$NON-NLS-1$
+ this.offset = prefix.length();
+
+ String encoding = this.compilerOptions.defaultEncoding;
+ BasicCompilationUnit fakeUnit = new BasicCompilationUnit(
+ fakeSource,
+ null,
+ "FakeType.java", //$NON-NLS-1$
+ encoding);
+
+ this.actualCompletionPosition = prefix.length() + position - 1;
+
+ CompilationResult fakeResult = new CompilationResult(fakeUnit, 1, 1, this.compilerOptions.maxProblemsPerUnit);
+ CompilationUnitDeclaration fakeAST = this.parser.dietParse(fakeUnit, fakeResult, this.actualCompletionPosition);
+
+ parseBlockStatements(fakeAST, this.actualCompletionPosition);
+ return (Initializer)fakeAST.types[0].fields[0];
+ }
protected void printDebug(CategorizedProblem error) {
if(CompletionEngine.DEBUG) {
System.out.print("COMPLETION - completionFailure("); //$NON-NLS-1$
@@ -10373,18 +10465,12 @@
System.out.println(")"); //$NON-NLS-1$
}
}
-
- private void printDebugTab(int tab, StringBuffer buffer) {
- for (int i = 0; i < tab; i++) {
- buffer.append('\t');
- }
- }
-
protected void printDebug(CompletionProposal proposal){
StringBuffer buffer = new StringBuffer();
printDebug(proposal, 0, buffer);
System.out.println(buffer.toString());
}
+
private void printDebug(CompletionProposal proposal, int tab, StringBuffer buffer){
printDebugTab(tab, buffer);
buffer.append("COMPLETION - "); //$NON-NLS-1$
@@ -10509,42 +10595,172 @@
buffer.append("}\n");//$NON-NLS-1$
}
- private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
- char[][] substituedParameterNames = new char[typeVariables.length][];
+ private void printDebugTab(int tab, StringBuffer buffer) {
+ for (int i = 0; i < tab; i++) {
+ buffer.append('\t');
+ }
+ }
- for (int i = 0; i < substituedParameterNames.length; i++) {
- substituedParameterNames[i] = typeVariables[i].sourceName;
+ private void proposeNewMethod(char[] token, ReferenceBinding reference) {
+ if(!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION)) {
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(IAccessRule.K_ACCESSIBLE); // no access restriction for new method
+
+ InternalCompletionProposal proposal = createProposal(CompletionProposal.POTENTIAL_METHOD_DECLARATION, this.actualCompletionPosition);
+ proposal.setDeclarationSignature(getSignature(reference));
+ proposal.setSignature(
+ createMethodSignature(
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR_CHAR,
+ CharOperation.NO_CHAR,
+ VOID));
+ proposal.setDeclarationPackageName(reference.qualifiedPackageName());
+ proposal.setDeclarationTypeName(reference.qualifiedSourceName());
+
+ //proposal.setPackageName(null);
+ proposal.setTypeName(VOID);
+ proposal.setName(token);
+ //proposal.setParameterPackageNames(null);
+ //proposal.setParameterTypeNames(null);
+ //proposal.setPackageName(null);
+ proposal.setCompletion(token);
+ proposal.setFlags(Flags.AccPublic);
+ proposal.setReplaceRange(this.startPosition - this.offset, this.endPosition - this.offset);
+ proposal.setTokenRange(this.tokenStart - this.offset, this.tokenEnd - this.offset);
+ proposal.setRelevance(relevance);
+ this.requestor.accept(proposal);
+ if(DEBUG) {
+ this.printDebug(proposal);
+ }
}
+ }
- boolean foundConflicts = false;
+ private void proposeType(
+ char[] packageName,
+ char[] simpleTypeName,
+ int modifiers,
+ int accessibility,
+ char[] typeName,
+ char[] fullyQualifiedName,
+ boolean isQualified,
+ boolean isNotOptimum,
+ Scope scope) {
+ char[] completionName = fullyQualifiedName;
+ if(isQualified) {
+ if (packageName == null || packageName.length == 0)
+ if (this.unitScope != null && this.unitScope.fPackage.compoundName != CharOperation.NO_CHAR_CHAR)
+ return; // ignore types from the default package from outside it
+ } else {
+ completionName = simpleTypeName;
+ }
- nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
- TypeVariableBinding typeVariableBinding = typeVariables[i];
- char[] methodParameterName = typeVariableBinding.sourceName;
+ TypeBinding guessedType = null;
+ if (!this.timeoutExceeded &&
+ (modifiers & ClassFileConstants.AccAnnotation) != 0 &&
+ this.assistNodeIsAnnotation &&
+ (this.targetedElement & TagBits.AnnotationTargetMASK) != 0) {
+ char[][] cn = CharOperation.splitOn('.', fullyQualifiedName);
- for (int j = 0; j < excludedNames.length; j++) {
- char[] typeParameterName = excludedNames[j];
- if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
- char[] substitution;
- if(methodParameterName.length == 1) {
- if(ScannerHelper.isUpperCase(methodParameterName[0])) {
- substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
- } else {
- substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
- }
- } else {
- substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
- }
- substituedParameterNames[i] = substitution;
+ TypeReference ref;
+ if (cn.length == 1) {
+ ref = new SingleTypeReference(simpleTypeName, 0);
+ } else {
+ ref = new QualifiedTypeReference(cn,new long[cn.length]);
+ }
- foundConflicts = true;
- continue nextTypeParameter;
- }
+ switch (scope.kind) {
+ case Scope.METHOD_SCOPE :
+ case Scope.BLOCK_SCOPE :
+ guessedType = ref.resolveType((BlockScope)scope);
+ break;
+ case Scope.CLASS_SCOPE :
+ guessedType = ref.resolveType((ClassScope)scope);
+ break;
}
+
+ if (guessedType == null || !guessedType.isValidBinding()) return;
+
+ if (!hasPossibleAnnotationTarget(guessedType, scope)) return;
}
- if(foundConflicts) return substituedParameterNames;
- return null;
+ int relevance = computeBaseRelevance();
+ relevance += computeRelevanceForResolution();
+ relevance += computeRelevanceForInterestingProposal();
+ relevance += computeRelevanceForRestrictions(accessibility);
+ relevance += computeRelevanceForCaseMatching(this.completionToken, simpleTypeName);
+ relevance += computeRelevanceForExpectingType(packageName, simpleTypeName);
+ relevance += computeRelevanceForQualification(isQualified);
+
+ int kind = modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation);
+ switch (kind) {
+ case ClassFileConstants.AccAnnotation:
+ case ClassFileConstants.AccAnnotation | ClassFileConstants.AccInterface:
+ relevance += computeRelevanceForAnnotation();
+ if (guessedType != null) relevance += computeRelevanceForAnnotationTarget(guessedType);
+ relevance += computeRelevanceForInterface();
+ break;
+ case ClassFileConstants.AccEnum:
+ relevance += computeRelevanceForEnum();
+ break;
+ case ClassFileConstants.AccInterface:
+ relevance += computeRelevanceForInterface();
+ break;
+ default:
+ relevance += computeRelevanceForClass();
+ relevance += computeRelevanceForException(simpleTypeName);
+ break;
+ }
+
+ this.noProposal = false;
+ if(!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
+ createTypeProposal(packageName, typeName, modifiers, accessibility, completionName, relevance, isNotOptimum);
+ }
+ }
+
+ protected void reset() {
+
+ super.reset(false);
+ this.knownPkgs = new HashtableOfObject(10);
+ this.knownTypes = new HashtableOfObject(10);
+ this.timeoutExceeded = false;
+ }
+
+ private void setSourceAndTokenRange(int start, int end) {
+ this.setSourceAndTokenRange(start, end, true);
+ }
+
+ private void setSourceAndTokenRange(int start, int end, boolean emptyTokenAdjstment) {
+ this.setSourceRange(start, end, emptyTokenAdjstment);
+ this.setTokenRange(start, end, emptyTokenAdjstment);
+ }
+
+ private void setSourceRange(int start, int end) {
+ this.setSourceRange(start, end, true);
+ }
+
+ private void setSourceRange(int start, int end, boolean emptyTokenAdjstment) {
+ this.startPosition = start;
+ if(emptyTokenAdjstment) {
+ int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
+ this.endPosition = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
+ } else {
+ this.endPosition = end + 1;
+ }
+ }
+
+ private void setTokenRange(int start, int end) {
+ this.setTokenRange(start, end, true);
+ }
+ private void setTokenRange(int start, int end, boolean emptyTokenAdjstment) {
+ this.tokenStart = start;
+ if(emptyTokenAdjstment) {
+ int endOfEmptyToken = ((CompletionScanner)this.parser.scanner).endOfEmptyToken;
+ this.tokenEnd = endOfEmptyToken > end ? endOfEmptyToken + 1 : end + 1;
+ } else {
+ this.tokenEnd = end + 1;
+ }
}
private char[] substituteMethodTypeParameterName(char firstName, char startChar, char endChar, char[][] excludedNames, char[][] otherParameterNames) {
@@ -10596,4 +10812,42 @@
}
return name;
}
+
+ private char[][] substituteMethodTypeParameterNames(TypeVariableBinding[] typeVariables, char[][] excludedNames) {
+ char[][] substituedParameterNames = new char[typeVariables.length][];
+
+ for (int i = 0; i < substituedParameterNames.length; i++) {
+ substituedParameterNames[i] = typeVariables[i].sourceName;
+ }
+
+ boolean foundConflicts = false;
+
+ nextTypeParameter : for (int i = 0; i < typeVariables.length; i++) {
+ TypeVariableBinding typeVariableBinding = typeVariables[i];
+ char[] methodParameterName = typeVariableBinding.sourceName;
+
+ for (int j = 0; j < excludedNames.length; j++) {
+ char[] typeParameterName = excludedNames[j];
+ if(CharOperation.equals(typeParameterName, methodParameterName, false)) {
+ char[] substitution;
+ if(methodParameterName.length == 1) {
+ if(ScannerHelper.isUpperCase(methodParameterName[0])) {
+ substitution = substituteMethodTypeParameterName(methodParameterName[0], 'A', 'Z', excludedNames, substituedParameterNames);
+ } else {
+ substitution = substituteMethodTypeParameterName(methodParameterName[0], 'a', 'z', excludedNames, substituedParameterNames);
+ }
+ } else {
+ substitution = substituteMethodTypeParameterName(methodParameterName, excludedNames, substituedParameterNames);
+ }
+ substituedParameterNames[i] = substitution;
+
+ foundConflicts = true;
+ continue nextTypeParameter;
+ }
+ }
+ }
+
+ if(foundConflicts) return substituedParameterNames;
+ return null;
+ }
}
\ No newline at end of file
Index: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java
===================================================================
RCS file: codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java
diff -N codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionOnBranchStatementLabel.java 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.codeassist.complete;
+
+import org.eclipse.jdt.internal.compiler.ast.BranchStatement;
+import org.eclipse.jdt.internal.compiler.flow.FlowContext;
+import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
+import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
+
+public class CompletionOnBranchStatementLabel extends BranchStatement {
+ public static final int BREAK = 1;
+ public static final int CONTINUE = 2;
+
+ private int kind;
+ public char[][] possibleLabels;
+
+ public CompletionOnBranchStatementLabel(int kind, char[] l, int s, int e, char[][] possibleLabels) {
+ super(l, s, e);
+ this.kind = kind;
+ this.possibleLabels = possibleLabels;
+ }
+
+ public FlowInfo analyseCode(BlockScope currentScope,
+ FlowContext flowContext, FlowInfo flowInfo) {
+ // Is never called
+ return null;
+ }
+
+ public void resolve(BlockScope scope) {
+ throw new CompletionNodeFound(this, scope);
+ }
+ public StringBuffer printStatement(int indent, StringBuffer output) {
+ printIndent(indent, output);
+ if(this.kind == CONTINUE) {
+ output.append("continue "); //$NON-NLS-1$
+ } else {
+ output.append("break "); //$NON-NLS-1$
+ }
+ output.append(";"); //$NON-NLS-1$
+ }
+
+}