### 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.221 diff -u -r1.221 CompletionParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 6 Apr 2011 22:26:04 -0000 1.221 +++ codeassist/org/eclipse/jdt/internal/codeassist/complete/CompletionParser.java 19 Apr 2011 12:15:41 -0000 @@ -4720,6 +4720,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(); } @@ -4940,4 +4952,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.95 diff -u -r1.95 AssistParser.java --- codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 27 Oct 2010 02:55:29 -0000 1.95 +++ codeassist/org/eclipse/jdt/internal/codeassist/impl/AssistParser.java 19 Apr 2011 12:15:42 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -1650,7 +1650,13 @@ ){ prepareForBlockStatements(); goForBlockStatementsOrCatchHeader(); - } else { + } else if((isInsideArrayInitializer()) && + isIndirectlyInsideFieldInitialization() && + this.assistNode == null + ){ + prepareForBlockStatements(); + goForBlockStatementsopt(); + } else { prepareForHeaders(); goForHeaders(); this.diet = true; // passed this point, will not consider method bodies @@ -1672,6 +1678,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.43 diff -u -r1.43 RecoveredField.java --- compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java 20 May 2010 18:03:14 -0000 1.43 +++ compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredField.java 19 Apr 2011 12:15:42 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -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.36 diff -u -r1.36 CompletionParserTest.java --- src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java 14 Jan 2011 17:02:23 -0000 1.36 +++ src/org/eclipse/jdt/core/tests/compiler/parser/CompletionParserTest.java 19 Apr 2011 12:15:44 -0000 @@ -19,7 +19,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); @@ -8688,4 +8688,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); +} } #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.238 diff -u -r1.238 CompletionTests.java --- src/org/eclipse/jdt/core/tests/model/CompletionTests.java 24 Feb 2011 02:48:03 -0000 1.238 +++ src/org/eclipse/jdt/core/tests/model/CompletionTests.java 19 Apr 2011 12:15:45 -0000 @@ -984,6 +984,9 @@ suite.addTest(new CompletionTests("test325481b")); suite.addTest(new CompletionTests("testBug332268a")); suite.addTest(new CompletionTests("testBug332268b")); + suite.addTest(new CompletionTests("testBug292087b")); + suite.addTest(new CompletionTests("testBug292087c")); + suite.addTest(new CompletionTests("testBug292087d")); return suite; } public CompletionTests(String name) { @@ -22947,4 +22950,140 @@ "myVar1[FIELD_REF]{myVar1, Ltest.Test;, I, myVar1, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED + R_EXACT_EXPECTED_TYPE) + "}", requestor.getResults()); } +// 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()); +} }