Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2021-05-22 10:37:30 +0000
committerJay Arthanareeswaran2021-05-24 09:47:10 +0000
commite211a44735f4142c81518de31a4da690328c1c35 (patch)
tree6b00ac91201cc4f3415807e0f25ade4818cfa647
parentb0f1636c9828e2afa0492327b2fa0e45cf131848 (diff)
downloadeclipse.jdt.core-e211a44735f4142c81518de31a4da690328c1c35.tar.gz
eclipse.jdt.core-e211a44735f4142c81518de31a4da690328c1c35.tar.xz
eclipse.jdt.core-e211a44735f4142c81518de31a4da690328c1c35.zip
Bug 573702 - Wrong completions for parameter on a method chainI20210524-1800I20210524-0600
Change-Id: I48ae23090a79c5d473d7793ec11d96df4c438d85 Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de> Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.core/+/180899 Tested-by: JDT Bot <jdt-bot@eclipse.org> Reviewed-by: Jay Arthanareeswaran <jarthana@in.ibm.com> Reviewed-by: Gayan Perera <gayanper@gmail.com>
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java144
-rw-r--r--org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java56
2 files changed, 197 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
index 4d57bdc8a3..0411c067d8 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests.java
@@ -26231,4 +26231,148 @@ public void testBug573632c() throws Exception {
"wait[METHOD_REF]{wait(), Ljava.lang.Object;, (JI)V, wait, (millis, nanos), 60}",
requestor.getResults());
}
+public void testBug573702() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "Completion/src/App.java",
+ "import java.util.Collection;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "interface ObjectProperty<T> {\n" +
+ " void addListener(SingleFireInvalidationListener singleFireInvalidationListener);\n" +
+ "}\n" +
+ "class SingleFireInvalidationListener {\n" +
+ " public SingleFireInvalidationListener(Collection<String> list) { }\n" +
+ "}\n" +
+ "public class App {\n" +
+ "\n" +
+ " public static void boo(Map<String, String> data) {\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation started\");\n" +
+ " App.getDataProperty().addListener(new SingleFireInvalidationListener(data.values()));\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation done\");\n" +
+ " }\n" +
+ "\n" +
+ " public static ObjectProperty<Map<String, String>> getDataProperty() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "new SingleFireInvalidationListener(data";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "data[LOCAL_VARIABLE_REF]{data, null, LMap;, data, null, 56}",
+ requestor.getResults());
+}
+public void testBug573702_fieldRef() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "Completion/src/App.java",
+ "import java.util.Collection;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "interface ObjectProperty<T> {\n" +
+ " void addListener(SingleFireInvalidationListener singleFireInvalidationListener);\n" +
+ "}\n" +
+ "class SingleFireInvalidationListener {\n" +
+ " public SingleFireInvalidationListener(Collection<String> list) { }\n" +
+ "}\n" +
+ "public class App {\n" +
+ " Map<String, String> data;\n" +
+ " public void boo() {\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation started\");\n" +
+ " App.getDataProperty().addListener(new SingleFireInvalidationListener(this.data.values()));\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation done\");\n" +
+ " }\n" +
+ "\n" +
+ " public static ObjectProperty<Map<String, String>> getDataProperty() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "new SingleFireInvalidationListener(this.data";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "data[FIELD_REF]{data, LApp;, LMap;, data, null, 64}",
+ requestor.getResults());
+}
+public void testBug573702_qualifiedName() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "Completion/src/App.java",
+ "import java.util.Collection;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "interface ObjectProperty<T> {\n" +
+ " void addListener(SingleFireInvalidationListener singleFireInvalidationListener);\n" +
+ "}\n" +
+ "class SingleFireInvalidationListener {\n" +
+ " public SingleFireInvalidationListener(Collection<String> list) { }\n" +
+ "}\n" +
+ "public class App {\n" +
+ " static Map<String, String> data;\n" +
+ " public void boo() {\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation started\");\n" +
+ " App.getDataProperty().addListener(new SingleFireInvalidationListener(App.data.values()));\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation done\");\n" +
+ " }\n" +
+ "\n" +
+ " public static ObjectProperty<Map<String, String>> getDataProperty() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "new SingleFireInvalidationListener(App.data";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "data[FIELD_REF]{data, LApp;, LMap;, data, null, 55}",
+ requestor.getResults());
+}
+public void testBug573702_qualifiedName_firstSegment() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "Completion/src/App.java",
+ "import java.util.Collection;\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "interface ObjectProperty<T> {\n" +
+ " void addListener(SingleFireInvalidationListener singleFireInvalidationListener);\n" +
+ "}\n" +
+ "class SingleFireInvalidationListener {\n" +
+ " public SingleFireInvalidationListener(Collection<String> list) { }\n" +
+ "}\n" +
+ "public class App {\n" +
+ " static Map<String, String> data;\n" +
+ " public void boo() {\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation started\");\n" +
+ " App.getDataProperty().addListener(new SingleFireInvalidationListener(App.data.values()));\n" +
+ " System.out.println(\"PopOver direct buffer delayed patch installation done\");\n" +
+ " }\n" +
+ "\n" +
+ " public static ObjectProperty<Map<String, String>> getDataProperty() {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n");
+
+ CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true);
+ requestor.allowAllRequiredProposals();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "new SingleFireInvalidationListener(App";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ assertResults(
+ "App[TYPE_REF]{App, , LApp;, null, null, 56}",
+ requestor.getResults());
+}
}
diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
index ace2ddef20..68bb0454dd 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java
@@ -5411,11 +5411,61 @@ protected TypeReference getTypeReferenceForGenericType(int dim, int identifierLe
}
@Override
protected NameReference getUnspecifiedReference(boolean rejectTypeAnnotations) {
- NameReference nameReference = super.getUnspecifiedReference(rejectTypeAnnotations);
+ // code copied from super, but conditionally creating CompletionOn* nodes:
+
+ /* build a (unspecified) NameReference which may be qualified*/
+ if (rejectTypeAnnotations) { // Compensate for overpermissive grammar.
+ consumeNonTypeUseName();
+ }
+ int length;
+ NameReference ref;
+ if ((length = this.identifierLengthStack[this.identifierLengthPtr--]) == 1) {
+ // single variable reference
+ char[] token = this.identifierStack[this.identifierPtr];
+ long position = this.identifierPositionStack[this.identifierPtr--];
+ int start = (int) (position >>> 32), end = (int) position;
+ if (this.assistNode == null && start < this.cursorLocation && end >= this.cursorLocation) {
+ ref = new CompletionOnSingleNameReference(token, position, isInsideAttributeValue());
+ this.assistNode = ref;
+ } else {
+ ref = new SingleNameReference(token, position);
+ }
+ } else {
+ //Qualified variable reference
+ char[][] tokens = new char[length][];
+ this.identifierPtr -= length;
+ System.arraycopy(this.identifierStack, this.identifierPtr + 1, tokens, 0, length);
+ long[] positions = new long[length];
+ System.arraycopy(this.identifierPositionStack, this.identifierPtr + 1, positions, 0, length);
+ int start = (int) (positions[0] >>> 32), end = (int) positions[length-1];
+ if (this.assistNode == null && start < this.cursorLocation && end >= this.cursorLocation) {
+ // find the token at cursorLocation:
+ int previousCount = 0;
+ for (int i=0; i<length; i++) {
+ if (((int) positions[i]) < this.cursorLocation)
+ previousCount = i + 1;
+ }
+ if (previousCount > 0) {
+ char[][] subset = new char[previousCount][];
+ System.arraycopy(tokens, 0, subset, 0, previousCount);
+ ref = new CompletionOnQualifiedNameReference(subset, tokens[previousCount], positions, isInsideAttributeValue());
+ } else {
+ // with only one token up-to cursorLocation avoid a bogus qualifiedNameReference (simply skipping the remainder):
+ ref = new CompletionOnSingleNameReference(tokens[0], positions[0], isInsideAttributeValue());
+ }
+ this.assistNode = ref;
+ } else {
+ ref =
+ new QualifiedNameReference(tokens,
+ positions,
+ (int) (this.identifierPositionStack[this.identifierPtr + 1] >> 32), // sourceStart
+ (int) this.identifierPositionStack[this.identifierPtr + length]); // sourceEnd
+ }
+ }
if (this.record) {
- recordReference(nameReference);
+ recordReference(ref);
}
- return nameReference;
+ return ref;
}
@Override
protected void consumePostfixExpression() {

Back to the top