update jdt.core.tests to v20130129-050623 (4.3M5).
diff --git a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
index a08cfcf..4e51e16 100644
--- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.tests.compiler
-Bundle-Version: 3.8.1
+Bundle-Version: 3.8.2
Bundle-ClassPath: jdtcoretestscompiler.jar
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.core.tests.compiler/pom.xml b/org.eclipse.jdt.core.tests.compiler/pom.xml
index fbdfee3..2d3a6d0 100644
--- a/org.eclipse.jdt.core.tests.compiler/pom.xml
+++ b/org.eclipse.jdt.core.tests.compiler/pom.xml
@@ -20,6 +20,6 @@
</parent>
<groupId>eclipse.jdt.core</groupId>
<artifactId>org.eclipse.jdt.core.tests.compiler</artifactId>
- <version>3.8.1-SNAPSHOT</version>
+ <version>3.8.2-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
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 dfbeb86..9608c05 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -13,6 +13,7 @@
* bug 366003 - CCE in ASTNode.resolveAnnotations(ASTNode.java:639)
* bug 384663 - Package Based Annotation Compilation Error in JDT 3.8/4.2 (works in 3.7.2)
* bug 386356 - Type mismatch error with annotations and generics
+ * bug 331649 - [compiler][null] consider null annotations for fields
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -10401,7 +10402,7 @@
"}\n" +
"class E3 {\n" +
" @p.NonNull\n" +
- " private int E3;\n" +
+ " private Object E3 = new Object();\n" +
"}\n" +
"class E4 {\n" +
" @Deprecated\n" +
@@ -10441,8 +10442,8 @@
"The value of the field E2.E2 is not used\n" +
"----------\n" +
"4. ERROR in Example.java (at line 15)\n" +
- " private int E3;\n" +
- " ^^\n" +
+ " private Object E3 = new Object();\n" +
+ " ^^\n" +
"The value of the field E3.E3 is not used\n" +
"----------\n",
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
@@ -10698,4 +10699,80 @@
});
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=398657
+public void test398657() throws Exception {
+ if (this.complianceLevel != ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+ options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+ this.runConformTest(
+ new String[] {
+ "p/Annot.java",
+ "package p;\n" +
+ "public @interface Annot {\n" +
+ " static public enum E { A }\n" +
+ " E getEnum();\n" +
+ "}",
+ "X.java",
+ "import static p.Annot.E.*;\n" +
+ "import p.Annot;" +
+ "@Annot(getEnum=A)\n" +
+ "public class X {}"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null,
+ true);
+
+ String expectedOutput =
+ " Inner classes:\n" +
+ " [inner class info: #22 p/Annot$E, outer class info: #24 p/Annot\n" +
+ " inner name: #26 E, accessflags: 16409 public static final]\n";
+
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator +"X.class", "X", expectedOutput, ClassFileBytesDisassembler.DETAILED);
+}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=398657
+public void test398657_2() throws Exception {
+ if (this.complianceLevel != ClassFileConstants.JDK1_5) {
+ return;
+ }
+ Map options = getCompilerOptions();
+ options.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
+ options.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
+ options.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
+ this.runConformTest(
+ new String[] {
+ "p/Y.java",
+ "package p;\n" +
+ "public class Y {\n" +
+ " static public @interface Annot {\n" +
+ " int id();\n" +
+ " }\n" +
+ "}",
+ "X.java",
+ "import p.Y.Annot;\n" +
+ "@Annot(id=4)\n" +
+ "public class X {}"
+ },
+ "",
+ null,
+ true,
+ null,
+ options,
+ null,
+ true);
+
+ String expectedOutput =
+ " Inner classes:\n" +
+ " [inner class info: #21 p/Y$Annot, outer class info: #23 p/Y\n" +
+ " inner name: #25 Annot, accessflags: 9737 public abstract static]\n";
+
+ checkDisassembledClassFile(OUTPUT_DIR + File.separator +"X.class", "X", expectedOutput, ClassFileBytesDisassembler.DETAILED);
+}
}
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 b7c9ef1..656bac1 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
@@ -23,6 +23,7 @@
* bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set
* bug 388281 - [compiler][null] inheritance of null annotations as an option
* bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ * bug 383368 - [compiler][null] syntactic null analysis for field references
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -1995,6 +1996,7 @@
" <option key=\"org.eclipse.jdt.core.compiler.problem.noEffectAssignment\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral\" value=\"ignore\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict\" value=\"error\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.nullReference\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.nullSpecViolation\" value=\"error\"/>\n" +
@@ -2016,6 +2018,7 @@
" <option key=\"org.eclipse.jdt.core.compiler.problem.staticAccessReceiver\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors\" value=\"disabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.suppressWarnings\" value=\"enabled\"/>\n" +
+ " <option key=\"org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields\" value=\"disabled\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation\" value=\"ignore\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.tasks\" value=\"warning\"/>\n" +
" <option key=\"org.eclipse.jdt.core.compiler.problem.typeParameterHiding\" value=\"warning\"/>\n" +
@@ -12699,13 +12702,18 @@
" ^^^^^^\n" +
"Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" +
"----------\n" +
- "2 problems (2 warnings)",
+ "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ " ^^^^^^\n" +
+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" +
+ "----------\n" +
+ "3 problems (3 warnings)",
true);
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=325342
// -err option - regression tests to check option nullAnnot
-// Null warnings because of annotations, null spec violations configured as errors
+// Null warnings because of annotations, null spec violations plus one specific problem configured as errors
public void test314_warn_options() {
this.runNegativeTest(
new String[] {
@@ -12730,7 +12738,7 @@
"\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\""
+ " -sourcepath \"" + OUTPUT_DIR + "\""
+ " -1.5"
- + " -err:+nullAnnot -warn:-null -proc:none -d \"" + OUTPUT_DIR + "\"",
+ + " -err:+nullAnnot -warn:-null -err:+nonnullNotRepeated -proc:none -d \"" + OUTPUT_DIR + "\"",
"",
"----------\n" +
"1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
@@ -12743,7 +12751,12 @@
" ^^^^^^\n" +
"Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" +
"----------\n" +
- "2 problems (2 errors)",
+ "3. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ " ^^^^^^\n" +
+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" +
+ "----------\n" +
+ "3 problems (3 errors)",
true);
}
@@ -13729,6 +13742,60 @@
" ^^^^^^\n" +
"Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" +
"----------\n" +
+ "3. WARNING in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ " ^^^^^^\n" +
+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" +
+ "----------\n" +
+ "3 problems (2 errors, 1 warning)",
+ false/*don't flush*/);
+}
+
+// Bug 375366 - ECJ ignores unusedParameterIncludeDocCommentReference unless enableJavadoc option is set
+// property file enables null annotation support, one optional warning disabled
+public void testBug375366d() throws IOException {
+ createOutputTestDirectory("regression/.settings");
+ Util.createFile(OUTPUT_DIR+"/.settings/org.eclipse.jdt.core.prefs",
+ "eclipse.preferences.version=1\n" +
+ "org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled\n" +
+ "org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=ignore\n");
+ this.runNegativeTest(
+ new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object foo(@Nullable Object o, @NonNull Object o2) {\n" +
+ " return this;\n" +
+ " }\n" +
+ "}\n" +
+ "class Y extends X {\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ "}\n",
+ "org/eclipse/jdt/annotation/NonNull.java",
+ NONNULL_ANNOTATION_CONTENT,
+ "org/eclipse/jdt/annotation/Nullable.java",
+ NULLABLE_ANNOTATION_CONTENT,
+ "org/eclipse/jdt/annotation/NonNullByDefault.java",
+ NONNULL_BY_DEFAULT_ANNOTATION_CONTENT
+ },
+ "\"" + OUTPUT_DIR + File.separator + "p" + File.separator + "X.java\""
+ + " -sourcepath \"" + OUTPUT_DIR + "\""
+ + " -1.5"
+ + " -properties " + OUTPUT_DIR + File.separator +".settings" + File.separator + "org.eclipse.jdt.core.prefs "
+ + " -d \"" + OUTPUT_DIR + "\"",
+ "",
+ "----------\n" +
+ "1. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ " ^^^^^^^^^^^^^^^^\n" +
+ "The return type is incompatible with the @NonNull return from X.foo(Object, Object)\n" +
+ "----------\n" +
+ "2. ERROR in ---OUTPUT_DIR_PLACEHOLDER---/p/X.java (at line 9)\n" +
+ " @Nullable Object foo(Object o, Object o2) { return null; }\n" +
+ " ^^^^^^\n" +
+ "Missing nullable annotation: inherited method from X declares this parameter as @Nullable\n" +
+ "----------\n" +
"2 problems (2 errors)",
false/*don't flush*/);
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index 249f0a0..f81c551 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -17,6 +17,9 @@
* bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
* bug 374605 - Unreasonable warning for enum-based switch statements
* bug 388281 - [compiler][null] inheritance of null annotations as an option
+ * bug 381443 - [compiler][null] Allow parameter widening from @NonNull to unannotated
+ * bug 331649 - [compiler][null] consider null annotations for fields
+ * bug 382789 - [compiler][null] warn when syntactically-nonnull expression is compared against null
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -739,6 +742,9 @@
expectedProblemAttributes.put("NonGenericConstructor", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NonGenericMethod", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("NonGenericType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+ expectedProblemAttributes.put("NonNullExpressionComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("NonNullMessageSendComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("NonNullSpecdFieldComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
@@ -751,6 +757,7 @@
expectedProblemAttributes.put("NotVisibleField", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleMethod", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("NotVisibleType", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
+ expectedProblemAttributes.put("NullableFieldReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -805,6 +812,8 @@
expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullExpression", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullSpecdField", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
@@ -897,6 +906,8 @@
expectedProblemAttributes.put("UninitializedBlankFinalFieldHintMissingDefault", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
expectedProblemAttributes.put("UninitializedLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("UninitializedLocalVariableHintMissingDefault", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
+ expectedProblemAttributes.put("UninitializedNonNullField", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
+ expectedProblemAttributes.put("UninitializedNonNullFieldHintMissingDefault", new ProblemAttributes(CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM));
expectedProblemAttributes.put("UnmatchedBracket", new ProblemAttributes(CategorizedProblem.CAT_SYNTAX));
expectedProblemAttributes.put("UnnecessaryArgumentCast", DEPRECATED);
expectedProblemAttributes.put("UnnecessaryCast", new ProblemAttributes(CategorizedProblem.CAT_UNNECESSARY_CODE));
@@ -906,6 +917,7 @@
expectedProblemAttributes.put("UnqualifiedFieldAccess", new ProblemAttributes(CategorizedProblem.CAT_CODE_STYLE));
expectedProblemAttributes.put("UnreachableCatch", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("UnresolvedVariable", new ProblemAttributes(CategorizedProblem.CAT_MEMBER));
+ expectedProblemAttributes.put("UnsafeElementTypeConversion", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("UnsafeGenericArrayForVarargs", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("UnsafeGenericCast", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
expectedProblemAttributes.put("UnsafeRawConstructorInvocation", new ProblemAttributes(CategorizedProblem.CAT_UNCHECKED_RAW));
@@ -1530,7 +1542,10 @@
expectedProblemAttributes.put("NonGenericConstructor", SKIP);
expectedProblemAttributes.put("NonGenericMethod", SKIP);
expectedProblemAttributes.put("NonGenericType", SKIP);
+ expectedProblemAttributes.put("NonNullExpressionComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
+ expectedProblemAttributes.put("NonNullSpecdFieldComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NonNullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
+ expectedProblemAttributes.put("NonNullMessageSendComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NonStaticAccessToStaticField", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
expectedProblemAttributes.put("NonStaticAccessToStaticMethod", new ProblemAttributes(JavaCore.COMPILER_PB_STATIC_ACCESS_RECEIVER));
expectedProblemAttributes.put("NonStaticContextForEnumMemberType", SKIP);
@@ -1542,6 +1557,7 @@
expectedProblemAttributes.put("NotVisibleField", SKIP);
expectedProblemAttributes.put("NotVisibleMethod", SKIP);
expectedProblemAttributes.put("NotVisibleType", SKIP);
+ expectedProblemAttributes.put("NullableFieldReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
expectedProblemAttributes.put("NullLocalVariableComparisonYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NullLocalVariableInstanceofYieldsFalse", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("NullLocalVariableReference", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_REFERENCE));
@@ -1558,7 +1574,7 @@
expectedProblemAttributes.put("PackageCollidesWithType", SKIP);
expectedProblemAttributes.put("PackageIsNotExpectedPackage", SKIP);
expectedProblemAttributes.put("ParameterAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_PARAMETER_ASSIGNMENT));
- expectedProblemAttributes.put("ParameterLackingNonNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
+ expectedProblemAttributes.put("ParameterLackingNonNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED));
expectedProblemAttributes.put("ParameterLackingNullableAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_NULL_SPECIFICATION_VIOLATION));
expectedProblemAttributes.put("ParameterMismatch", SKIP);
expectedProblemAttributes.put("ParameterizedConstructorArgumentTypeMismatch", SKIP);
@@ -1596,6 +1612,8 @@
expectedProblemAttributes.put("RedundantSpecificationOfTypeArguments", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_TYPE_ARGUMENTS));
expectedProblemAttributes.put("RedundantLocalVariableNullAssignment", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullAnnotation", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION));
+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullExpression", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
+ expectedProblemAttributes.put("RedundantNullCheckOnNonNullSpecdField", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNonNullMessageSend", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
expectedProblemAttributes.put("RedundantNullCheckOnNullLocalVariable", new ProblemAttributes(JavaCore.COMPILER_PB_REDUNDANT_NULL_CHECK));
@@ -1688,6 +1706,8 @@
expectedProblemAttributes.put("UninitializedBlankFinalFieldHintMissingDefault", SKIP);
expectedProblemAttributes.put("UninitializedLocalVariable", SKIP);
expectedProblemAttributes.put("UninitializedLocalVariableHintMissingDefault", SKIP);
+ expectedProblemAttributes.put("UninitializedNonNullField", SKIP);
+ expectedProblemAttributes.put("UninitializedNonNullFieldHintMissingDefault", SKIP);
expectedProblemAttributes.put("UnmatchedBracket", SKIP);
expectedProblemAttributes.put("UnnecessaryArgumentCast", SKIP);
expectedProblemAttributes.put("UnnecessaryCast", new ProblemAttributes(JavaCore.COMPILER_PB_UNNECESSARY_TYPE_CHECK));
@@ -1697,6 +1717,7 @@
expectedProblemAttributes.put("UnqualifiedFieldAccess", new ProblemAttributes(JavaCore.COMPILER_PB_UNQUALIFIED_FIELD_ACCESS));
expectedProblemAttributes.put("UnreachableCatch", SKIP);
expectedProblemAttributes.put("UnresolvedVariable", SKIP);
+ expectedProblemAttributes.put("UnsafeElementTypeConversion", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("UnsafeGenericArrayForVarargs", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("UnsafeGenericCast", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
expectedProblemAttributes.put("UnsafeRawConstructorInvocation", new ProblemAttributes(JavaCore.COMPILER_PB_UNCHECKED_TYPE_OPERATION));
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
index 13f6920..4c1edd5 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ForeachStatementTest.java
@@ -7,6 +7,8 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for
+ * bug 393719 - [compiler] inconsistent warnings on iteration variables
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -38,7 +40,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[] { "test000" };
+// TESTS_NAMES = new String[] { "test055" };
// TESTS_NUMBERS = new int[] { 50, 51, 52, 53 };
// TESTS_RANGE = new int[] { 34, 38 };
}
@@ -2815,7 +2817,7 @@
"2. WARNING in X.java (at line 10)\n" +
" for (Set<String> BUG : new Set[] { x, y }) {\n" +
" ^^^^^^^^^^^^^^^^^^\n" +
- "Type safety: The expression of type Set[] needs unchecked conversion to conform to Set<String>[]\n" +
+ "Type safety: Elements of type Set need unchecked conversion to conform to Set<String>\n" +
"----------\n" +
"3. WARNING in X.java (at line 14)\n" +
" Set [] set = new Set[] { x, y };\n" +
@@ -2825,7 +2827,7 @@
"4. WARNING in X.java (at line 15)\n" +
" for (Set<String> BUG : set) {\n" +
" ^^^\n" +
- "Type safety: The expression of type Set[] needs unchecked conversion to conform to Set<String>[]\n" +
+ "Type safety: Elements of type Set need unchecked conversion to conform to Set<String>\n" +
"----------\n" +
"5. ERROR in X.java (at line 20)\n" +
" Zork z;\n" +
@@ -2833,6 +2835,77 @@
"Zork cannot be resolved to a type\n" +
"----------\n");
}
+// https://bugs.eclipse.org/393719
+// like test054 but suppressing the warnings.
+public void test055() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.HashSet;\n" +
+ "import java.util.Set;\n" +
+ "public class X {\n" +
+ " void foo() {\n" +
+ " HashSet<String> x = new HashSet<String>();\n" +
+ " x.add(\"a\");\n" +
+ " HashSet<Integer> y = new HashSet<Integer>();\n" +
+ " y.add(1);\n" +
+ " @SuppressWarnings(\"unchecked\") Set<String> [] OK= new Set[] { x, y };\n" +
+ " for (@SuppressWarnings(\"unchecked\") Set<String> BUG : new Set[] { x, y }) {\n" +
+ " for (String str : BUG)\n" +
+ " System.out.println(str);\n" +
+ " }\n" +
+ " @SuppressWarnings({\"rawtypes\", \"unchecked\"}) Set [] set = new Set[] { x, y };\n" +
+ " for (@SuppressWarnings(\"unchecked\") Set<String> BUG : set) {\n" +
+ " for (String str : BUG)\n" +
+ " System.out.println(str);\n" +
+ " }\n" +
+ " }\n" +
+ " Zork z;\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 20)\n" +
+ " Zork z;\n" +
+ " ^^^^\n" +
+ "Zork cannot be resolved to a type\n" +
+ "----------\n");
+}
+// https://bugs.eclipse.org/393719
+// "unchecked" warning against the collection (raw Iterable)
+public void test056() throws Exception {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "import java.util.List;\n" +
+ "public class X {\n" +
+ " void testRawType(@SuppressWarnings(\"rawtypes\") List<List> lists) {\n" +
+ " List<String> stringList = lists.get(0); // (1)\n" +
+ " for (List<String> strings : lists) // (2)\n" +
+ " stringList = strings;\n" +
+ " for (@SuppressWarnings(\"unchecked\") List<String> strings : lists) // no warning\n" +
+ " stringList = strings;\n" +
+ " System.out.println(stringList.get(0));\n" +
+ " }\n" +
+ " Zork z;\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. WARNING in X.java (at line 4)\n" +
+ " List<String> stringList = lists.get(0); // (1)\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Type safety: The expression of type List needs unchecked conversion to conform to List<String>\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 5)\n" +
+ " for (List<String> strings : lists) // (2)\n" +
+ " ^^^^^\n" +
+ "Type safety: Elements of type List need unchecked conversion to conform to List<String>\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 11)\n" +
+ " Zork z;\n" +
+ " ^^^^\n" +
+ "Zork cannot be resolved to a type\n" +
+ "----------\n");
+}
public static Class testClass() {
return ForeachStatementTest.class;
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
index ffc6b67..8721046 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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,7 +7,9 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
- * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+ * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
+ * bug 282152 - [1.5][compiler] Generics code rejected by Eclipse but accepted by javac
+ * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -28,7 +30,7 @@
// Static initializer to specify tests subset using TESTS_* static variables
// All specified tests which does not belong to the class are skipped...
static {
-// TESTS_NAMES = new String[] { "test347426" };
+// TESTS_NAMES = new String[] { "testBug395002_combined" };
// TESTS_NAMES = new String[] { "test1464" };
// TESTS_NUMBERS = new int[] { 1465 };
// TESTS_RANGE = new int[] { 1097, -1 };
@@ -2649,4 +2651,170 @@
"----------\n",
null, true, customOptions);
}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// version with intermediate assignment, always worked
+public void testBug395002_1() {
+ runConformTest(new String[] {
+ "Client.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "public class Client {\n" +
+ " <A extends SelfBound<?,A>> void foo3(A arg3) {\n" +
+ " SelfBound<?, A> var3 = arg3;\n" +
+ " SelfBound<? extends SelfBound<?, A>, ?> var4 = var3;\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// version with direct assignment to local
+public void testBug395002_2() {
+ runConformTest(new String[] {
+ "Client.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "public class Client {\n" +
+ " <A extends SelfBound<?,A>> void foo2(A arg2) {\n" +
+ " SelfBound<? extends SelfBound<?, A>, ?> var2 = arg2;\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// version with direct assignment to field
+public void testBug395002_3() {
+ runConformTest(new String[] {
+ "Client.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "public class Client<A extends SelfBound<?,A>> {\n" +
+ " SelfBound<? extends SelfBound<?, A>, ?> field2;\n" +
+ " void foo2(A arg2) {\n" +
+ " field2 = arg2;\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// version with argument passing
+public void testBug395002_4() {
+ runConformTest(new String[] {
+ "Client.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "public class Client<A extends SelfBound<?,A>> {\n" +
+ " void bar(SelfBound<? extends SelfBound<?, A>, ?> argBar) {};\n" +
+ " void foo2(A arg2) {\n" +
+ " bar(arg2);\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// original problem with invocation of generic type
+public void testBug395002_full() {
+ runConformTest(new String[] {
+ "Bug.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "class Test<X extends SelfBound<? extends Y, ?>, Y> {\n" +
+ "}\n" +
+ "public class Bug<A extends SelfBound<?, A>> {\n" +
+ " public Bug() {\n" +
+ " new Test<A, SelfBound<?, A>>();\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
+// combined version with direct assignment to local + original problem w/ invocation of generic type
+public void testBug395002_combined() {
+ runConformTest(new String[] {
+ "Client.java",
+ "interface SelfBound<S extends SelfBound<S, T>, T> {\n" +
+ "}\n" +
+ "class Test<X extends SelfBound<? extends Y, ?>, Y> {\n" +
+ "}\n" +
+ "public class Client {\n" +
+ " <A extends SelfBound<?,A>> void foo2(A arg2) {\n" +
+ " Object o = new Test<A, SelfBound<?, A>>();\n" +
+ " SelfBound<? extends SelfBound<?, A>, ?> var2 = arg2;\n" +
+ " }\n" +
+ "}\n"
+ });
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397888
+public void test397888a() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedTypeParameter, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedParameter, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
+ CompilerOptions.ENABLED);
+
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "/***\n" +
+ " * @param <T>\n" +
+ " */\n" +
+ "public class X <T> {\n"+
+ "/***\n" +
+ " * @param <S>\n" +
+ " */\n" +
+ " public <S> void ph(int i) {\n"+
+ " }\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " public <S> void ph(int i) {\n" +
+ " ^\n" +
+ "The value of the parameter i is not used\n" +
+ "----------\n",
+ null, true, customOptions);
+}
+
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397888
+public void test397888b() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedTypeParameter, CompilerOptions.ERROR);
+ customOptions.put(CompilerOptions.OPTION_ReportUnusedParameterIncludeDocCommentReference,
+ CompilerOptions.DISABLED);
+
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "/***\n" +
+ " * @param <T>\n" +
+ " */\n" +
+ "public class X <T> {\n"+
+ "/***\n" +
+ " * @param <S>\n" +
+ " */\n" +
+ "public <S> void ph() {\n"+
+ "}\n"+
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " public class X <T> {\n" +
+ " ^\n" +
+ "Unused type parameter T\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " public <S> void ph() {\n" +
+ " ^\n" +
+ "Unused type parameter S\n" +
+ "----------\n",
+ null, true, customOptions);
+}
}
\ No newline at end of file
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 c904e2a..294e913 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
@@ -53,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[] { "testBug388281_09" };
+// TESTS_NAMES = new String[] { "test_nullable_field_10e" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -127,6 +127,17 @@
void runConformTestWithLibs(String[] testFiles, Map customOptions, String expectedCompilerLog) {
runConformTestWithLibs(false /* flush output directory */, testFiles, customOptions, expectedCompilerLog);
}
+void runConformTestWithLibs(String[] testFiles, Map customOptions, String expectedCompilerLog, String expectedOutput) {
+ runConformTest(
+ false, /* flush output directory */
+ testFiles,
+ this.LIBS,
+ customOptions,
+ expectedCompilerLog,
+ expectedOutput,
+ "",/* expected error */
+ JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
+}
void runConformTestWithLibs(boolean shouldFlushOutputDirectory, String[] testFiles, Map customOptions, String expectedCompilerLog) {
runConformTest(
shouldFlushOutputDirectory,
@@ -1061,7 +1072,12 @@
},
options,
"----------\n" +
- "1. ERROR in XSub.java (at line 3)\n" +
+ "1. WARNING in XSub.java (at line 3)\n" +
+ " public void printObject(Object o) { super.printObject(o); }\n" +
+ " ^^^^^^\n" +
+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in XSub.java (at line 3)\n" +
" public void printObject(Object o) { super.printObject(o); }\n" +
" ^\n" +
"Null type safety: The expression of type Object needs unchecked conversion to conform to \'@NonNull Object\'\n" +
@@ -1197,6 +1213,7 @@
public void test_parameter_specification_inheritance_013() {
Map customOptions = getCompilerOptions();
customOptions.put(JavaCore.COMPILER_PB_NULL_UNCHECKED_CONVERSION, JavaCore.ERROR);
+ customOptions.put(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED, JavaCore.IGNORE);
runNegativeTestWithLibs(
new String[] {
"p1/X.java",
@@ -1334,6 +1351,95 @@
null/*vmArgs*/);
}
+// a method relaxes the parameter null specification from @NonNull to un-annotated
+// see https://bugs.eclipse.org/381443
+// issue configured as error
+public void test_parameter_specification_inheritance_016() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED, JavaCore.ERROR);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " void foo(@NonNull String s) { System.out.println(s); }\n" +
+ "}\n",
+ "XSub.java",
+ "public class XSub extends X {\n" +
+ " @Override\n" +
+ " public void foo(String s) { if (s != null) super.foo(s); }\n" +
+ " void bar() { foo(null); }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in XSub.java (at line 3)\n" +
+ " public void foo(String s) { if (s != null) super.foo(s); }\n" +
+ " ^^^^^^\n" +
+ "Missing non-null annotation: inherited method from X declares this parameter as @NonNull\n" +
+ "----------\n");
+}
+
+// a class inherits two methods with different spec: one non-null param & one unannotated param
+// widening reported as warning by default
+// see https://bugs.eclipse.org/381443
+public void test_parameter_specification_inheritance_017() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(String s) { System.out.println(s); }\n" +
+ "}\n",
+ "IX.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public interface IX {\n" +
+ " void foo(@NonNull String s);\n" +
+ "}\n",
+ "XSub.java",
+ "public class XSub extends X implements IX {\n" +
+ " void bar() { foo(null); }\n" +
+ " static void zork(XSub sub) {\n" +
+ " sub.foo(null);\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. WARNING in XSub.java (at line 1)\n" +
+ " public class XSub extends X implements IX {\n" +
+ " ^^^^\n" +
+ "Missing non-null annotation: inherited method from IX declares this parameter as @NonNull\n" +
+ "----------\n");
+}
+
+// a class inherits two methods with different spec: one non-null param & one unannotated param
+// opt to accept this widening
+// see https://bugs.eclipse.org/381443
+public void test_parameter_specification_inheritance_018() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_NONNULL_PARAMETER_ANNOTATION_DROPPED, JavaCore.IGNORE);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " public void foo(String s) { System.out.println(s); }\n" +
+ "}\n",
+ "IX.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public interface IX {\n" +
+ " void foo(@NonNull String s);\n" +
+ "}\n",
+ "XSub.java",
+ "public class XSub extends X implements IX {\n" +
+ " void bar() { foo(null); }\n" +
+ " static void zork(XSub sub) {\n" +
+ " sub.foo(null);\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+
// a nullable return value is dereferenced without a check
public void test_nullable_return_001() {
runNegativeTestWithLibs(
@@ -1538,7 +1644,12 @@
"1. ERROR in X.java (at line 7)\n" +
" if (getObject() == null)\n" +
" ^^^^^^^^^^^\n" +
- "Redundant null check: The method getObject() cannot return null\n" +
+ "Null comparison always yields false: The method getObject() cannot return null\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 8)\n" +
+ " throw new RuntimeException();\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
"----------\n");
}
// a result from a nonnull method is directly checked for null (from local): redundant
@@ -2689,6 +2800,87 @@
"----------\n");
}
+// default nullness applied to fields, class-level:
+public void test_default_nullness_016() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " Object foo;\n" +
+ " void doFoo() {\n" +
+ " foo = null;\n" +
+ " }\n" +
+ " class Inner {\n" +
+ " Object iFoo;\n" +
+ " void diFoo(@Nullable Object arg) {\n" +
+ " iFoo = arg;\n" +
+ " }\n" +
+ " }\n" +
+ "}\n",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " Object foo;\n" +
+ " ^^^\n" +
+ "The @NonNull field foo may not have been initialized\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " foo = null;\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 9)\n" +
+ " Object iFoo;\n" +
+ " ^^^^\n" +
+ "The @NonNull field iFoo may not have been initialized\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 11)\n" +
+ " iFoo = arg;\n" +
+ " ^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is specified as @Nullable\n" +
+ "----------\n");
+}
+
+// default nullness applied to fields, method level applied to local class + redundant annotation
+public void test_default_nullness_017() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_UNUSED_PRIVATE_MEMBER, JavaCore.IGNORE);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNullByDefault\n" +
+ " Object doFoo() {\n" +
+ " class Local {\n" +
+ " Object foo;\n" +
+ " @NonNull Object goo;\n" +
+ " };" +
+ " return new Local();\n" +
+ " }\n" +
+ "}\n",
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " Object foo;\n" +
+ " ^^^\n" +
+ "The @NonNull field foo may not have been initialized\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 7)\n" +
+ " @NonNull Object goo;\n" +
+ " ^^^^^^^^^^^^^^^\n" +
+ "The nullness annotation is redundant with a default that applies to this location\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " @NonNull Object goo;\n" +
+ " ^^^\n" +
+ "The @NonNull field goo may not have been initialized\n" +
+ "----------\n");
+}
+
// redundant default annotations - class vs. inner class
public void test_redundant_annotation_01() {
Map customOptions = getCompilerOptions();
@@ -3008,6 +3200,27 @@
"----------\n");
}
+// contradictory null annotations on a field
+public void test_contradictory_annotations_02() {
+ Map customOptions = getCompilerOptions();
+ runNegativeTestWithLibs(
+ new String[] {
+ "p2/Y.java",
+ "package p2;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Y {\n" +
+ " @NonNull @Nullable Object o;\n" +
+ "}\n"
+ },
+ customOptions,
+ "----------\n" +
+ "1. ERROR in p2\\Y.java (at line 4)\n" +
+ " @NonNull @Nullable Object o;\n" +
+ " ^^^^^^^^^\n" +
+ "Contradictory null specification; only one of @NonNull and @Nullable can be specified at any location\n" +
+ "----------\n");
+}
+
// a nonnull variable is dereferenced in a loop
public void test_nonnull_var_in_constrol_structure_1() {
Map customOptions = getCompilerOptions();
@@ -3241,6 +3454,7 @@
"Null comparison always yields false: The variable enclosingSourceType cannot be null at this location\n" +
"----------\n");
}
+
// Bug 370930 - NonNull annotation not considered for enhanced for loops
public void test_message_send_in_control_structure_02() {
runNegativeTestWithLibs(
@@ -3515,6 +3729,1339 @@
"Dead code\n" +
"----------\n");
}
+// access to a non-null field
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_1() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o = new Object();\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// a non-null field is not properly initialized
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o;\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " @NonNull Object o;\n" +
+ " ^\n" +
+ "The @NonNull field o may not have been initialized\n" +
+ "----------\n");
+}
+
+// a non-null field is not properly initialized - explicit constructor
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2a() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o;\n" +
+ " X (boolean b) { // only potentially initialized\n" +
+ " if (b)\n" +
+ " o = this;\n" +
+ " }\n" +
+ " X (@NonNull Object other) {\n" + // no problem
+ " o = other;\n" +
+ " }\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " X (boolean b) { // only potentially initialized\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "The @NonNull field o may not have been initialized\n" +
+ "----------\n");
+}
+
+// a non-null field is not properly initialized - explicit constructor - incomplete switch
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2b() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "enum Color { BLACK, GREEN }\n" +
+ "public class X {\n" +
+ " @NonNull Object o;\n" +
+ " X (Color c) { // only potentially initialized\n" +
+ " switch (c) {\n" +
+ " case BLACK: o = this; break;\n" +
+ " case GREEN: o = new Object(); break;\n" +
+ " }\n" +
+ " }\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " X (Color c) { // only potentially initialized\n" +
+ " ^^^^^^^^^^^\n" +
+ "The @NonNull field o may not have been initialized. Note that a problem regarding missing \'default:\' on \'switch\' has been suppressed, which is perhaps related to this problem\n" +
+ "----------\n");
+}
+
+// a non-null static field is not properly initialized
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2c() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " static @NonNull Object o;\n" +
+ " static {\n" +
+ " if (new Object().hashCode() == 42)\n" +
+ " o = new Object();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " static @NonNull Object o;\n" +
+ " ^\n" +
+ "The @NonNull field o may not have been initialized\n" +
+ "----------\n");
+}
+
+// a non-null static field is properly initialized
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2d() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " static @NonNull Object o;\n" +
+ " static {\n" +
+ " o = new Object();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// a non-null field is properly initialized - using this.f reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_2e() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object f;\n" +
+ " {\n" +
+ " this.f = new Object();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// a non-null field is initialized to null
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_3() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o = null;\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " @NonNull Object o = null;\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n");
+}
+// a non-null field is assigned to null
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_4() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o = new Object();\n" +
+ " void breakIt1() {\n" +
+ " o = null;\n" +
+ " }\n" +
+ " void breakIt2() {\n" +
+ " this.o = null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " o = null;\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " this.o = null;\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n");
+}
+// a non-null field is checked for null
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_5() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o = new Object();\n" +
+ " boolean checkIt1() {\n" +
+ " return o == null;\n" +
+ " }\n" +
+ " boolean checkIt() {\n" +
+ " return this.o != null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return o == null;\n" +
+ " ^\n" +
+ "Null comparison always yields false: The field o is declared as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " return this.o != null;\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n");
+}
+
+// a non-null field is checked for null twice - method call inbetween
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_6() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Object o = new Object();\n" +
+ " boolean checkIt1() {\n" +
+ " if (o != null)\n" +
+ " System.out.print(\"not null\");\n" +
+ " System.out.print(\"continue\");\n" +
+ " return this.o == null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " if (o != null)\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " return this.o == null;\n" +
+ " ^\n" +
+ "Null comparison always yields false: The field o is declared as @NonNull\n" +
+ "----------\n");
+}
+
+// a non-null field is accessed via a qualified name reference - static field
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_7() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class Objects {\n" +
+ " static @NonNull Object o = new Object();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " @NonNull Object getIt1() {\n" +
+ " if (Objects.o != null) // redundant\n" +
+ " System.out.print(\"not null\");\n" +
+ " System.out.print(\"continue\");\n" +
+ " return Objects.o;\n" +
+ " }\n" +
+ " @NonNull Object getIt2() {\n" +
+ " if (null != Objects.o) // redundant\n" +
+ " System.out.print(\"not null\");\n" +
+ " System.out.print(\"continue\");\n" +
+ " return Objects.o;\n" +
+ " }\n" +
+ " String getIt3() {\n" +
+ " return Objects.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " if (Objects.o != null) // redundant\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 13)\n" +
+ " if (null != Objects.o) // redundant\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n");
+}
+
+// a non-null field is accessed via a qualified name reference - instance field
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_8() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class Objects {\n" +
+ " @NonNull Object o = new Object();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " @NonNull Object getIt1(@NonNull Objects objs) {\n" +
+ " if (objs.o == null) // always false\n" +
+ " System.out.print(\"not null\");\n" +
+ " System.out.print(\"continue\");\n" +
+ " return objs.o;\n" +
+ " }\n" +
+ " String getIt2(@NonNull Objects objs) {\n" +
+ " return objs.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " if (objs.o == null) // always false\n" +
+ " ^\n" +
+ "Null comparison always yields false: The field o is declared as @NonNull\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 8)\n" +
+ " System.out.print(\"not null\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n");
+}
+
+// a non-null field is accessed via an indirect field reference - instance field
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_9() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class Objects {\n" +
+ " @NonNull Object o = new Object();\n" +
+ "}\n" +
+ "public class X {\n" +
+ " Objects objs = new Objects();\n" +
+ " @NonNull Object getIt1() {\n" +
+ " if (this.objs.o != null) // redundant\n" +
+ " System.out.print(\"not null\");\n" +
+ " System.out.print(\"continue\");\n" +
+ " if (getObjs().o != null) // redundant\n" +
+ " System.out.print(\"not null\");\n" +
+ " return this.objs.o;\n" +
+ " }\n" +
+ " Objects getObjs() { return this.objs; }\n" +
+ " String getIt2() {\n" +
+ " return this.objs.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " if (this.objs.o != null) // redundant\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 11)\n" +
+ " if (getObjs().o != null) // redundant\n" +
+ " ^\n" +
+ "Redundant null check: The field o is declared as @NonNull\n" +
+ "----------\n");
+}
+
+// trying to assign null to a nonnull field via a single / a qualified name reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_11() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class Objects {\n" +
+ " @NonNull Object o = new Object();\n" +
+ " void test0(@Nullable Object x) {\n" +
+ " o = x;\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " void test(@NonNull Objects objs) {\n" +
+ " objs.o = null;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " o = x;\n" +
+ " ^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is specified as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 10)\n" +
+ " objs.o = null;\n" +
+ " ^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is null\n" +
+ "----------\n");
+}
+
+// @NonNull is applied to a field with primitive type
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_12() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull int o = 1;\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " @NonNull int o = 1;\n" +
+ " ^^^^^^^^^^^^\n" +
+ "The nullness annotation @NonNull is not applicable for the primitive type int\n" +
+ "----------\n");
+}
+
+// A final field is initialized to non-null, treat as effectively @NonNull
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void _test_nonnull_field_13() {
+ // withdrawn as of https://bugs.eclipse.org/331649#c75
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " final String s1 = \"\";\n" +
+ " @NonNull String s2;\n" +
+ " X() {\n" +
+ " s2 = s1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// A field in a different CU is implicitly @NonNull (by type default) - that class is read from binary
+// Assignment to other @NonNull field should not raise a warning
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_14() {
+ runConformTestWithLibs(
+ new String[] {
+ "p1/X.java",
+ "package p1;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "@NonNullByDefault\n" +
+ "public class X {\n" +
+ " public String s1 = \"\";\n" +
+ "}\n",
+ },
+ null /*customOptions*/,
+ "");
+ runConformTestWithLibs(
+ new String[] {
+ "p2/Y.java",
+ "package p2;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import p1.X;\n" +
+ "public class Y {\n" +
+ " @NonNull String s2 = \"\";\n" +
+ " void foo(X other) {\n" +
+ " s2 = other.s1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// A field in a different CU is implicitly @NonNull (by package default) - that class is read from binary
+// Assignment to other @NonNull field should not raise a warning
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nonnull_field_14b() {
+ runConformTestWithLibs(
+ new String[] {
+ "p1/package-info.java",
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "package p1;\n",
+ "p1/X.java",
+ "package p1;\n" +
+ "public class X {\n" +
+ " public String s1 = \"\";\n" +
+ "}\n",
+ },
+ null /*customOptions*/,
+ "");
+ runConformTestWithLibs(
+ new String[] {
+ "p2/Y.java",
+ "package p2;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "import p1.X;\n" +
+ "public class Y {\n" +
+ " @NonNull String s2 = \"\";\n" +
+ " void foo(X other) {\n" +
+ " s2 = other.s1;\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// access to a nullable field - field reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_1() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " public String oString() {\n" +
+ " return this.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return this.o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+// access to a nullable field - single name reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_2() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " public String oString() {\n" +
+ " return o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+// access to a nullable field - qualified name reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_3() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " @Nullable X other;\n" +
+ " public String oString() {\n" +
+ " return other.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " return other.o.toString();\n" +
+ " ^^^^^\n" +
+ "Potential null pointer access: The field other is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " return other.o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+// access to a nullable field - qualified name reference - multiple segments
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_3m() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " @Nullable X other;\n" +
+ " public String oString() {\n" +
+ " return other.other.o.toString();\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " return other.other.o.toString();\n" +
+ " ^^^^^\n" +
+ "Potential null pointer access: The field other is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " return other.other.o.toString();\n" +
+ " ^^^^^\n" +
+ "Potential null pointer access: The field other is declared as @Nullable\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 6)\n" +
+ " return other.other.o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+// access to a nullable field - dereference after check
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_4() {
+ // currently no flow analysis for fields is implemented,
+ // but the direct sequence of null-check + dereference is optionally supported as a special case
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " public String oString() {\n" +
+ " if (this.o != null)\n" +
+ " return this.o.toString();\n" + // silent after check
+ " if (o != null)\n" +
+ " return o.toString();\n" + // silent after check
+ " return \"\";\n" +
+ " }\n" +
+ " public String oString2() {\n" +
+ " String local = o.toString();\n" +
+ " if (this.o != null) {\n" +
+ " this.toString();\n" + // method call wipes null info
+ " return this.o.toString(); // warn here\n" +
+ " }\n" +
+ " return \"\";\n" +
+ " }\n" +
+ "}\n"
+ },
+ options /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " String local = o.toString();\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 15)\n" +
+ " return this.o.toString(); // warn here\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// access to a nullable field - intermediate component in a QNR
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_5() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @NonNull Y y = new Y();\n" +
+ " public String oString() {\n" +
+ " return y.z.o.toString(); // pot.NPE on z\n" +
+ " }\n" +
+ "}\n",
+ "Y.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Y {\n" +
+ " @Nullable Z z = new Z();\n" +
+ "}\n",
+ "Z.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Z {\n" +
+ " @NonNull Object o = new Object();\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return y.z.o.toString(); // pot.NPE on z\n" +
+ " ^\n" +
+ "Potential null pointer access: The field z is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// access to a nullable field - intermediate component in a QNR - inverse of test_nullable_field_5
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_6() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Y y = new Y();\n" +
+ " public String oString() {\n" +
+ " return y.z.o.toString(); // pot.NPE on y and o\n" +
+ " }\n" +
+ "}\n",
+ "Y.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Y {\n" +
+ " @NonNull Z z = new Z();\n" +
+ "}\n",
+ "Z.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Z {\n" +
+ " Object dummy;\n" + // ensure different interal fieldId
+ " @Nullable Object o = new Object();\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return y.z.o.toString(); // pot.NPE on y and o\n" +
+ " ^\n" +
+ "Potential null pointer access: The field y is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 5)\n" +
+ " return y.z.o.toString(); // pot.NPE on y and o\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// access to a nullable field - intermediate component in a double field reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_7() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Y y = new Y();\n" +
+ " public String oString() {\n" +
+ " return this.y.o.toString(); // pot.NPE on y and o\n" +
+ " }\n" +
+ "}\n",
+ "Y.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class Y {\n" +
+ " @Nullable Object o = new Object();\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " return this.y.o.toString(); // pot.NPE on y and o\n" +
+ " ^\n" +
+ "Potential null pointer access: The field y is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 5)\n" +
+ " return this.y.o.toString(); // pot.NPE on y and o\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// static access to a nullable field - qualified name reference
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_8() {
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable static final Object o = null;\n" +
+ " public void foo() {\n" +
+ " if (X.o == null){\n" +
+ " System.out.println(X.o);\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "");
+}
+
+// illegal use of @Nullable for a field of primitive type
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_9() {
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable int i;\n" +
+ "}\n"
+ },
+ null /*customOptions*/,
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " @Nullable int i;\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "The nullness annotation @Nullable is not applicable for the primitive type int\n" +
+ "----------\n");
+}
+
+// protected access to nullable fields - different kinds of references
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10a() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1, o2, o3;\n" +
+ " @NonNull X x = new X();\n" +
+ " public void foo(X other) {\n" +
+ " if (other.o1 != null){\n" + // qualified reference -> block
+ " System.out.println(other.o1.toString());\n" +
+ " }\n" +
+ " if (this.o2 != null)\n" + // field reference -> statement
+ " System.out.println(o2.toString());\n" +
+ " if (this.o2 != null)\n" + // identical field references
+ " System.out.println(this.o2.toString());\n" +
+ " System.out.println (null != o3 ? o3.toString() : \"nothing\");\n" + // ternary
+ " if (this.x.o1 != null)\n" + // nested field reference ...
+ " System.out.println(x.o1.toString());\n" + // ... equiv qualified name reference
+ " if (x.o1 != null)\n" + // qualified name reference ...
+ " System.out.println(this.x.o1.toString());\n" +// ... equiv nested field reference
+ " if (this.x.o1 != null)\n" + // identical nested field references
+ " System.out.println(this.x.o1.toString());\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+
+// protected access to nullable fields - different kinds of references - option not enabled
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10b() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.DISABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1, o2, o3;\n" +
+ " @NonNull X x = new X();\n" +
+ " public void foo(X other) {\n" +
+ " if (other.o1 != null){\n" + // qualified reference -> block
+ " System.out.println(other.o1.toString());\n" +
+ " }\n" +
+ " if (this.o2 != null)\n" + // field reference -> statement
+ " System.out.println(o2.toString());\n" +
+ " if (this.o2 != null)\n" + // identical field references
+ " System.out.println(this.o2.toString());\n" +
+ " System.out.println (null != o3 ? o3.toString() : \"nothing\");\n" + // ternary
+ " if (this.x.o1 != null)\n" + // nested field reference ...
+ " System.out.println(x.o1.toString());\n" + // ... equiv qualified name reference
+ " if (x.o1 != null)\n" + // qualified name reference ...
+ " System.out.println(this.x.o1.toString());\n" +// ... equiv nested field reference
+ " if (this.x.o1 != null)\n" + // identical nested field references
+ " System.out.println(this.x.o1.toString());\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " System.out.println(other.o1.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 10)\n" +
+ " System.out.println(o2.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 12)\n" +
+ " System.out.println(this.o2.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 13)\n" +
+ " System.out.println (null != o3 ? o3.toString() : \"nothing\");\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o3 is declared as @Nullable\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 15)\n" +
+ " System.out.println(x.o1.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n" +
+ "6. ERROR in X.java (at line 17)\n" +
+ " System.out.println(this.x.o1.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n" +
+ "7. ERROR in X.java (at line 19)\n" +
+ " System.out.println(this.x.o1.toString());\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// protected access to nullable fields - different boolean operators
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10c() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1, o2, o3;\n" +
+ " public void foo(X other) {\n" +
+ " if (o1 != null && o2 != null & o3 != null) \n" + // conjunction: OK
+ " System.out.println(o2.toString());\n" +
+ " if (o1 != null || o2 != null || o3 != null) \n" +
+ " System.out.println(o2.toString()); // warn here: disjunktion is no protection\n" +
+ " if (!(o1 != null)) \n" +
+ " System.out.println(o1.toString()); // warn here: negation is no protection\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 8)\n" +
+ " System.out.println(o2.toString()); // warn here: disjunktion is no protection\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 10)\n" +
+ " System.out.println(o1.toString()); // warn here: negation is no protection\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// protected access to nullable fields - assignment as expression
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10d() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1;\n" +
+ " public void foo(@NonNull X other, X last) {\n" +
+ " o1 = other;\n" + // reference test case: assignment as statement
+ " if (o1 == last) \n" + // no expiry
+ " System.out.println(o1.toString());\n" +
+ " if ((o1 = other) == last) \n" + // no expiry
+ " System.out.println(o1.toString());\n" +
+ " if ((o1 = other) == last) {\n" +
+ " o1 = null;\n" + // expire here
+ " System.out.println(o1.toString()); // info is expired\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 12)\n" +
+ " System.out.println(o1.toString()); // info is expired\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// protected access to nullable fields - distinguish local and field
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10e() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class Y {\n" +
+ " @Nullable Object o2;\n" +
+ " void bar(Object o2) {\n" +
+ " if (o2 != null)\n" +
+ " System.out.println(this.o2.toString()); // field access is not protected\n" +
+ " }\n" +
+ "}\n" +
+ "public class X {\n" +
+ " @NonNull Y o1 = new Y();\n" +
+ " public void foo() {\n" +
+ " Y o1 = new Y();\n" +
+ " if (o1.o2 != null) \n" + // check via local
+ " System.out.println(this.o1.o2.toString()); // field access via other field not protected\n" +
+ " if (this.o1.o2 != null) \n" + // check via field
+ " System.out.println(o1.o2.toString()); // field access via local not protected\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. WARNING in X.java (at line 4)\n" +
+ " void bar(Object o2) {\n" +
+ " ^^\n" +
+ "The parameter o2 is hiding a field from type Y\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 6)\n" +
+ " System.out.println(this.o2.toString()); // field access is not protected\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "3. WARNING in X.java (at line 12)\n" +
+ " Y o1 = new Y();\n" +
+ " ^^\n" +
+ "The local variable o1 is hiding a field from type X\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 14)\n" +
+ " System.out.println(this.o1.o2.toString()); // field access via other field not protected\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "5. ERROR in X.java (at line 16)\n" +
+ " System.out.println(o1.o2.toString()); // field access via local not protected\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// protected access to nullable fields - duplicate comparison
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_10f() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1;\n" +
+ " public void foo(X other) {\n" +
+ " if (o1 != null && o1 != null) // second term is redundant\n" +
+ " System.out.println(o1.toString());\n" +
+ " if (o1 != null)\n" +
+ " if (o1 != null) // this if is redundant\n" +
+ " System.out.println(o1.toString());\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " if (o1 != null && o1 != null) // second term is redundant\n" +
+ " ^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " if (o1 != null) // this if is redundant\n" +
+ " ^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n");
+}
+
+// combined test from comment 20 in https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_11() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class X {\n" +
+ " @Nullable Object o;\n" +
+ " public @NonNull Object foo(X x) {\n" +
+ " return x.o != null ? x.o : new Object();\n" +
+ " }\n" +
+ " public void goo(X x) {\n" +
+ " if (x.o != null) {\n" +
+ " x.o.toString();\n" +
+ " }\n" +
+ " }\n" +
+ " public void boo(X x) {\n" +
+ " if (x.o instanceof String) {\n" +
+ " x.o.toString();\n" +
+ " }\n" +
+ " }\n" +
+ " public void zoo(X x) {\n" +
+ " x.o = new Object();\n" +
+ " System.out.println(\"hashCode of new Object = \" + x.o.hashCode());\n" +
+ " }\n" +
+ " public void doo(X x) {\n" +
+ " x.o = foo(x); // foo is guaranteed to return @NonNull Object.\n" +
+ " System.out.println(\"hashCode of new Object = \" + x.o.hashCode());\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+
+// combined test from comment 20 in https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+// - version with 'this' field references
+public void test_nullable_field_11a() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "class X {\n" +
+ " @Nullable Object o;\n" +
+ " public @NonNull Object foo() {\n" +
+ " return o != null ? o : new Object();\n" +
+ " }\n" +
+ " public void goo() {\n" +
+ " if (o != null) {\n" +
+ " o.toString();\n" +
+ " }\n" +
+ " }\n" +
+ " public void boo() {\n" +
+ " if (o instanceof String) {\n" +
+ " o.toString();\n" +
+ " }\n" +
+ " }\n" +
+ " public void zoo() {\n" +
+ " o = new Object();\n" +
+ " System.out.println(\"hashCode of new Object = \" + o.hashCode());\n" +
+ " }\n" +
+ " public void doo() {\n" +
+ " o = foo(); // foo is guaranteed to return @NonNull Object.\n" +
+ " System.out.println(\"hashCode of new Object = \" + o.hashCode());\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+
+// protected access to nullable field - expiration of information
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_12() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1, o2, o3, o4;\n" +
+ " public void foo(X other) {\n" +
+ " if (other.o1 != null){\n" +
+ " System.out.println(goo()+other.o1.toString()); // warn here: expired by call to goo()\n" +
+ " }\n" +
+ " Object x = o2 != null ? o2 : o1;\n" +
+ " System.out.println(o2.toString()); // warn here: not protected\n" +
+ " if (o3 != null) /*nop*/;\n" +
+ " System.out.println(o3.toString()); // warn here: expired by empty statement\n" +
+ " if (o4 != null && hoo())\n" +
+ " System.out.println(o4.toString()); // warn here: expired by call to hoo()\n" +
+ " }\n" +
+ " String goo() { return \"\"; }\n" +
+ " boolean hoo() { return false; }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " System.out.println(goo()+other.o1.toString()); // warn here: expired by call to goo()\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o1 is declared as @Nullable\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 9)\n" +
+ " System.out.println(o2.toString()); // warn here: not protected\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o2 is declared as @Nullable\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 11)\n" +
+ " System.out.println(o3.toString()); // warn here: expired by empty statement\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o3 is declared as @Nullable\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 13)\n" +
+ " System.out.println(o4.toString()); // warn here: expired by call to hoo()\n" +
+ " ^^\n" +
+ "Potential null pointer access: The field o4 is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// example from comment 47
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_13() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o1;\n" +
+ " @NonNull Object o2 = new Object();\n" +
+ " public void foo(X other) {\n" +
+ " if (other.o1 == null){\n" +
+ " this.o2 = other.o1; // warn here: assign @Nullable to @NonNull\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " this.o2 = other.o1; // warn here: assign @Nullable to @NonNull\n" +
+ " ^^^^^^^^\n" +
+ "Null type mismatch: required \'@NonNull Object\' but the provided value is specified as @Nullable\n" +
+ "----------\n");
+}
+
+// access to a nullable field - protected by check against a @NonNull value
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_14() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runConformTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " public String oString(@NonNull Object a) {\n" +
+ " if (this.o == a)\n" +
+ " return this.o.toString();\n" + // silent after check
+ " return \"\";\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "");
+}
+
+// access to a nullable field - not protected by negative check against a @NonNull value
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=331649
+public void test_nullable_field_14a() {
+ Map options = getCompilerOptions();
+ options.put(JavaCore.COMPILER_PB_SYNTACTIC_NULL_ANALYSIS_FOR_FIELDS, JavaCore.ENABLED);
+ runNegativeTestWithLibs(
+ new String[] {
+ "X.java",
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " @Nullable Object o = new Object();\n" +
+ " public String oString(@NonNull Object a) {\n" +
+ " if (this.o != a)\n" +
+ " return this.o.toString(); // warn here, check has no effect\n" +
+ " return \"\";\n" +
+ " }\n" +
+ "}\n"
+ },
+ options,
+ "----------\n" +
+ "1. ERROR in X.java (at line 6)\n" +
+ " return this.o.toString(); // warn here, check has no effect\n" +
+ " ^\n" +
+ "Potential null pointer access: The field o is declared as @Nullable\n" +
+ "----------\n");
+}
+
+// an enum is declared within the scope of a null-default
+// https://bugs.eclipse.org/331649#c61
+public void test_enum_field_01() {
+ runConformTestWithLibs(
+ new String[] {
+ "tests/X.java",
+ "package tests;\n" +
+ "@org.eclipse.jdt.annotation.NonNullByDefault\n" +
+ "public class X {\n" +
+ " enum A { B }\n" +
+ " public static void main(String ... args) {\n" +
+ " System.out.println(A.B);\n" +
+ " }\n" +
+ "}\n"
+ },
+ null,
+ "",
+ "B");
+}
+
+// Bug 380896 - Enum constants not recognised as being NonNull.
+// see also https://bugs.eclipse.org/331649#c61
+public void test_enum_field_02() {
+ runConformTestWithLibs(
+ new String[] {
+ "tests/X.java",
+ "package tests;\n" +
+ "import org.eclipse.jdt.annotation.*;\n" +
+ "public class X {\n" +
+ " enum A { B }\n" +
+ " public static void main(String ... args) {\n" +
+ " test(A.B);\n" +
+ " }\n" +
+ " static void test(@NonNull A a) {\n" +
+ " System.out.println(a.ordinal());\n" +
+ " }\n" +
+ "}\n"
+ },
+ null,
+ "",
+ "0");
+}
+
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=372011
// Test whether @NonNullByDefault on a binary package or an enclosing type is respected from enclosed elements.
public void testBug372011() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
index ffa67b4..21bdbfb 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceImplTests.java
@@ -11,6 +11,7 @@
* bug 320170
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
* bug 386181 - [compiler][null] wrong transition in UnconditionalFlowInfo.mergedWith()
+ * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation.
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -38,6 +39,7 @@
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
/**
@@ -1022,7 +1024,7 @@
public PackageBinding getPackage() {
return null;
}
- public boolean isCompatibleWith(TypeBinding right) {
+ public boolean isCompatibleWith(TypeBinding right, Scope captureScope) {
return false;
}
public char[] qualifiedSourceName() {
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
index 077a446..6245e57 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java
@@ -24,6 +24,9 @@
* bug 367879 - Incorrect "Potential null pointer access" warning on statement after try-with-resources within try-finally
* bug 383690 - [compiler] location of error re uninitialized final field should be aligned
* bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
+ * bug 376263 - Bogus "Potential null pointer access" warning
+ * bug 331649 - [compiler][null] consider null annotations for fields
+ * bug 382789 - [compiler][null] warn when syntactically-nonnull expression is compared against null
*******************************************************************************/
package org.eclipse.jdt.core.tests.compiler.regression;
@@ -32,6 +35,7 @@
import junit.framework.Test;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.tests.util.Util;
import org.eclipse.jdt.core.util.ClassFileBytesDisassembler;
@@ -53,6 +57,7 @@
static {
// TESTS_NAMES = new String[] { "testBug345305_14" };
// TESTS_NAMES = new String[] { "test0515_try_finally" };
+// TESTS_NAMES = new String[] { "testBug376263" };
// TESTS_NUMBERS = new int[] { 561 };
// TESTS_RANGE = new int[] { 1, 2049 };
}
@@ -9634,9 +9639,9 @@
"X.java",
"public class X {\n" +
"\n" +
- " void foo() {\n" +
+ " void foo(Object that) {\n" +
" Object o = new Object();\n" +
- " while (this != null) {\n" +
+ " while (that != null) {\n" +
" try {\n" +
" o = null;\n" +
" break;\n" +
@@ -9653,7 +9658,7 @@
" ^\n" +
"Null comparison always yields false: The variable o cannot be null at this location\n" +
"----------\n" +
- "2. WARNING in X.java (at line 13)\n" +
+ "2. WARNING in X.java (at line 13)\n" +
" if (o == null) return;\n" +
" ^^^^^^^\n" +
"Dead code\n" +
@@ -15623,6 +15628,190 @@
"",/* expected error */
JavacTestOptions.Excuse.EclipseWarningConfiguredAsError);
}
+public void testBug376263() {
+ Map customOptions = getCompilerOptions();
+ customOptions.put(JavaCore.COMPILER_PB_POTENTIAL_NULL_REFERENCE, JavaCore.ERROR);
+ runConformTest(
+ new String[] {
+ "Test.java",
+ "public class Test {\n" +
+ " private int x;\n" +
+ "\n" +
+ " static void test(Test[] array) {\n" +
+ " Test elem = null;\n" +
+ " int i = 0;\n" +
+ " while (i < array.length) {\n" +
+ " if (i == 0) {\n" +
+ " elem = array[0];\n" +
+ " }\n" +
+ " if (elem != null) {\n" +
+ " while (true) {\n" +
+ " if (elem.x >= 0 || i >= array.length) { // should not warn here\n" +
+ " break;\n" +
+ " }\n" +
+ " elem = array[i++];\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ "",
+ null/*classLibraries*/,
+ true/*shouldFlush*/,
+ null/*vmArgs*/,
+ customOptions,
+ null/*requestor*/);
+}
+//object/array allocation
+public void testExpressions01() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo() {\n" +
+ " if (new Object() == null)\n" +
+ " System.out.println(\"null\");\n" +
+ " }\n" +
+ " void goo() {\n" +
+ " if (null != this.new I())\n" +
+ " System.out.println(\"nonnull\");\n" +
+ " }\n" +
+ " void hoo() {\n" +
+ " if (null != new Object[3])\n" +
+ " System.out.println(\"nonnull\");\n" +
+ " }\n" +
+ " class I {}\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " if (new Object() == null)\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Null comparison always yields false: this expression cannot be null\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 4)\n" +
+ " System.out.println(\"null\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " if (null != this.new I())\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 11)\n" +
+ " if (null != new Object[3])\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n"
+ );
+}
+//'this' expressions (incl. qualif.)
+public void testExpressions02() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo() {\n" +
+ " if (this == null)\n" +
+ " System.out.println(\"null\");\n" +
+ " }\n" +
+ " class I {\n" +
+ " void goo() {\n" +
+ " if (null != X.this)\n" +
+ " System.out.println(\"nonnull\");\n" +
+ " }\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " if (this == null)\n" +
+ " ^^^^\n" +
+ "Null comparison always yields false: this expression cannot be null\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 4)\n" +
+ " System.out.println(\"null\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 8)\n" +
+ " if (null != X.this)\n" +
+ " ^^^^^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n"
+ );
+}
+//various non-null expressions: class-literal, string-literal, casted 'this'
+public void testExpressions03() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo() {\n" +
+ " if (X.class == null)\n" +
+ " System.out.println(\"null\");\n" +
+ " }\n" +
+ " void goo() {\n" +
+ " if (null != \"STRING\")\n" +
+ " System.out.println(\"nonnull\");\n" +
+ " if (null == (Object)this)\n" +
+ " System.out.println(\"I'm null\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " if (X.class == null)\n" +
+ " ^^^^^^^\n" +
+ "Null comparison always yields false: this expression cannot be null\n" +
+ "----------\n" +
+ "2. WARNING in X.java (at line 4)\n" +
+ " System.out.println(\"null\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n" +
+ "3. ERROR in X.java (at line 7)\n" +
+ " if (null != \"STRING\")\n" +
+ " ^^^^^^^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n" +
+ "4. ERROR in X.java (at line 9)\n" +
+ " if (null == (Object)this)\n" +
+ " ^^^^^^^^^^^^\n" +
+ "Null comparison always yields false: this expression cannot be null\n" +
+ "----------\n" +
+ "5. WARNING in X.java (at line 10)\n" +
+ " System.out.println(\"I\'m null\");\n" +
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
+ "Dead code\n" +
+ "----------\n"
+ );
+}
+
+//a non-null ternary expression
+public void testExpressions04() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public class X {\n" +
+ " void foo(boolean b) {\n" +
+ " Object o1 = new Object();\n" +
+ " Object o2 = new Object();\n" +
+ " if ((b ? o1 : o2) != null)\n" +
+ " System.out.println(\"null\");\n" +
+ " }\n" +
+ "}\n"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 5)\n" +
+ " if ((b ? o1 : o2) != null)\n" +
+ " ^^^^^^^^^^^^^\n" +
+ "Redundant null check: this expression cannot be null\n" +
+ "----------\n"
+ );
+}
// Bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
// simplified: only try-finally involved
diff --git a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
index 6ced2f5..25fcd68 100644
--- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.jdt.core.tests.model;singleton:=true
-Bundle-Version: 3.8.1
+Bundle-Version: 3.8.2
Bundle-ClassPath: jdtcoretestsmodel.jar
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/org.eclipse.jdt.core.tests.model/pom.xml b/org.eclipse.jdt.core.tests.model/pom.xml
index 36df8eb..1415479 100644
--- a/org.eclipse.jdt.core.tests.model/pom.xml
+++ b/org.eclipse.jdt.core.tests.model/pom.xml
@@ -20,7 +20,7 @@
</parent>
<groupId>eclipse.jdt.core</groupId>
<artifactId>org.eclipse.jdt.core.tests.model</artifactId>
- <version>3.8.1-SNAPSHOT</version>
+ <version>3.8.2-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<build>
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
index 5a94b55..77ade14 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTModelBridgeTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2012 IBM Corporation and others.
+ * Copyright (c) 2004, 2013 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
@@ -15,6 +15,7 @@
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.*;
@@ -1194,6 +1195,31 @@
"LX;@LX~MyAnnot;",
bindings);
}
+
+ /*
+ * Ensures that the correct IBinding is created for package-info.class's IType
+ */
+ public void testCreateBindings24() throws CoreException {
+ createClassFile(
+ "/P/lib",
+ "pack/package-info.class",
+ "@Deprecated\n" +
+ "package pack;");
+ IJavaProject javaProject = getJavaProject("P");
+ IPackageFragment pack = javaProject.findPackageFragment(new Path("/P/lib/pack"));
+ IType type = pack.getClassFile("package-info.class").getType();
+ ASTParser parser = ASTParser.newParser(JLS3_INTERNAL);
+ parser.setProject(javaProject);
+ IJavaElement[] elements = new IJavaElement[] {type};
+ IBinding[] bindings = parser.createBindings(elements, null);
+ assertBindingsEqual(
+ "Lpack/package-info;",
+ bindings);
+ IAnnotationBinding[] annotations = ((ITypeBinding) bindings[0]).getAnnotations();
+ assertBindingsEqual(
+ "@Ljava/lang/Deprecated;",
+ annotations);
+ }
/*
* Ensures that the IJavaElement of an IBinding representing a field is correct.
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
index ee7353c..82c0dc8 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachSourceTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -351,15 +351,14 @@
/*
* Ensures that the source of a .class file is implicetely attached when prj=src=bin
* (regression test for bug 41444 [navigation] error dialog on opening class file)
+ *
+ * Note: The test case is being modified as part of fix for bug
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=398490
*/
public void testClassFileInOutput() throws CoreException {
IClassFile classFile = getClassFile("AttachSourceTests/src/A.class");
String source = classFile.getSource();
- assertSourceEquals(
- "Unexpected source",
- "public class A {\n" +
- "}",
- source);
+ assertNull("Unexpected source", source);
}
/**
* Retrieves the source code for "A.class", which is
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java
index 613c598..fdadfe7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -93,6 +93,7 @@
suite.addTest(new AttachedJavadocTests("testBug354766_2"));
suite.addTest(new AttachedJavadocTests("testBug394967"));
suite.addTest(new AttachedJavadocTests("testBug394382"));
+ suite.addTest(new AttachedJavadocTests("testBug398272"));
return suite;
}
@@ -1150,4 +1151,15 @@
this.project.setRawClasspath(oldClasspath, null);
}
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=398272
+ public void testBug398272() throws JavaModelException {
+ IPackageFragment packageFragment = this.root.getPackageFragment("p1.p2.p3.p4"); //$NON-NLS-1$
+ assertNotNull("Should not be null", packageFragment); //$NON-NLS-1$
+ try {
+ String javadoc = packageFragment.getAttachedJavadoc(new NullProgressMonitor()); //$NON-NLS-1$
+ assertNull("Javadoc should be null", javadoc); //$NON-NLS-1$
+ } catch(JavaModelException jme) {
+ fail("Should not throw Java Model Exception");
+ }
+ }
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
index c00cad2..ecd021f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -344,6 +344,7 @@
suite.addTest(new ClasspathTests("testBug287164"));
suite.addTest(new ClasspathTests("testBug220928a"));
suite.addTest(new ClasspathTests("testBug220928b"));
+ suite.addTest(new ClasspathTests("testBug396299"));
return suite;
}
public void setUpSuite() throws Exception {
@@ -7420,4 +7421,43 @@
deleteProject("P");
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=396299
+public void testBug396299() throws Exception {
+ boolean autoBuild = getWorkspace().isAutoBuilding();
+ IWorkspaceDescription preferences = getWorkspace().getDescription();
+ try {
+ JavaModelManager.EclipsePreferencesListener prefListener = new JavaModelManager.EclipsePreferencesListener();
+ preferences.setAutoBuilding(true);
+ getWorkspace().setDescription(preferences);
+
+ JavaProject proj1 = (JavaProject) this.createJavaProject("P1", new String[] {}, "");
+ addLibrary(proj1, "abc.jar", null, new String[] {
+ "p/X.java",
+ "package p;\n" +
+ "public class X {}\n"},
+ JavaCore.VERSION_1_4);
+ proj1.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_4);
+
+ Map map = proj1.getOptions(false);
+ map.put(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, JavaCore.WARNING);
+ proj1.setOptions(map);
+
+ IEclipsePreferences eclipsePreferences = proj1.getEclipsePreferences();
+ eclipsePreferences.addPreferenceChangeListener(prefListener);
+ simulateExitRestart();
+ waitForAutoBuild();
+ assertMarkers("Unexpected markers", "", proj1);
+ map = proj1.getOptions(false);
+ map.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_1);
+ proj1.setOptions(map);
+
+ assertMarkers("Unexpected markers",
+ "Incompatible .class files version in required binaries. Project \'P1\' is targeting a 1.1 runtime, but is compiled against \'P1/abc.jar\' which requires a 1.4 runtime", proj1);
+ eclipsePreferences.removePreferenceChangeListener(prefListener);
+ } finally {
+ preferences.setAutoBuilding(autoBuild);
+ getWorkspace().setDescription(preferences);
+ deleteProject("P1");
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
index 2f8c3af..c2b7869 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/CompletionTests2.java
@@ -30,19 +30,25 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.CompletionContext;
+import org.eclipse.jdt.core.CompletionProposal;
+import org.eclipse.jdt.core.CompletionRequestor;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.codeassist.InternalCompletionContext;
import org.eclipse.jdt.internal.codeassist.RelevanceConstants;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.SourceType;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
public class CompletionTests2 extends ModifyingResourceTests implements RelevanceConstants {
@@ -5981,4 +5987,64 @@
deleteProject("P");
}
}
+//https://bugs.eclipse.org/bugs/show_bug.cgi?id=397070
+public void testBug397070() throws JavaModelException {
+ this.workingCopies = new ICompilationUnit[1];
+ this.workingCopies[0] = getWorkingCopy(
+ "/Completion/src/test/Completion.java",
+ "package test;\n" +
+ "public class Completion implements {}\n" +
+ "public interface Completion2 extends {}\n" +
+ "public class Completion3 extends {}\n" +
+ "}\n");
+
+ class CompletionRequestor2 extends CompletionRequestor {
+ SourceType type = null;
+ public void acceptContext(CompletionContext con) {
+ this.type = null;
+ if (con instanceof InternalCompletionContext) {
+ InternalCompletionContext context = (InternalCompletionContext) con;
+ IJavaElement element = context.getEnclosingElement();
+ if (element instanceof org.eclipse.jdt.internal.core.SourceType) {
+ this.type = (SourceType) element;
+ }
+ }
+ }
+ public boolean isExtendedContextRequired() {
+ return true;
+ }
+ public SourceType getType() {
+ return this.type;
+ }
+ public void accept(CompletionProposal proposal) {
+ // Do nothing
+ }
+ }
+
+ CompletionRequestor2 requestor = new CompletionRequestor2();
+ String str = this.workingCopies[0].getSource();
+ String completeBehind = "Completion implements ";
+ int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ try {
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ SourceType type = requestor.getType();
+ String[] names = type.getSuperInterfaceTypeSignatures();
+ assertEquals("Incorrect syper interface signature", 0, names.length);
+
+ completeBehind = "Completion2 extends ";
+ cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ type = requestor.getType();
+ names = type.getSuperInterfaceTypeSignatures();
+ assertEquals("Incorrect syper interface signature", 0, names.length);
+
+ completeBehind = "Completion3 extends ";
+ cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
+ this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
+ type = requestor.getType();
+ assertNull("Incorrect syper class signature", type.getSuperclassTypeSignature());
+ } catch (IllegalArgumentException iae) {
+ fail("Invalid completion context");
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java
index 52af315..23cf2f2 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaSearchScopeTests.java
@@ -10,10 +10,13 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.HashMap;
import junit.framework.Test;
+import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
@@ -24,6 +27,7 @@
import org.eclipse.jdt.core.tests.model.AbstractJavaSearchTests.JavaSearchResultCollector;
import org.eclipse.jdt.core.tests.model.AbstractJavaSearchTests.TypeNameMatchCollector;
import org.eclipse.jdt.internal.core.JavaModelManager;
+import org.eclipse.jdt.internal.core.index.IndexLocation;
import org.eclipse.jdt.internal.core.search.indexing.IndexManager;
/**
@@ -1096,4 +1100,22 @@
}
}
}
+// https://bugs.eclipse.org/bugs/show_bug.cgi?id=397818
+public void testBug397818() throws CoreException {
+ try {
+ createJavaProject("P1", new String[] {"src"}, new String[] {}, "bin");
+
+ createFolder("/P1/new folder");
+ IFile newFile = createFile("/P1/new folder/testindex.index", "");
+ try {
+ URL newURL = newFile.getLocationURI().toURL();
+ IndexLocation indexLoc = IndexLocation.createIndexLocation(newURL);
+ assertTrue("Malformed index location", indexLoc.getIndexFile().exists());
+ } catch (MalformedURLException e) {
+ fail("Malformed index location");
+ }
+ } finally {
+ deleteProject("P1");
+ }
+}
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SuiteOfTestCases.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SuiteOfTestCases.java
index 25fb7e5..4a7250f 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SuiteOfTestCases.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/SuiteOfTestCases.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
@@ -12,21 +12,25 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
+import java.util.Set;
+import org.eclipse.test.internal.performance.PerformanceMeterFactory;
+
+import junit.extensions.TestSetup;
import junit.framework.Protectable;
import junit.framework.Test;
import junit.framework.TestResult;
import junit.framework.TestSuite;
/**
- * A test case class that can be set up (using the setUpSuite() method) and tore down (using the teardDownSuite() method)
+ * A test case class that can be set up (using the setUpSuite() method) and torn down (using the tearDownSuite() method)
* once for all test cases of this class.
*/
public class SuiteOfTestCases extends org.eclipse.jdt.core.tests.junit.extension.TestCase {
/*
* A test suite that initialize the test case's fields once, then that copies the values
- * of these fields intto each subsequent test case.
+ * of these fields into each subsequent test case.
*/
public static class Suite extends TestSuite {
public SuiteOfTestCases currentTestCase;
@@ -120,4 +124,31 @@
*/
public void tearDownSuite() throws Exception {
}
+
+ /**
+ * Decorate an individual test with setUpSuite/tearDownSuite, so that the test can be run standalone.
+ * This method is called by the Eclipse JUnit test runner when a test is re-run from the JUnit view's context menu.
+ */
+ public static Test setUpTest(Test test) {
+ if (!(test instanceof SuiteOfTestCases))
+ return test;
+
+ final SuiteOfTestCases suiteOfTestCases = (SuiteOfTestCases) test;
+ return new TestSetup(test) {
+ protected void setUp() throws Exception {
+ // reset the PerformanceMeterFactory, so that the same scenario can be run again:
+ Field field = PerformanceMeterFactory.class.getDeclaredField("fScenarios");
+ field.setAccessible(true);
+ Set set = (Set) field.get(null);
+ set.clear();
+
+ suiteOfTestCases.setUpSuite();
+ }
+
+ protected void tearDown() throws Exception {
+ suiteOfTestCases.tearDownSuite();
+ }
+ };
+ }
+
}
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java
index 7d01596..d791a49 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/rewrite/describing/ImportRewriteTest.java
@@ -1,12 +1,13 @@
/*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2013 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Corporation - initial API and implementation
+ * IBM Corporation - initial API and implementation
+ * Stephan Herrmann - Contribution for Bug 378024 - Ordering of comments between imports not preserved
*******************************************************************************/
package org.eclipse.jdt.core.tests.rewrite.describing;
@@ -65,6 +66,10 @@
}
public static Test suite() {
+// System.err.println("Warning, only part of the ImportRewriteTest are being executed!");
+// Suite suite = new Suite(ImportRewriteTest.class.getName());
+// suite.addTest(new ImportRewriteTest("testRemoveImports1"));
+// return suite;
return allTests();
}
@@ -1913,6 +1918,7 @@
"import java.util.Map.*;\n" +
"\n" +
"/* lead 2*/import java.io.PrintWriter.*; // test2\n" +
+ "\n" +
"/* lead 3*/ import java.util.Map.SomethingElse; // test3\n" +
"// commen 3\n" +
"\n" +
@@ -1973,6 +1979,7 @@
"\n" +
"// comment 1\n" +
"/* lead 2*/import java.io.PrintWriter.*; // test2\n" +
+ "\n" +
"/* lead 1*/ import java.util.*; // test1\n" +
"import java.util.Map.*;\n" +
"/* lead 3*/ import java.util.Map.SomethingElse; // test3\n" +
@@ -2032,11 +2039,8 @@
"package pack1;\n" +
"\n" +
"// comment 1\n" +
- "/* lead 2*/" +
- "import java.util.*;\n" +
+ "/* lead 2*//* lead 1*/ import java.util.*; // test1\n" +
"// test2\n" +
- "/* lead 1*/ \n" +
- "// test1\n" +
"/* lead 3*/ \n" +
"// test3\n" +
"// commen 3\n" +
@@ -2096,8 +2100,7 @@
"\n" +
"// comment 1\n" +
"/* lead 1*/ " +
- "import java.util.Map.*;\n" +
- "// test1\n" +
+ "import java.util.Map.*; // test1\n" +
"/* lead 2*/\n" +
"// test2\n" +
"/* lead 3*/ \n" +
@@ -2159,10 +2162,9 @@
"// comment 1\n" +
"/* lead 2*/import java.io.PrintWriter.*; // test2\n" +
"\n" +
- "/* lead 1*/ \n" +
+ "/* lead 1*/ import java.util.*;\n" +
" // test1\n" +
"// commen 3\n" +
- "import java.util.*;\n" +
"\n" +
"public class C {\n" +
" public static void main(String[] args) {\n" +
@@ -2178,6 +2180,1392 @@
assertEqualString(cu.getSource(), buf.toString());
}
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=376930
+ // separating comment should not prevent folding into *-import
+ public void testBug376930_5e() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "import java.util.Map;\n" +
+ "/* comment leading Map.Entry */\n" +
+ "import java.util.Map.Entry;\n" +
+ "\n" +
+ "public class C {\n" +
+ " public static void main(String[] args) {\n" +
+ " HashMap h;\n" +
+ "\n" +
+ " Map.Entry e= null;\n" +
+ " Entry e2= null;\n" +
+ "\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "javax", "org", "com" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, true);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "import java.util.*;\n" +
+ "/* comment leading Map.Entry */\n" +
+ "import java.util.Map.Entry;\n" +
+ "\n" +
+ "public class C {\n" +
+ " public static void main(String[] args) {\n" +
+ " HashMap h;\n" +
+ "\n" +
+ " Map.Entry e= null;\n" +
+ " Entry e2= null;\n" +
+ "\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ public void testBug378024() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * keep me with List\n" +
+ " *\n" +
+ " */\n" +
+ "import java.awt.List;// test1\n" +
+ "/*\n" +
+ " * keep me with Serializable\n" +
+ " */\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * keep me with HashMap\n" +
+ " */\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.awt", "java.io", "java.util" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * keep me with List\n" +
+ " *\n" +
+ " */\n" +
+ "import java.awt.List;// test1\n\n" +
+ "/*\n" +
+ " * keep me with Serializable\n" +
+ " */\n" +
+ "import java.io.Serializable;// test2\n\n" +
+ "/*\n" +
+ " * keep me with HashMap\n" +
+ " */\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ public void testBug378024b() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "import java.awt.List;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 1, 1, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "import java.awt.*;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "import java.io.*;// test2\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "import java.util.*;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // leading and trailing comments always move with imports.
+ // comments in between stay where they are
+ public void testBug378024c() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // leading and trailing comments always move with imports.
+ // comments in between stay where they are
+ public void testBug378024c_1() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // leading and trailing comments always move with imports, even if they get folded.
+ // comments in between stay where they are
+ public void testBug378024c_2() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 1, 1, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.*;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.*;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "//lead 3\n" +
+ "import java.util.*;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // not adding an import should preserve its comments and put them at the end.
+ public void testBug378024d() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 1, 1, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.*;// test1\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.*;// test3\n" +
+ "// commen 3\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // adding a new import should not disturb comments and import should be added in its group
+ public void testBug378024e() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.io.PrintWriter");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.*;\n" +
+ "// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // removing an import should preserve its comments at the end, and adding a new import should not disturb
+ // existing comments
+ public void testBug378024e_1() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.PrintWriter");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "import java.io.PrintWriter;\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // folding imports because of a newly added import should preserve comments
+ public void testBug378024f() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.io.PrintWriter");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.*;\n" +
+ "// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // folding imports because of a newly added import should preserve comments
+ public void testBug378024f_1() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * keep me with List\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * keep me with Serializable\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * keep me with Serializable 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 3\n" +
+ "import java.io.PrintWriter;// test3\n" +
+ "/*\n" +
+ " * keep me with PrintWriter\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me\n" +
+ " */\n" +
+ "\n" +
+ "//lead 4\n" +
+ "import java.util.HashMap;// test4\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 2, 2, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.io.PrintWriter");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * keep me with List\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "//lead 4\n" +
+ "import java.util.HashMap;// test4\n" +
+ "// commen 3\n" +
+ "/*\n" +
+ " * keep me with Serializable\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "// lead 3\n" +
+ "import java.io.*;// test3\n" +
+ "/*\n" +
+ " * keep me with PrintWriter\n" +
+ " */\n" +
+ "// test2\n" +
+ "/*\n" +
+ " * keep me with Serializable 2\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me\n" +
+ " */\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // Re-ordering imports and converting them to *
+ public void testBug378024g() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.awt", "java.util", "java.io", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 1, 1, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+
+ apply(imports);
+
+ StringBuffer buf2 = new StringBuffer();
+ buf2.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.*;// test1\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.*;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.*;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " List l = new List();\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf2.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // Preserve comments when imports are removed in case the restoring of imports is enabled
+ // This will test changes in org.eclipse.jdt.internal.core.dom.rewrite.ImportRewriteAnalyzer.removeImport(String, boolean)
+ public void testBug378024h() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, true);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.removeImport("java.awt.List");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "\n" +
+ "// lead 1\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // Preserve comments when imports are removed in case the restoring of imports is enabled
+ public void testBug378024h_1() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/* i am with List */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, true);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.removeImport("java.awt.List");
+ imports.addImport("java.util.List");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "/* i am with List */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "import java.util.List;\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // Preserve comments when imports are unfolded.
+ public void testBug378024i() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "import java.awt.*;// test1\n" +
+ "/* i am with List */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.*;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.*;// test3\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " HashMap e= null;\n" +
+ " PrintWriter p= null;\n" +
+ " List l= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 99, 99, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.io.PrintWriter");
+ imports.addImport("java.io.Serializable");
+ imports.addImport("java.util.HashMap");
+ imports.addImport("java.util.Map");
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/* i am with List */\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.PrintWriter;// test2\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "import java.io.Serializable;\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "// commen 3\n" +
+ "import java.util.Map;\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " HashMap e= null;\n" +
+ " PrintWriter p= null;\n" +
+ " List l= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=378024
+ // Preserve comments when imports are folded but a member type import is present
+ public void testBug378024j() throws Exception {
+ IPackageFragment pack1 = this.sourceFolder.createPackageFragment("pack1", false, null);
+ StringBuffer buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "import java.awt.List;// test1\n" +
+ "/* i am with List */\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.HashMap;// test3\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "\n" +
+ "/*keep me with Map.Entry*/\n" +
+ "import java.util.Map.Entry;// member type import\n" +
+ "/*keep me with Map.Entry 2*/\n" +
+ "\n" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "\n" +
+ "// lead 2\n" +
+ "import java.io.Serializable;// test2\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ ICompilationUnit cu = pack1.createCompilationUnit("C.java", buf.toString(), false, null);
+
+ String[] order = new String[] { "java", "java.util", "com", "pack" };
+
+ ImportRewrite imports= newImportsRewrite(cu, order, 1, 1, false);
+ imports.setUseContextToFilterImplicitImports(true);
+ imports.addImport("java.awt.List");
+ imports.addImport("java.util.HashMap");
+ imports.addImport("java.util.Map.Entry");
+ imports.addImport("java.io.Serializable");
+
+ apply(imports);
+
+ buf = new StringBuffer();
+ buf.append(
+ "package pack1;\n" +
+ "\n" +
+ "// comment 1\n" +
+ "/*\n" +
+ " * don't move me 1\n" +
+ " *\n" +
+ " */\n" +
+ "// lead 1\n" +
+ "import java.awt.*;// test1\n" +
+ "/* i am with List */\n" +
+ "\n" +
+ "//lead 3\n" +
+ "import java.util.*;// test3\n" +
+ "/*\n" +
+ " * don't move me 3\n" +
+ " */\n" +
+ "/*keep me with Map.Entry*/\n" +
+ "import java.util.Map.Entry;// member type import\n" +
+ "/*keep me with Map.Entry 2*/\n" +
+ "/*\n" +
+ " * don't move me 2\n" +
+ " */" +
+ "/*\n" +
+ " * don't move me 4\n" +
+ " */\n" +
+ "// lead 2\n" +
+ "import java.io.*;// test2\n" +
+ "// commen 3\n" +
+ "\n" +
+ "public class C implements Serializable{\n" +
+ " public static void main(String[] args) {\n" +
+ " Map e= null;\n" +
+ " }\n" +
+ "}");
+ assertEqualString(cu.getSource(), buf.toString());
+ }
+
private void assertAddedAndRemoved(ImportRewrite imports, String[] expectedAdded, String[] expectedRemoved, String[] expectedAddedStatic, String[] expectedRemovedStatic) {
assertEqualStringsIgnoreOrder(imports.getAddedImports(), expectedAdded);
assertEqualStringsIgnoreOrder(imports.getAddedStaticImports(), expectedAddedStatic);