diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java index 695aa46..6e8ba36 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/parser/AnnotationDietRecoveryTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2008 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 @@ -1909,4 +1909,59 @@ expectedCompletionDietUnitToString, testName); } +// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366003 +public void test0041() { + + String s = + "package snippet;\n" + + "public class Bug366003 {\n" + + " void foo(Object o1){}\n" + + " @Blah org.User(@Bla String str){}\n" + + "}\n"; + + String expectedDietUnitToString = + "package snippet;\n" + + "public class Bug366003 {\n" + + " public Bug366003() {\n" + + " }\n" + + " void foo(Object o1) {\n" + + " }\n" + + " @Blah User(@Bla String str) {\n" + + " }\n" + + "}\n"; + + String expectedDietPlusBodyUnitToString = + "package snippet;\n" + + "public class Bug366003 {\n" + + " public Bug366003() {\n" + + " super();\n" + + " }\n" + + " void foo(Object o1) {\n" + + " }\n" + + " @Blah User(@Bla String str) {\n" + + " }\n" + + "}\n"; + + String expectedFullUnitToString = expectedDietUnitToString; + + String expectedCompletionDietUnitToString = + "package snippet;\n" + + "public class Bug366003 {\n" + + " public Bug366003() {\n" + + " }\n" + + " void foo(Object o1) {\n" + + " }\n" + + " User(@Bla String str) {\n" + + " }\n" + + "}\n"; + + String testName = ""; + checkParse( + s.toCharArray(), + expectedDietUnitToString, + expectedDietPlusBodyUnitToString, + expectedFullUnitToString, + expectedCompletionDietUnitToString, + testName); +} } diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java index 53d8a6f..37fb551 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullAnnotationTest.java @@ -52,7 +52,7 @@ // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which do not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "test_assignment_expression_1" }; +// TESTS_NAMES = new String[] { "testBug366003c" }; // TESTS_NUMBERS = new int[] { 561 }; // TESTS_RANGE = new int[] { 1, 2049 }; } @@ -2763,4 +2763,298 @@ "Dead code\n" + "----------\n"); } +// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) +// many syntax errors fixed, does not trigger CCE +public void testBug366003() { + runNegativeTestWithLibs( + new String[] { + "snippet/Bug366003.java", + "package snippet;\n" + + "public class Bug366003 {\n" + + " public void foo(@NonNull Object o1) {\n" + + " System.out.println(o1.toString()); // OK: o1 cannot be null\n" + + " } \n" + + " @NonNull Object bar(@Nullable String s1) {\n" + + " foo(null); // cannot pass null argument\n" + + " @NonNull String s= null; // cannot assign null value\n" + + " @NonNull String t= s1; // cannot assign potentially null value\n" + + " return null; // cannot return null value\n" + + " }\n" + + "}\n" + + "org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + "" + }, + "----------\n" + + "1. ERROR in snippet\\Bug366003.java (at line 3)\n" + + " public void foo(@NonNull Object o1) {\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in snippet\\Bug366003.java (at line 6)\n" + + " @NonNull Object bar(@Nullable String s1) {\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "3. ERROR in snippet\\Bug366003.java (at line 6)\n" + + " @NonNull Object bar(@Nullable String s1) {\n" + + " ^^^^^^^^\n" + + "Nullable cannot be resolved to a type\n" + + "----------\n" + + "4. ERROR in snippet\\Bug366003.java (at line 8)\n" + + " @NonNull String s= null; // cannot assign null value\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "5. ERROR in snippet\\Bug366003.java (at line 9)\n" + + " @NonNull String t= s1; // cannot assign potentially null value\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "6. ERROR in snippet\\Bug366003.java (at line 12)\n" + + " }\n" + + " ^\n" + + "Syntax error on token \"}\", delete this token\n" + + "----------\n" + + "7. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^^^^^^^^^\n" + + "Syntax error on tokens, delete these tokens\n" + + "----------\n" + + "8. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + + "----------\n" + + "9. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + + "----------\n" + + "10. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n" + + "11. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Return type for the method is missing\n" + + "----------\n" + + "12. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "13. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^\n" + + "Nullable cannot be resolved to a type\n" + + "----------\n" + + "14. ERROR in snippet\\Bug366003.java (at line 13)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^\n" + + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + + "----------\n"); +} +// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) +// code is garbage, triggers CCE +public void testBug366003b() { + runNegativeTestWithLibs( + new String[] { + "snippet/Bug366003.java", + "package snippet;\n" + + "public class Bug366003 {\n" + + " public void foo(@Blah Object o1) { \n" + + "System.out.println(o1.toString()); // OK: o1 cannot be null } \n" + + "@Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + + "null argument @Blah String s= null; // cannot assign null value \n" + + " @Blah String t= s1; // cannot assign potentially null value \n" + + "return null; // cannot return null value }\n" + + "}\n" + + "\n" + + "org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + "" + }, + "----------\n" + + "1. ERROR in snippet\\Bug366003.java (at line 3)\n" + + " public void foo(@Blah Object o1) { \n" + + " ^^^^\n" + + "Blah cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " System.out.println(o1.toString()); // OK: o1 cannot be null } \n" + + " ^\n" + + "Syntax error, insert \"}\" to complete MethodBody\n" + + "----------\n" + + "3. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " @Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + + " ^^^^\n" + + "Blah cannot be resolved to a type\n" + + "----------\n" + + "4. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " @Blah Object bar(@BlahBlah String s1) { foo(null); // cannot pass\n" + + " ^^^^^^^^\n" + + "BlahBlah cannot be resolved to a type\n" + + "----------\n" + + "5. ERROR in snippet\\Bug366003.java (at line 6)\n" + + " null argument @Blah String s= null; // cannot assign null value \n" + + " ^^^^\n" + + "Syntax error on token \"null\", @ expected\n" + + "----------\n" + + "6. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^^^^^^^^^\n" + + "Syntax error on tokens, delete these tokens\n" + + "----------\n" + + "7. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + + "----------\n" + + "8. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + + "----------\n" + + "9. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n" + + "10. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + + "Return type for the method is missing\n" + + "----------\n" + + "11. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^\n" + + "NonNull cannot be resolved to a type\n" + + "----------\n" + + "12. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^^^^^^^^\n" + + "Nullable cannot be resolved to a type\n" + + "----------\n" + + "13. ERROR in snippet\\Bug366003.java (at line 11)\n" + + " org.eclipse.User.User(@NonNull String name, int uid, @Nullable String email)\n" + + " ^\n" + + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + + "----------\n"); +} +// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639) +// minimal syntax error to trigger CCE +public void testBug366003c() { + runNegativeTestWithLibs( + new String[] { + "snippet/Bug366003.java", + "package snippet;\n" + + "public class Bug366003 {\n" + + " void foo(Object o1) {\n" + + " }\n" + + "org.User(@Bla String a)" + }, + "----------\n" + + "1. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Syntax error on token \"org\", delete this token\n" + + "----------\n" + + "2. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Syntax error, insert \"enum Identifier\" to complete EnumHeaderName\n" + + "----------\n" + + "3. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Syntax error, insert \"EnumBody\" to complete EnumDeclaration\n" + + "----------\n" + + "4. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n" + + "5. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^^^^^^^^^^^^^^^^^\n" + + "Return type for the method is missing\n" + + "----------\n" + + "6. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^^^\n" + + "Bla cannot be resolved to a type\n" + + "----------\n" + + "7. ERROR in snippet\\Bug366003.java (at line 5)\n" + + " org.User(@Bla String a)\n" + + " ^\n" + + "Syntax error, insert \";\" to complete ConstructorDeclaration\n" + + "----------\n"); +} +public void testBug366003d() { + runNegativeTestWithLibs( + new String[] { + "snippet/Bug366003.java", + "package snippet;\n" + + "public class Bug366003 {\n" + + " {\n" + + " wrong\n" + + " try {\n" + + " } catch (@Bla String a) \n" + + " }\n" + }, + "----------\n" + + "1. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " wrong\n" + + " ^^^^^\n" + + "Syntax error, insert \"AssignmentOperator Expression\" to complete Assignment\n" + + "----------\n" + + "2. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " wrong\n" + + " ^^^^^\n" + + "Syntax error, insert \";\" to complete BlockStatements\n" + + "----------\n" + + "3. ERROR in snippet\\Bug366003.java (at line 6)\n" + + " } catch (@Bla String a) \n" + + " ^\n" + + "Syntax error on token \")\", Block expected after this token\n" + + "----------\n" + + "4. ERROR in snippet\\Bug366003.java (at line 7)\n" + + " }\n" + + " ^\n" + + "Syntax error, insert \"}\" to complete ClassBody\n" + + "----------\n"); +} +public void testBug366003e() { + runNegativeTestWithLibs( + new String[] { + "snippet/Bug366003.java", + "package snippet;\n" + + "public class Bug366003 {\n" + + " void foo(Object o1){}\n" + + " @Blah org.User(@Bla String str){}\n" + + "}\n" + }, + "----------\n" + + "1. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " @Blah org.User(@Bla String str){}\n" + + " ^^^^\n" + + "Blah cannot be resolved to a type\n" + + "----------\n" + + "2. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " @Blah org.User(@Bla String str){}\n" + + " ^^^^\n" + + "Syntax error on token \"User\", Identifier expected after this token\n" + + "----------\n" + + "3. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " @Blah org.User(@Bla String str){}\n" + + " ^^^^^^^^^^^^^^^^^^^^^\n" + + "Return type for the method is missing\n" + + "----------\n" + + "4. ERROR in snippet\\Bug366003.java (at line 4)\n" + + " @Blah org.User(@Bla String str){}\n" + + " ^^^\n" + + "Bla cannot be resolved to a type\n" + + "----------\n"); +} } 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 afd0ccc..927db1b 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 @@ -2627,6 +2627,9 @@ arg.annotations = new Annotation[length], 0, length); + RecoveredType currentRecoveryType = this.currentRecoveryType(); + if (currentRecoveryType != null) + currentRecoveryType.annotationsConsumed(arg.annotations); } arg.isCatchArgument = topKnownElementKind(COMPLETION_OR_ASSIST_PARSER) == K_BETWEEN_CATCH_AND_RIGHT_PAREN; diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java index 5e59a1b..0be1b54 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java @@ -634,6 +634,9 @@ arg.annotations = new Annotation[length], 0, length); + RecoveredType currentRecoveryType = this.currentRecoveryType(); + if (currentRecoveryType != null) + currentRecoveryType.annotationsConsumed(arg.annotations); } pushOnAstStack(arg); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java index 121be78..7f9986a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -3943,6 +3943,9 @@ arg.annotations = new Annotation[length], 0, length); + RecoveredType currentRecoveryType = this.currentRecoveryType(); + if (currentRecoveryType != null) + currentRecoveryType.annotationsConsumed(arg.annotations); } pushOnAstStack(arg); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java index ea53456..8dccb57 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveredType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 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 @@ -773,4 +773,21 @@ this.typeDeclaration.bodyEnd = end; } } +public void annotationsConsumed(Annotation[] consumedAnnotations) { + RecoveredAnnotation[] keep = new RecoveredAnnotation[this.pendingAnnotationCount]; + int numKeep = 0; + outerLoop: + for (int i = 0; i < this.pendingAnnotationCount; i++) { + Annotation pendingAnnotationAST = this.pendingAnnotations[i].annotation; + for (int j = 0; j < consumedAnnotations.length; j++) { + if (consumedAnnotations[j] == pendingAnnotationAST) + continue outerLoop; + } + keep[numKeep++] = this.pendingAnnotations[i]; + } + if (numKeep != this.pendingAnnotationCount) { + this.pendingAnnotations = keep; + this.pendingAnnotationCount = numKeep; + } +} } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java index cea4763..597b56c 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/DocumentElementParser.java @@ -623,6 +623,9 @@ arg.annotations = new Annotation[length], 0, length); + RecoveredType currentRecoveryType = this.currentRecoveryType(); + if (currentRecoveryType != null) + currentRecoveryType.annotationsConsumed(arg.annotations); } pushOnAstStack(arg); this.intArrayPtr--;