### Eclipse Workspace Patch 1.0 #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.224 diff -u -r1.224 CompletionParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 28 Jul 2011 17:07:25 -0000 1.224 +++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 12 Aug 2011 09:48:23 -0000 @@ -4758,6 +4758,18 @@ if(oldElement != this.currentElement) { popElement(K_LOCAL_INITIALIZER_DELIMITER); } + } else if(this.currentElement != null && this.currentElement instanceof RecoveredField) { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 + // To make sure the array initializer is popped when the focus is shifted to the parent + // in case we're restarting recovery inside an array initializer + RecoveredElement oldElement = this.currentElement; + super.recoveryExitFromVariable(); + if(oldElement != this.currentElement) { + if(topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_ARRAY_INITIALIZER) { + popElement(K_ARRAY_INITIALIZER); + popElement(K_FIELD_INITIALIZER_DELIMITER); + } + } } else { super.recoveryExitFromVariable(); } @@ -4978,4 +4990,13 @@ } return false; } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +protected boolean isInsideArrayInitializer(){ + int i = this.elementPtr; + if (i > -1 && this.elementKindStack[i] == K_ARRAY_INITIALIZER) { + return true; + } + return false; +} } \ No newline at end of file Index: codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java,v retrieving revision 1.99 diff -u -r1.99 AssistParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 28 Jul 2011 17:07:53 -0000 1.99 +++ codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 12 Aug 2011 09:48:23 -0000 @@ -1655,6 +1655,11 @@ ){ prepareForBlockStatements(); goForBlockStatementsOrCatchHeader(); + } else if((isInsideArrayInitializer()) && + isIndirectlyInsideFieldInitialization() && + this.assistNode == null){ + prepareForBlockStatements(); + goForBlockStatementsopt(); } else { prepareForHeaders(); goForHeaders(); @@ -1677,6 +1682,11 @@ // does not know how to restart return false; } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +// To be implemented in children viz. CompletionParser that are aware of array initializers +protected boolean isInsideArrayInitializer() { + return false; +} public abstract void setAssistIdentifier(char[] assistIdent); protected int topKnownElementInfo(int owner) { return topKnownElementInfo(owner, 0); Index: compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java,v retrieving revision 1.46 diff -u -r1.46 RecoveredField.java --- compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java 28 Jul 2011 17:07:15 -0000 1.46 +++ compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java 12 Aug 2011 09:48:23 -0000 @@ -76,7 +76,9 @@ if (this.alreadyCompletedFieldInitialization || !(statement instanceof Expression)) { return super.add(statement, bracketBalanceValue); } else { - this.alreadyCompletedFieldInitialization = true; + if (statement.sourceEnd > 0) + this.alreadyCompletedFieldInitialization = true; + // else we may still be inside the initialization, having parsed only a part of it yet this.fieldDeclaration.initialization = (Expression)statement; this.fieldDeclaration.declarationSourceEnd = statement.sourceEnd; this.fieldDeclaration.declarationEnd = statement.sourceEnd; #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java,v retrieving revision 1.39 diff -u -r1.39 CompletionParserTest.java --- src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java 28 Jul 2011 17:06:35 -0000 1.39 +++ src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java 12 Aug 2011 09:48:25 -0000 @@ -20,7 +20,7 @@ super(testName); } static { -// TESTS_NAMES = new String[] { "testXA_1FGGUQF_1FHSL8H_1" }; +// TESTS_NAMES = new String[] { "testBug292087" }; } public static Test suite() { return buildAllCompliancesTestSuite(CompletionParserTest.class); @@ -8997,4 +8997,120 @@ expectedReplacedSource, testName); } + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +// To verify that the completion node is found inside a field initializer +// that contains an anonymous class. +public void testBug292087a(){ + String str = + "package test;\n" + + "class MyClass{\n" + + "}\n" + + "public class Try extends Thread{\n" + + " public static MyClass MyClassField;" + + " public static MyClass MyClassMethod(){\n" + + " return null;\n" + + " }\n" + + " public MyClass member[] = {\n" + + " " + + " new MyClass (){\n" + + " public void abc() {}\n" + + " },\n" + + " /*Complete here*/\n" + + " };\n" + + "}\n"; + + String testName = ""; + String completeBehind = "/*Complete here*/"; + String expectedCompletionNodeToString = ""; + String expectedParentNodeToString = + "public MyClass[] member = {};"; + String completionIdentifier = ""; + String expectedReplacedSource = ""; + int cursorLocation = str.lastIndexOf("/*Complete here*/") + completeBehind.length() - 1; + String expectedUnitDisplayString = + "package test;\n" + + "class MyClass {\n" + + " MyClass() {\n" + + " }\n" + + "}\n" + + "public class Try extends Thread {\n" + + " public static MyClass MyClassField;\n" + + " public MyClass[] member = {};\n" + + " public Try() {\n" + + " }\n" + + " () {\n" + + " }\n" + + " public static MyClass MyClassMethod() {\n" + + " }\n" + + "}\n"; + + checkDietParse( + str.toCharArray(), + cursorLocation, + expectedCompletionNodeToString, + expectedParentNodeToString, + expectedUnitDisplayString, + completionIdentifier, + expectedReplacedSource, + testName); +} + +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +// To verify that anonymous class inside an array initializer of a recovered field +// doesn't end up at a bogus location. +public void testBug292087b(){ + String str = + "package test;\n" + + "class MyClass{\n" + + "}\n" + + "public class Try extends Thread{\n" + + " public static MyClass MyClassField;" + + " public static MyClass MyClassMethod(){\n" + + " return null;\n" + + " }\n" + + " public MyClass member[] = {\n" + + " /*Complete here*/\n" + + " new MyClass (){\n" + + " public void abc() {}\n" + + " },\n" + + " " + + " };\n" + + "}\n"; + + String testName = ""; + String completeBehind = "/*Complete here*/"; + String expectedCompletionNodeToString = ""; + String expectedParentNodeToString = + "public MyClass[] member = {};"; + String completionIdentifier = ""; + String expectedReplacedSource = ""; + int cursorLocation = str.lastIndexOf("/*Complete here*/") + completeBehind.length() - 1; + String expectedUnitDisplayString = + "package test;\n" + + "class MyClass {\n" + + " MyClass() {\n" + + " }\n" + + "}\n" + + "public class Try extends Thread {\n" + + " public static MyClass MyClassField;\n" + + " public MyClass[] member = {};\n" + + " public Try() {\n" + + " }\n" + + " () {\n" + + " }\n" + + " public static MyClass MyClassMethod() {\n" + + " }\n" + + "}\n"; + + checkDietParse( + str.toCharArray(), + cursorLocation, + expectedCompletionNodeToString, + expectedParentNodeToString, + expectedUnitDisplayString, + completionIdentifier, + expectedReplacedSource, + testName); +} } Index: src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java,v retrieving revision 1.67 diff -u -r1.67 DietRecoveryTest.java --- src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java 28 Jul 2011 17:06:38 -0000 1.67 +++ src/org/eclipse/jdt/core/tests/compiler/parser/DietRecoveryTest.java 12 Aug 2011 09:48:25 -0000 @@ -4657,15 +4657,23 @@ String expectedCompletionDietUnitToString = "package ZKentTest;\n" + - "import java.awt.color.*;\n" + - "public class A {\n" + - " int[] ii;\n" + - " public A() {\n" + - " }\n" + - " A foo(int i) {\n" + - " }\n" + - " int bar() {\n" + - " }\n" + + "import java.awt.color.*;\n" + + "public class A {\n" + + " int[] ii;\n" + + " public A() {\n" + + " }\n" + + " A foo(int i) {\n" + + " }\n" + + "}\n" + + "class Local {\n" + + " Local() {\n" + + " }\n" + + " int hello() {\n" + + " }\n" + + " int world() {\n" + + " }\n" + + " void foo() {\n" + + " }\n" + "}\n"; String testName = ""; #P org.eclipse.jdt.core.tests.model 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.243 diff -u -r1.243 CompletionTests.java --- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 28 Jul 2011 17:06:08 -0000 1.243 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 12 Aug 2011 09:48:28 -0000 @@ -43,7 +43,9 @@ // TESTS_NAMES = new String[] { "testCompletionMethodDeclaration17"}; } public static Test suite() { - //return buildModelTestSuite(CompletionTests.class); + if (TESTS_PREFIX != null || TESTS_NAMES != null || TESTS_NUMBERS != null || TESTS_RANGE != null) { + return buildModelTestSuite(CompletionTests.class); + } TestSuite suite = new Suite(CompletionTests.class.getName()); suite.addTest(new CompletionTests("testAbortCompletion1")); suite.addTest(new CompletionTests("testAbortCompletion2")); @@ -1036,6 +1038,9 @@ suite.addTest(new CompletionTests("testBug351444c")); suite.addTest(new CompletionTests("testBug351444d")); suite.addTest(new CompletionTests("testBug351444e")); + suite.addTest(new CompletionTests("testBug292087b")); + suite.addTest(new CompletionTests("testBug292087c")); + suite.addTest(new CompletionTests("testBug292087d")); return suite; } public CompletionTests(String name) { @@ -25520,4 +25525,140 @@ COMPLETION_PROJECT.setOptions(options); } } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug292087b() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "class MyClass{\n" + + "}\n" + + "public class Try extends Thread{\n" + + " public static MyClass MyClassField;" + + " public static MyClass MyClassMethod(){\n" + + " return null;\n" + + " }\n" + + " public MyClass member[] = { new MyClass (){\n" + + " public void abc() {}\n" + + " },\n" + + " /*Complete here*/M" + + " };\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "/*Complete here*/M"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "expectedTypesSignatures={Ltest.MyClass;}\n" + + "expectedTypesKeys={Ltest/Try~MyClass;}", + requestor.getContext()); + assertResults( + "mypackage[PACKAGE_REF]{mypackage, mypackage, null, null, null, " + (R_NON_STATIC + R_UNQUALIFIED) + "}\n" + + "MyClass[TYPE_REF]{mypackage.MyClass, mypackage, Lmypackage.MyClass;, null, null, " + (R_NON_STATIC + R_UNQUALIFIED + R_CASE) + "}\n" + + "MyClass[TYPE_REF]{MyClass, test, Ltest.MyClass;, null, null, " + (R_NON_STATIC + R_UNQUALIFIED + R_CASE + R_NON_RESTRICTED + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassField[FIELD_REF]{MyClassField, Ltest.Try;, Ltest.MyClass;, MyClassField, null, " + (R_NON_STATIC + R_UNQUALIFIED + R_CASE + R_NON_RESTRICTED + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassMethod[METHOD_REF]{MyClassMethod(), Ltest.Try;, ()Ltest.MyClass;, MyClassMethod, null, " + (R_NON_STATIC + R_UNQUALIFIED + R_CASE + R_NON_RESTRICTED + R_EXACT_EXPECTED_TYPE) + "}", + requestor.getResults()); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug292087c() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "class MyClass{\n" + + "}\n" + + "public class Try extends Thread{\n" + + " public static MyClass MyClassField;" + + " public static MyClass MyClassMethod(){\n" + + " return null;\n" + + " }\n" + + " public MyClass member[] = { new MyClass (){\n" + + " public void abc() {}\n" + + " },\n" + + " /*Complete here*/" + + " };\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "/*Complete here*/"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "expectedTypesSignatures={Ltest.MyClass;}\n" + + "expectedTypesKeys={Ltest/Try~MyClass;}", + requestor.getContext()); + assertResults( + "finalize[METHOD_REF]{finalize(), Ljava.lang.Object;, ()V, finalize, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "notify[METHOD_REF]{notify(), Ljava.lang.Object;, ()V, notify, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "notifyAll[METHOD_REF]{notifyAll(), Ljava.lang.Object;, ()V, notifyAll, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, ()V, wait, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (J)V, wait, (millis), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (JI)V, wait, (millis, nanos), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "Try[TYPE_REF]{Try, test, Ltest.Try;, null, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "clone[METHOD_REF]{clone(), Ljava.lang.Object;, ()Ljava.lang.Object;, clone, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "equals[METHOD_REF]{equals(), Ljava.lang.Object;, (Ljava.lang.Object;)Z, equals, (obj), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "getClass[METHOD_REF]{getClass(), Ljava.lang.Object;, ()Ljava.lang.Class;, getClass, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "hashCode[METHOD_REF]{hashCode(), Ljava.lang.Object;, ()I, hashCode, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "MyClass[TYPE_REF]{MyClass, test, Ltest.MyClass;, null, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassField[FIELD_REF]{MyClassField, Ltest.Try;, Ltest.MyClass;, MyClassField, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassMethod[METHOD_REF]{MyClassMethod(), Ltest.Try;, ()Ltest.MyClass;, MyClassMethod, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}", + requestor.getResults()); +} +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292087 +public void testBug292087d() throws JavaModelException { + this.workingCopies = new ICompilationUnit[1]; + this.workingCopies[0] = getWorkingCopy( + "/Completion/src/test/Try.java", + "package test;\n" + + "class MyClass{\n" + + "}\n" + + "public class Try extends Thread{\n" + + " public static MyClass MyClassField;" + + " public static MyClass MyClassMethod(){\n" + + " return null;\n" + + " }\n" + + " public MyClass member[] = {\n" + + " /*Complete here*/\n" + + " new MyClass (){\n" + + " public void abc() {}\n" + + " },\n" + + " " + + " };\n" + + "}\n"); + + CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true); + requestor.allowAllRequiredProposals(); + String str = this.workingCopies[0].getSource(); + String completeBehind = "/*Complete here*/"; + int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length(); + this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner); + assertResults( + "expectedTypesSignatures={Ltest.MyClass;}\n" + + "expectedTypesKeys={Ltest/Try~MyClass;}", + requestor.getContext()); + assertResults( + "finalize[METHOD_REF]{finalize(), Ljava.lang.Object;, ()V, finalize, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "notify[METHOD_REF]{notify(), Ljava.lang.Object;, ()V, notify, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "notifyAll[METHOD_REF]{notifyAll(), Ljava.lang.Object;, ()V, notifyAll, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, ()V, wait, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (J)V, wait, (millis), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "wait[METHOD_REF]{wait(), Ljava.lang.Object;, (JI)V, wait, (millis, nanos), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_VOID) + "}\n" + + "Try[TYPE_REF]{Try, test, Ltest.Try;, null, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "clone[METHOD_REF]{clone(), Ljava.lang.Object;, ()Ljava.lang.Object;, clone, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "equals[METHOD_REF]{equals(), Ljava.lang.Object;, (Ljava.lang.Object;)Z, equals, (obj), " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "getClass[METHOD_REF]{getClass(), Ljava.lang.Object;, ()Ljava.lang.Class;, getClass, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "hashCode[METHOD_REF]{hashCode(), Ljava.lang.Object;, ()I, hashCode, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "toString[METHOD_REF]{toString(), Ljava.lang.Object;, ()Ljava.lang.String;, toString, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS) + "}\n" + + "MyClass[TYPE_REF]{MyClass, test, Ltest.MyClass;, null, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassField[FIELD_REF]{MyClassField, Ltest.Try;, Ltest.MyClass;, MyClassField, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}\n" + + "MyClassMethod[METHOD_REF]{MyClassMethod(), Ltest.Try;, ()Ltest.MyClass;, MyClassMethod, null, " + (R_RESOLVED + R_NON_STATIC + R_NAME_LESS_NEW_CHARACTERS + R_EXACT_EXPECTED_TYPE) + "}", + requestor.getResults()); +} }