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..2789f1a 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,281 @@ "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 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"); +} } 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..3daa61d 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[i] == pendingAnnotationAST) + continue outerLoop; + } + keep[numKeep++] = this.pendingAnnotations[i]; + } + if (numKeep != this.pendingAnnotationCount) { + this.pendingAnnotations = keep; + this.pendingAnnotationCount = numKeep; + } +} }