Merge branch 'master' into integration
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java
index 7b36543..84b904d 100644
--- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java
+++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/IncrementalTests.java
@@ -1053,4 +1053,37 @@
JavaCore.setOptions(options);
}
}
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450
+ // Incremental build should not generate buildpath error
+ // NOT generated by full build.
+ public void testBug364450() throws JavaModelException {
+ IPath projectPath = env.addProject("Project"); //$NON-NLS-1$
+ env.addExternalJars(projectPath, Util.getJavaClassLibs());
+ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$
+
+ IPath wPath = env.addClass(projectPath, "w", "W", //$NON-NLS-1$ //$NON-NLS-2$
+ "package w;\n" +
+ "public class W {\n" +
+ " private w.I i;}"); //$NON-NLS-1$
+
+ IPath aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "import w.I;\n" +
+ "import w.W;\n" +
+ "public class A {}"); //$NON-NLS-1$
+
+ fullBuild(projectPath);
+ expectingSpecificProblemFor(wPath, new Problem("W", "w.I cannot be resolved to a type", wPath, 37, 40, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+
+ aPath = env.addClass(projectPath, "a", "A", //$NON-NLS-1$ //$NON-NLS-2$
+ "package a;\n" +
+ "import w.I;\n" +
+ "import w.W;\n" +
+ "public class A {}"); //$NON-NLS-1$
+
+ incrementalBuild(projectPath);
+ expectingSpecificProblemFor(aPath, new Problem("A", "The import w.I cannot be resolved", aPath, 18, 21, CategorizedProblem.CAT_IMPORT, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
}
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 = "<annotation recovery>";
+ 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/AnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
index 36aaf2e..bbe0ba5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AnnotationTest.java
@@ -7,8 +7,10 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann - Contribution for bug 295551
- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read
+ * Stephan Herrmann - Contributions for
+ * bug 295551 - Add option to automatically promote all warnings to error
+ * bug 185682 - Increment/decrement operators mark local variables as read
+ * bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -9848,4 +9850,302 @@
true,
customOptions);
}
+// Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
+// many syntax errors fixed, does not trigger CCE
+public void testBug366003() {
+ runNegativeTest(
+ 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() {
+ runNegativeTest(
+ 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() {
+ runNegativeTest(
+ 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");
+}
+// unfinished attempt to trigger the same CCE via catch formal parameters
+public void testBug366003d() {
+ runNegativeTest(
+ new String[] {
+ "snippet/Bug366003.java",
+ "package snippet; \n" +
+ "public class Bug366003 {\n" +
+ " void foo() {\n" +
+ " try {\n" +
+ " System.out.println(\"\");\n" +
+ " } catch (Exeption eFirst) {\n" +
+ " e } catch (@Blah Exception eSecond) {\n" +
+ " e }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in snippet\\Bug366003.java (at line 7)\n" +
+ " e } catch (@Blah Exception eSecond) {\n" +
+ " ^\n" +
+ "Syntax error, insert \"AssignmentOperator Expression\" to complete Assignment\n" +
+ "----------\n" +
+ "2. ERROR in snippet\\Bug366003.java (at line 7)\n" +
+ " e } catch (@Blah Exception eSecond) {\n" +
+ " ^\n" +
+ "Syntax error, insert \";\" to complete BlockStatements\n" +
+ "----------\n" +
+ "3. ERROR in snippet\\Bug366003.java (at line 8)\n" +
+ " e }\n" +
+ " ^\n" +
+ "Syntax error, insert \"AssignmentOperator Expression\" to complete Expression\n" +
+ "----------\n" +
+ "4. ERROR in snippet\\Bug366003.java (at line 8)\n" +
+ " e }\n" +
+ " ^\n" +
+ "Syntax error, insert \";\" to complete BlockStatements\n" +
+ "----------\n");
+}
+public void testBug366003e() {
+ runNegativeTest(
+ 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.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
index 340c8e0..3e46fd6 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/BatchCompilerTest.java
@@ -12302,4 +12302,54 @@
"1 problem (1 warning)",
true);
}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829
+// -warn option - regression test to check option syncOverride
+// Warning when when a class overrides a synchronized method without synchronizing it
+public void test310_warn_options() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "class X { synchronized void foo() {} }\n" +
+ "class Y extends X { @Override void foo() { } }"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\""
+ + " -sourcepath \"" + OUTPUT_DIR + "\""
+ + " -warn:syncOverride -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "----------\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
+ " class Y extends X { @Override void foo() { } }\n" +
+ " ^^^^^\n" +
+ "The method Y.foo() is overriding a synchronized method without being synchronized\n" +
+ "----------\n" +
+ "1 problem (1 warning)",
+ true);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829
+// -warn option - regression test to check option syncOverride
+// Warning when when a class overrides a synchronized method without synchronizing it
+public void test310b_warn_options() {
+ this.runConformTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void bar() { new X() { @Override void foo() {} }; }\n"+
+ " synchronized void foo() { }\n"+
+ "}"
+ },
+ "\"" + OUTPUT_DIR + File.separator + "X.java\""
+ + " -sourcepath \"" + OUTPUT_DIR + "\""
+ + " -warn:syncOverride -1.5 -proc:none -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "----------\n" +
+ "1. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/X.java (at line 2)\n" +
+ " void bar() { new X() { @Override void foo() {} }; }\n"+
+ " ^^^^^\n" +
+ "The method new X(){}.foo() is overriding a synchronized method without being synchronized\n" +
+ "----------\n" +
+ "1 problem (1 warning)",
+ true);
+}
}
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..6227a8a 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
@@ -19,6 +19,7 @@
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
// see bug 186342 - [compiler][null] Using annotations for null checking
public class NullAnnotationTest extends AbstractComparableTest {
@@ -52,7 +53,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[] { "test_nonnull_return_014" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -550,6 +551,110 @@
"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
"----------\n");
}
+// non-null varargs (message send)
+public void test_nonnull_parameter_015() {
+ if (this.complianceLevel > ClassFileConstants.JDK1_7) {
+ fail("Reminder: should check if JSR 308 mandates a change in handling vararg elements (see bug 365983).");
+ return;
+ }
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " void foo(@NonNull Object ... o) {\n" +
+ " if (o != null)\n" +
+ " System.out.print(o.toString());\n" +
+ " }\n" +
+ " void foo2(int i, @NonNull Object ... o) {\n" +
+ " if (o.length > 0 && o[0] != null)\n" +
+ " System.out.print(o[0].toString());\n" +
+ " }\n" +
+ " void bar() {\n" +
+ " foo((Object)null);\n" + // unchecked: single plain argument
+ " Object[] objs = null;\n" +
+ " foo(objs);\n" + // error
+ " foo(this, null);\n" + // unchecked: multiple plain arguments
+ " foo2(2, (Object)null);\n" + // unchecked: single plain argument
+ " foo2(2, null, this);\n" + // unchecked: multiple plain arguments
+ " foo2(2, null);\n" + // error
+ " }\n" +
+ "}\n"},
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " if (o != null)\n" +
+ " ^\n" +
+ "Redundant null check: The variable o cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 14)\n" +
+ " foo(objs);\n" +
+ " ^^^^\n" +
+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 18)\n" +
+ " foo2(2, null);\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "The argument of type null should explicitly be cast to Object[] for the invocation of the varargs method foo2(int, Object...) from type X. It could alternatively be cast to Object for a varargs invocation\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 18)\n" +
+ " foo2(2, null);\n" +
+ " ^^^^\n" +
+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" +
+ "----------\n",
+ this.LIBS,
+ true /* shouldFlush*/);
+}
+// non-null varargs (allocation and explicit constructor calls)
+public void test_nonnull_parameter_016() {
+ if (this.complianceLevel > ClassFileConstants.JDK1_7) {
+ fail("Reminder: should check if JSR 308 mandates a change in handling vararg elements (see bug 365983).");
+ return;
+ }
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " X(@NonNull Object ... o) {\n" +
+ " if (o != null)\n" +
+ " System.out.print(o.toString());\n" +
+ " }\n" +
+ " class Y extends X {\n" +
+ " Y(int i, @NonNull Object ... o) {\n" +
+ " super(i, (Object)null);\n" +
+ " }\n" +
+ " Y(char c, @NonNull Object ... o) {\n" +
+ " this(1, new Object(), null);\n" +
+ " }\n" +
+ " }\n" +
+ " void bar() {\n" +
+ " new X((Object[])null);\n" +
+ " new X(this, null);\n" +
+ " X x = new X(null, this);\n" +
+ " x.new Y(2, (Object)null);\n" +
+ " this.new Y(2, null, this);\n" +
+ " this.new Y(2, (Object[])null);\n" +
+ " }\n" +
+ "}\n"},
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " if (o != null)\n" +
+ " ^\n" +
+ "Redundant null check: The variable o cannot be null at this location\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 16)\n" +
+ " new X((Object[])null);\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 21)\n" +
+ " this.new Y(2, (Object[])null);\n" +
+ " ^^^^^^^^^^^^^^\n" +
+ "Type mismatch: required \'@NonNull Object[]\' but the provided value is null\n" +
+ "----------\n",
+ this.LIBS,
+ true /* shouldFlush*/);
+}
// assigning potential null to a nonnull local variable
public void test_nonnull_local_001() {
runNegativeTest(
@@ -1513,6 +1618,39 @@
customOptions,
"");
}
+// bug 365835: [compiler][null] inconsistent error reporting.
+public void test_nonnull_return_014() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNull;\n" +
+ "\n" +
+ "public class X {\n" +
+ " @NonNull\n" +
+ " public Object foo(Object x, int y) {\n" +
+ " @NonNull Object local;\n" +
+ " while (true) {\n" +
+ " if (y == 4) {\n" +
+ " local = x; // error\n" +
+ " return x; // only a warning.\n" +
+ " }\n" +
+ " x = null;\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 9)\n" +
+ " local = x; // error\n" +
+ " ^\n" +
+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 10)\n" +
+ " return x; // only a warning.\n" +
+ " ^\n" +
+ "Type mismatch: required \'@NonNull Object\' but the provided value can be null\n" +
+ "----------\n");
+}
//suppress an error regarding null-spec violation
public void test_suppress_001() {
Map customOptions = getCompilerOptions();
@@ -2328,6 +2466,61 @@
"Type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
"----------\n");
}
+// Bug 365836 - [compiler][null] Incomplete propagation of null defaults.
+public void test_default_nullness_012() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "public class X {\n" +
+ " @NonNullByDefault \n" +
+ " public void foo(@Nullable String [] args) {\n" +
+ " class local {\n" +
+ " void zoo(Object o) {\n" +
+ " }\n" +
+ " };\n" +
+ " new local().zoo(null); // defaults applying from foo\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " new local().zoo(null); // defaults applying from foo\n" +
+ " ^^^^\n" +
+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n");
+}
+// Bug 365836 - [compiler][null] Incomplete propagation of null defaults.
+public void test_default_nullness_013() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.NonNullByDefault;\n" +
+ "import org.eclipse.jdt.annotation.Nullable;\n" +
+ "\n" +
+ "@SuppressWarnings(\"unused\")\n" +
+ "public class X {\n" +
+ " @NonNullByDefault \n" +
+ " public void foo(@Nullable String [] args) {\n" +
+ " class local {\n" +
+ " class Deeply {\n" +
+ " Object zoo() {\n" +
+ " return null; // defaults applying from foo\n" +
+ " }\n" +
+ " }\n" +
+ " };\n" +
+ " }\n" +
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 11)\n" +
+ " return null; // defaults applying from foo\n" +
+ " ^^^^\n" +
+ "Type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n");
+}
// a nonnull variable is dereferenced in a loop
public void test_nonnull_var_in_constrol_structure_1() {
Map customOptions = getCompilerOptions();
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
index eec97ac..8ecb0b9 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveElementsTests.java
@@ -2452,7 +2452,7 @@
try {
TestProgressMonitor monitor = TestProgressMonitor.getInstance();
monitor.setCancelledCounter(1);
- movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, monitor);
+ movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, true, monitor);
} catch (OperationCanceledException e) {
isCanceled = true;
}
@@ -2488,7 +2488,7 @@
try {
TestProgressMonitor monitor = TestProgressMonitor.getInstance();
monitor.setCancelledCounter(1);
- movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, monitor);
+ movePositive(typeSource.getMethods(), new IJavaElement[] {typeDest}, null, null, false, true, monitor);
} catch (OperationCanceledException e) {
isCanceled = true;
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
index 3d4d1ec..2b68fd0 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveResourcesTests.java
@@ -80,7 +80,13 @@
}
IJavaElementDelta destDelta = this.deltaListener.getDeltaFor(container, true);
assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
- IJavaElementDelta[] deltas = destDelta.getAddedChildren();
+ IJavaElementDelta[] deltas = null;
+ if (force) {
+ deltas = destDelta.getChangedChildren();
+ }
+ else {
+ deltas = destDelta.getAddedChildren();
+ }
// FIXME: not strong enough
boolean found = false;
for (int i = 0; i < deltas.length; i++) {
@@ -809,25 +815,38 @@
* existing CU.
*/
public void testMoveCU03() throws CoreException {
- this.createFolder("/P/src/p1");
- this.createFile(
- "/P/src/p1/X.java",
- "package p1;\n" +
- "public class X {\n" +
- "}"
- );
- ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
+ try {
+ this.createFolder("/P/src/p1");
+ this.createFile(
+ "/P/src/p1/X.java",
+ "package p1;\n" +
+ "public class X {\n" +
+ "}"
+ );
+ ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
- this.createFolder("/P/src/p2");
- this.createFile(
- "/P/src/p2/X.java",
- "package p2;\n" +
- "public class X {\n" +
- "}"
- );
- IPackageFragment pkgDest = getPackage("/P/src/p2");
-
- movePositive(cuSource, pkgDest, null, null, true);
+ this.createFolder("/P/src/p2");
+ this.createFile(
+ "/P/src/p2/X.java",
+ "package p2;\n" +
+ "public class X {\n" +
+ "}"
+ );
+ IPackageFragment pkgDest = getPackage("/P/src/p2");
+ startDeltas();
+ movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, null, true, false, null);
+ assertDeltas(
+ "Incorrect delta",
+ "P[*]: {CHILDREN}\n"
+ + " src[*]: {CHILDREN}\n"
+ + " p1[*]: {CHILDREN}\n"
+ + " X.java[-]: {MOVED_TO(X.java [in p2 [in src [in P]]])}\n"
+ + " p2[*]: {CHILDREN}\n"
+ + " X.java[*]: {CONTENT | PRIMARY RESOURCE}");
+ }
+ finally {
+ stopDeltas();
+ }
}
/**
* Ensures that a CU can be moved to a different package,
@@ -853,25 +872,39 @@
* be renamed, overwriting an existing resource.
*/
public void testMoveCU05() throws CoreException {
- this.createFolder("/P/src/p1");
- this.createFile(
- "/P/src/p1/X.java",
- "package p1;\n" +
- "public class X {\n" +
- "}"
- );
- ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
+ try {
+ this.createFolder("/P/src/p1");
+ this.createFile(
+ "/P/src/p1/X.java",
+ "package p1;\n" +
+ "public class X {\n" +
+ "}"
+ );
+ ICompilationUnit cuSource = getCompilationUnit("/P/src/p1/X.java");
- this.createFolder("/P/src/p2");
- this.createFile(
- "/P/src/p2/Y.java",
- "package p2;\n" +
- "public class Y {\n" +
- "}"
- );
- IPackageFragment pkgDest = getPackage("/P/src/p2");
-
- movePositive(cuSource, pkgDest, null, "Y.java", true);
+ this.createFolder("/P/src/p2");
+ this.createFile(
+ "/P/src/p2/Y.java",
+ "package p2;\n" +
+ "public class Y {\n" +
+ "}"
+ );
+ IPackageFragment pkgDest = getPackage("/P/src/p2");
+ startDeltas();
+ movePositive(new IJavaElement[] {cuSource}, new IJavaElement[] {pkgDest}, null, new String[]{"Y.java"}, true, false, null);
+ assertDeltas(
+ "Incorrect delta",
+ "P[*]: {CHILDREN}\n"
+ + " src[*]: {CHILDREN}\n"
+ + " p1[*]: {CHILDREN}\n"
+ + " X.java[-]: {MOVED_TO(Y.java [in p2 [in src [in P]]])}\n"
+ + " p2[*]: {CHILDREN}\n"
+ + " Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n"
+ + " Y[+]: {MOVED_FROM(X [in X.java [in p1 [in src [in P]]]])}");
+ }
+ finally {
+ stopDeltas();
+ }
}
/**
* Ensures that a CU cannot be moved to a different package, replacing an
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
index b1066ae..c03e393 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CopyMoveTests.java
@@ -253,12 +253,15 @@
public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force) throws JavaModelException {
movePositive(elements, destinations, siblings, names, force, null);
}
+public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
+ movePositive(elements, destinations, siblings, names, force, true, null);
+}
/**
* Moves the elements to the containers with optional renaming
* and forcing. The operation should succeed, so any exceptions
* encountered are thrown.
*/
-public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, IProgressMonitor monitor) throws JavaModelException {
+public void movePositive(IJavaElement[] elements, IJavaElement[] destinations, IJavaElement[] siblings, String[] names, boolean force, boolean checkDelta, IProgressMonitor monitor) throws JavaModelException {
// if forcing, ensure that a name collision exists
int i;
if (force) {
@@ -275,7 +278,7 @@
}
try {
- startDeltas();
+ if(checkDelta) startDeltas();
// move
getJavaModel().move(elements, destinations, siblings, names, force, monitor);
@@ -341,24 +344,26 @@
}
}
}
- IJavaElementDelta destDelta = null;
- if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
- destDelta = this.deltaListener.getDeltaFor(moved.getParent());
- assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
- assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
- assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent()));
- } else {
- destDelta = this.deltaListener.getDeltaFor(destinations[i], true);
- assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
- IJavaElementDelta[] deltas = destDelta.getAddedChildren();
- assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
- assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
- IJavaElementDelta sourceDelta= this.deltaListener.getDeltaFor(element, false);
- assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED);
+ if(checkDelta) {
+ IJavaElementDelta destDelta = null;
+ if (isMainType(element, destinations[i]) && names != null && names[i] != null) { //moved/renamed main type to same cu
+ destDelta = this.deltaListener.getDeltaFor(moved.getParent());
+ assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED);
+ assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0);
+ assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(element.getParent()));
+ } else {
+ destDelta = this.deltaListener.getDeltaFor(destinations[i], true);
+ assertTrue("Destination container not changed", destDelta != null && destDelta.getKind() == IJavaElementDelta.CHANGED);
+ IJavaElementDelta[] deltas = destDelta.getAddedChildren();
+ assertTrue("Added children not correct for element copy", deltas[i].getElement().equals(moved));
+ assertTrue("should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
+ IJavaElementDelta sourceDelta= this.deltaListener.getDeltaFor(element, false);
+ assertTrue("should be K_REMOVED", sourceDelta.getKind() == IJavaElementDelta.REMOVED);
+ }
}
}
} finally {
- stopDeltas();
+ if(checkDelta) stopDeltas();
}
}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
index f08ed7a..92b80fa 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/RenameTests.java
@@ -115,9 +115,9 @@
assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(e.getParent()));
} else {
assertTrue("Destination container not changed", destDelta != null && deltaChildrenChanged(destDelta));
- IJavaElementDelta[] deltas = destDelta.getAddedChildren();
+ IJavaElementDelta[] deltas = force ? destDelta.getChangedChildren() : destDelta.getAddedChildren();
assertTrue("Added children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(renamed));
- assertTrue("kind should be K_ADDED", deltas[i].getKind() == IJavaElementDelta.ADDED);
+ assertTrue("kind should be K_ADDED", deltas[i].getKind() == (force? IJavaElementDelta.CHANGED : IJavaElementDelta.ADDED));
deltas = destDelta.getRemovedChildren();
assertTrue("Removed children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(e));
assertTrue("kind should be K_REMOVED", deltas[i].getKind() == IJavaElementDelta.REMOVED);
@@ -364,11 +364,12 @@
assertDeltas(
"Unexpected deltas",
- "P[*]: {CHILDREN}\n" +
- " src[*]: {CHILDREN}\n" +
- " <default>[*]: {CHILDREN}\n" +
- " X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" +
- " Y.java[+]: {MOVED_FROM(X.java [in <default> [in src [in P]]])}"
+ "P[*]: {CHILDREN}\n" +
+ " src[*]: {CHILDREN}\n" +
+ " <default>[*]: {CHILDREN}\n" +
+ " X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" +
+ " Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" +
+ " Y[+]: {MOVED_FROM(X [in X.java [in <default> [in src [in P]]]])}"
);
}
/*
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
index 3211979..a67f3cc 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/Main.java
@@ -3491,6 +3491,9 @@
} else if (token.equals("static-method")) { //$NON-NLS-1$
setSeverity(CompilerOptions.OPTION_ReportMethodCanBeStatic, severity, isEnabling);
return;
+ } else if (token.equals("syncOverride")) { //$NON-NLS-1$
+ setSeverity(CompilerOptions.OPTION_ReportMissingSynchronizedOnInheritedMethod, severity, isEnabling);
+ return;
}
break;
case 't' :
diff --git a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
index 3902328..6985fe3 100644
--- a/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
+++ b/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties
@@ -19,7 +19,7 @@
#Format: compiler.name = word1 word2 word3
compiler.name = Eclipse Compiler for Java(TM)
#Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)]
-compiler.version = 0.C25, 3.8.0 M4
+compiler.version = 0.C26, 3.8.0 M4
compiler.copyright = Copyright IBM Corp 2000, 2011. All rights reserved.
### progress
diff --git a/org.eclipse.jdt.core/buildnotes_jdt-core.html b/org.eclipse.jdt.core/buildnotes_jdt-core.html
index e54753d..0e46cc5 100644
--- a/org.eclipse.jdt.core/buildnotes_jdt-core.html
+++ b/org.eclipse.jdt.core/buildnotes_jdt-core.html
@@ -42,11 +42,34 @@
</td>
</tr>
</table>
+<a name="v_C26"></a>
+<hr><h1>
+Eclipse Platform Build Notes<br>
+Java development tools core</h1>
+Eclipse SDK 3.8.0 - December 20, 2011 - December 2, 2011
+<h2>What's new in this drop</h2>
+
+<h3>Problem Reports Fixed</h3>
+<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=362711">362711</a>
+possibly incorrect JDT POST_CHANGE event fired when a file is replaced
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365835">365835</a>
+[compiler][null] inconsistent error reporting.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365836">365836</a>
+[compiler][null] Incomplete propagation of null defaults.
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=365983">365983</a>
+[compiler][null] AIOOB with null annotation analysis and varargs
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366003">366003</a>
+CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=366829">366829</a>
+Batch compiler option and SuppressWarnings token for Overriding a Synchronized Method with a Non-synchronized Method
+<br><a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450">364450</a>
+Dubious class path error triggers a full rebuild
+
<a name="v_C25"></a>
<hr><h1>
Eclipse Platform Build Notes<br>
Java development tools core</h1>
-Eclipse SDK 3.8.0 - December 13, 2011 - December 2, 2011
+Eclipse SDK 3.8.0 - December 13, 2011
<h2>What's new in this drop</h2>
<ul>
<li>New constant for the name of index location class path attribute in IClasspathAttribute(see bug <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=356620">356620</a> for details)
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/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
index 57f4d89..61c67a0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java
@@ -12,6 +12,7 @@
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 360328 - [compiler][null] detect null problems in nested code (local class inside a loop)
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 365835 - [compiler][null] inconsistent error reporting.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -46,7 +47,7 @@
this.expression.checkNPE(currentScope, flowContext, flowInfo);
}
if (flowInfo.reachMode() == FlowInfo.REACHABLE)
- checkAgainstNullAnnotation(currentScope, this.expression.nullStatus(flowInfo));
+ checkAgainstNullAnnotation(currentScope, flowContext, this.expression.nullStatus(flowInfo));
FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression);
if (trackingVariable != null) {
if (methodScope != trackingVariable.methodScope)
@@ -122,7 +123,7 @@
currentScope.checkUnclosedCloseables(flowInfo, this, currentScope);
return FlowInfo.DEAD_END;
}
-void checkAgainstNullAnnotation(BlockScope scope, int nullStatus) {
+void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, int nullStatus) {
if (nullStatus != FlowInfo.NON_NULL) {
// if we can't prove non-null check against declared null-ness of the enclosing method:
long tagBits;
@@ -134,8 +135,7 @@
return;
}
if ((tagBits & TagBits.AnnotationNonNull) != 0) {
- char[][] annotationName = scope.environment().getNonNullAnnotationName();
- scope.problemReporter().nullityMismatch(this.expression, methodBinding.returnType, nullStatus, annotationName);
+ flowContext.recordNullityMismatch(scope, this.expression, nullStatus, methodBinding.returnType);
}
}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
index 073ecc1..8f68b7c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java
@@ -8,9 +8,10 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Stephan Herrmann - Contributions for
- * bug 335093 - [compiler][null] minimal hook for future null annotation support
- * bug 349326 - [1.7] new warning for missing try-with-resources
+ * bug 335093 - [compiler][null] minimal hook for future null annotation support
+ * bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 365983 - [compiler][null] AIOOB with null annotation analysis and varargs
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.ast;
@@ -64,7 +65,26 @@
{
// compare actual null-status against parameter annotations of the called method:
if (arguments != null && methodBinding.parameterNonNullness != null) {
- for (int i = 0; i < arguments.length; i++) {
+
+ // check if varargs need special treatment:
+ int numParamsToCheck = methodBinding.parameters.length;
+ boolean passThrough = false;
+ if (methodBinding.isVarargs()) {
+ int varArgPos = numParamsToCheck-1;
+ // this if-block essentially copied from generateArguments(..):
+ if (numParamsToCheck == arguments.length) {
+ TypeBinding varArgsType = methodBinding.parameters[varArgPos];
+ TypeBinding lastType = arguments[varArgPos].resolvedType;
+ if (lastType == TypeBinding.NULL
+ || (varArgsType.dimensions() == lastType.dimensions()
+ && lastType.isCompatibleWith(varArgsType)))
+ passThrough = true; // pass directly as-is
+ }
+ if (!passThrough)
+ numParamsToCheck--; // with non-passthrough varargs last param is fed from individual args -> don't check
+ }
+
+ for (int i = 0; i < numParamsToCheck; i++) {
if (methodBinding.parameterNonNullness[i] == Boolean.TRUE) {
TypeBinding expectedType = methodBinding.parameters[i];
Expression argument = arguments[i];
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
index c973fd3..bd0c98d 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java
@@ -423,6 +423,7 @@
"static-method", //$NON-NLS-1$
"super", //$NON-NLS-1$
"synthetic-access", //$NON-NLS-1$
+ "syncOverride", //$NON-NLS-1$
"unchecked", //$NON-NLS-1$
"unqualified-field-access", //$NON-NLS-1$
"unused", //$NON-NLS-1$
@@ -862,6 +863,8 @@
case MissingJavadocComments :
case MissingJavadocTags:
return "javadoc"; //$NON-NLS-1$
+ case MissingSynchronizedModifierInInheritedMethod:
+ return "syncOverride"; //$NON-NLS-1$
}
return null;
}
@@ -932,6 +935,8 @@
if ("super".equals(warningToken)) { //$NON-NLS-1$
return IrritantSet.SUPER;
}
+ if ("syncOverride".equals(warningToken)) //$NON-NLS-1$
+ return IrritantSet.SYNCHRONIZED;
break;
case 'u' :
if ("unused".equals(warningToken)) //$NON-NLS-1$
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
index 4c77979..2de9409 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java
@@ -56,6 +56,7 @@
public static final IrritantSet STATIC_ACCESS = new IrritantSet(CompilerOptions.IndirectStaticAccess);
public static final IrritantSet STATIC_METHOD = new IrritantSet(CompilerOptions.MethodCanBeStatic);
public static final IrritantSet SYNTHETIC_ACCESS = new IrritantSet(CompilerOptions.AccessEmulation);
+ public static final IrritantSet SYNCHRONIZED = new IrritantSet(CompilerOptions.MissingSynchronizedModifierInInheritedMethod);
public static final IrritantSet SUPER = new IrritantSet(CompilerOptions.OverridingMethodWithoutSuperInvocation);
public static final IrritantSet UNUSED = new IrritantSet(CompilerOptions.UnusedLocalVariable);
public static final IrritantSet UNCHECKED = new IrritantSet(CompilerOptions.UncheckedTypeOperation);
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
index f4b99d8..0b48bbb 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/LookupEnvironment.java
@@ -1267,7 +1267,13 @@
packageBinding.addType(binding);
} else if (binding == TheNotFoundType) {
// report the missing class file first
- this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation);
+ if (!wasMissingType) {
+ /* Since missing types have been already been complained against while producing binaries, there is no class path
+ * misconfiguration now that did not also exist in some equivalent form while producing the class files which encode
+ * these missing types. So no need to bark again. Note that wasMissingType == true signals a type referenced in a .class
+ * file which could not be found when the binary was produced. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=364450 */
+ this.problemReporter.isClassPathCorrect(compoundName, this.unitBeingCompleted, this.missingClassFileLocation);
+ }
// create a proxy for the missing BinaryType
binding = createMissingType(null, compoundName);
} else if (!isParameterized) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
index e8b277c..e96a1f9 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/SourceTypeBinding.java
@@ -11,6 +11,7 @@
* bug 328281 - visibility leaks not detected when analyzing unused field in private class
* bug 349326 - [1.7] new warning for missing try-with-resources
* bug 186342 - [compiler][null] Using annotations for null checking
+ * bug 365836 - [compiler][null] Incomplete propagation of null defaults.
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
@@ -1667,6 +1668,12 @@
annotationBinding = ((SourceTypeBinding) currentType).getNullnessDefaultAnnotation();
if (annotationBinding != null)
return annotationBinding;
+ if (currentType.isLocalType()) {
+ // if direct enclosing is a method travel that way:
+ MethodBinding enclosingMethod = ((LocalTypeBinding)currentType).enclosingMethod;
+ if (enclosingMethod != null)
+ return findDefaultNullness(enclosingMethod, environment);
+ }
currentType = currentType.enclosingType();
}
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..daff09b 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
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196
+ * Stephan Herrmann - Contribution for Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;
@@ -3943,6 +3944,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..aac6d22 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for Bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;
@@ -773,4 +774,23 @@
this.typeDeclaration.bodyEnd = end;
}
}
+public void annotationsConsumed(Annotation[] consumedAnnotations) {
+ RecoveredAnnotation[] keep = new RecoveredAnnotation[this.pendingAnnotationCount];
+ int numKeep = 0;
+ int pendingCount = this.pendingAnnotationCount;
+ int consumedLength = consumedAnnotations.length;
+ outerLoop:
+ for (int i = 0; i < pendingCount; i++) {
+ Annotation pendingAnnotationAST = this.pendingAnnotations[i].annotation;
+ for (int j = 0; j < consumedLength; 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--;
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
index 291378c..426d41e 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CopyResourceElementsOperation.java
@@ -266,20 +266,29 @@
* <li>On a copy, the delta should be rooted in the dest project
* <li>On a move, two deltas are generated<ul>
* <li>one rooted in the source project
- * <li>one rooted in the destination project</ul></ul>
+ * <li>one rooted in the destination project
+ * <li> When a CU is being overwritten, the delta on the destination will be of type F_CONTENT </ul></ul>
* If the operation is rooted in a single project, the delta is rooted in that project
*
*/
- protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove) {
+ protected void prepareDeltas(IJavaElement sourceElement, IJavaElement destinationElement, boolean isMove, boolean overWriteCU) {
if (Util.isExcluded(sourceElement) || Util.isExcluded(destinationElement)) return;
+
IJavaProject destProject = destinationElement.getJavaProject();
if (isMove) {
IJavaProject sourceProject = sourceElement.getJavaProject();
getDeltaFor(sourceProject).movedFrom(sourceElement, destinationElement);
- getDeltaFor(destProject).movedTo(destinationElement, sourceElement);
+ if (!overWriteCU) {
+ getDeltaFor(destProject).movedTo(destinationElement, sourceElement);
+ return;
+ }
} else {
- getDeltaFor(destProject).added(destinationElement);
+ if (!overWriteCU) {
+ getDeltaFor(destProject).added(destinationElement);
+ return;
+ }
}
+ getDeltaFor(destinationElement.getJavaProject()).changed(destinationElement, IJavaElementDelta.F_CONTENT);
}
/**
* Copies/moves a compilation unit with the name <code>newCUName</code>
@@ -357,12 +366,14 @@
}
// register the correct change deltas
- prepareDeltas(source, destCU, isMove());
+ boolean contentChanged = this.force && destFile.exists();
+ prepareDeltas(source, destCU, isMove(), contentChanged);
+
if (newCUName != null) {
//the main type has been renamed
String oldName = Util.getNameWithoutJavaLikeExtension(source.getElementName());
String newName = Util.getNameWithoutJavaLikeExtension(newCUName);
- prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove());
+ prepareDeltas(source.getType(oldName), destCU.getType(newName), isMove(), false);
}
} else {
if (!this.force) {