diff --git a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF index bc00fbfe540..3bb787a3c47 100644 --- a/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.builder/META-INF/MANIFEST.MF @@ -14,7 +14,6 @@ Require-Bundle: org.junit;bundle-version="3.8.1", org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)", org.eclipse.test;bundle-version="[3.6.0,4.0.0)", org.eclipse.test.performance;bundle-version="[3.1.0,4.0.0)", - org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional, org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional, org.eclipse.jdt.apt.core Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java index e735f0b847c..b4da162ae70 100644 --- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java +++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/AnnotationDependencyTests.java @@ -17,21 +17,19 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.builder; -import java.io.File; +import java.io.IOException; import junit.framework.Test; import org.eclipse.core.resources.IMarker; -import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.eclipse.jdt.core.tests.compiler.regression.AbstractNullAnnotationTest; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.osgi.framework.Bundle; /** * Tests to verify that annotation changes cause recompilation of dependent types. @@ -144,17 +142,19 @@ private void addAnnotationType() { void setupProjectForNullAnnotations() throws JavaModelException { // add the org.eclipse.jdt.annotation library (bin/ folder or jar) to the project: - Bundle[] bundles = Platform.getBundles("org.eclipse.jdt.annotation","[1.1.0,2.0.0)"); - File bundleFile = FileLocator.getBundleFileLocation(bundles[0]).get(); - String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); - IJavaProject javaProject = env.getJavaProject(this.projectPath); - IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); - int len = rawClasspath.length; - System.arraycopy(rawClasspath, 0, rawClasspath = new IClasspathEntry[len+1], 0, len); - rawClasspath[len] = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null); - javaProject.setRawClasspath(rawClasspath, null); - - javaProject.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + try { + String annotationsLib = AbstractNullAnnotationTest.getAnnotationV1LibPath(); + IJavaProject javaProject = env.getJavaProject(this.projectPath); + IClasspathEntry[] rawClasspath = javaProject.getRawClasspath(); + int len = rawClasspath.length; + System.arraycopy(rawClasspath, 0, rawClasspath = new IClasspathEntry[len+1], 0, len); + rawClasspath[len] = JavaCore.newLibraryEntry(new Path(annotationsLib), null, null); + javaProject.setRawClasspath(rawClasspath, null); + + javaProject.setOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, JavaCore.ENABLED); + } catch (IOException ioe) { + throw new JavaModelException(ioe, -13); + } } /** 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 b4db246297f..5789e272ced 100644 --- a/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.compiler/META-INF/MANIFEST.MF @@ -22,7 +22,6 @@ Require-Bundle: org.junit;bundle-version="3.8.1", org.eclipse.test;bundle-version="[3.6.0,4.0.0)", org.eclipse.test.performance;bundle-version="[3.10.0,4.0.0)", org.eclipse.core.resources;bundle-version="[3.21.0,4.0.0)", - org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional, org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)", org.eclipse.jdt.internal.compiler.apt.dispatch diff --git a/org.eclipse.jdt.core.tests.compiler/build.properties b/org.eclipse.jdt.core.tests.compiler/build.properties index cfa629f6809..1693443f0a3 100644 --- a/org.eclipse.jdt.core.tests.compiler/build.properties +++ b/org.eclipse.jdt.core.tests.compiler/build.properties @@ -17,7 +17,8 @@ bin.includes = test.xml,\ .,\ META-INF/,\ plugin.properties,\ - workspace/ + workspace/,\ + lib/org.eclipse.jdt.annotation_1.2.100.v20241001-0914.jar source.. = src/ output.. = bin/ src.includes = about.html diff --git a/org.eclipse.jdt.core.tests.compiler/lib/org.eclipse.jdt.annotation_1.2.100.v20241001-0914.jar b/org.eclipse.jdt.core.tests.compiler/lib/org.eclipse.jdt.annotation_1.2.100.v20241001-0914.jar new file mode 100644 index 00000000000..5db80bf2399 Binary files /dev/null and b/org.eclipse.jdt.core.tests.compiler/lib/org.eclipse.jdt.annotation_1.2.100.v20241001-0914.jar differ diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java index 5376767e4cb..35d2e597c2f 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractNullAnnotationTest.java @@ -15,10 +15,11 @@ import java.io.File; import java.io.IOException; +import java.net.URL; import java.util.Map; import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.osgi.framework.Bundle; @@ -89,16 +90,24 @@ protected void setUpAnnotationLib() throws IOException { int len = defaultLibs.length; this.LIBS = new String[len+1]; System.arraycopy(defaultLibs, 0, this.LIBS, 0, len); - String version = this.complianceLevel >= ClassFileConstants.JDK1_8 ? "[2.0.0,3.0.0)" : "[1.1.0,2.0.0)"; - Bundle[] bundles = org.eclipse.jdt.core.tests.compiler.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", version); - File bundleFile = FileLocator.getBundleFileLocation(bundles[0]).get(); - if (bundleFile.isDirectory()) - this.LIBS[len] = bundleFile.getPath()+"/bin"; - else - this.LIBS[len] = bundleFile.getPath(); + this.LIBS[len] = getAnnotationLibPath(); } } + protected String getAnnotationLibPath() throws IOException { + Bundle[] bundles = org.eclipse.jdt.core.tests.compiler.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[2.0.0,3.0.0)"); + File bundleFile = FileLocator.getBundleFileLocation(bundles[0]).get(); + if (bundleFile.isDirectory()) + return bundleFile.getPath()+"/bin"; + else + return bundleFile.getPath(); + } + + public static String getAnnotationV1LibPath() throws IOException { + URL libEntry = Platform.getBundle("org.eclipse.jdt.core.tests.compiler").getEntry("/lib/org.eclipse.jdt.annotation_1.2.100.v20241001-0914.jar"); + return FileLocator.toFileURL(libEntry).getPath(); + } + // Conditionally augment problem detection settings static boolean setNullRelatedOptions = true; diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java index 028d6281d3b..699b4d914cc 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java @@ -36,6 +36,8 @@ import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.element.TypeElement; +import junit.framework.Test; +import junit.framework.TestSuite; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -1341,6 +1343,59 @@ public void run() { public AbstractRegressionTest(String name) { super(name); } + + /* argument 'inheritedDepth' is not exposed in original API, therefore these helpers are copied below with this arg added */ + protected static void buildMinimalComplianceTestSuite(int minimalCompliance, int inheritedDepth, TestSuite suite, Class evaluationTestClass) { + int complianceLevels = getPossibleComplianceLevels(); + for (int[] map : complianceTestLevelMapping) { + if ((complianceLevels & map[0]) != 0) { + long complianceLevelForJavaVersion = ClassFileConstants.getComplianceLevelForJavaVersion(map[1]); + checkCompliance(evaluationTestClass, minimalCompliance, suite, complianceLevels, inheritedDepth, map[0], map[1], getVersionString(complianceLevelForJavaVersion)); + } + } + } + protected static void checkCompliance(Class evaluationTestClass, int minimalCompliance, TestSuite suite, int complianceLevels, int inheritedDepth, + int abstractCompilerTestCompliance, int classFileConstantsVersion, String release) { + int lev = complianceLevels & abstractCompilerTestCompliance; + if (lev != 0) { + if (lev < minimalCompliance) { + System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance " + release + "!"); + } else { + suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(classFileConstantsVersion), inheritedDepth)); + } + } + } + public static Test buildUniqueComplianceTestSuite(Class evaluationTestClass, long uniqueCompliance, int inheritedDepth) { + long highestLevel = highestComplianceLevels(); + if (highestLevel < uniqueCompliance) { + String complianceString; + if (highestLevel == ClassFileConstants.JDK10) + complianceString = "10"; + else if (highestLevel == ClassFileConstants.JDK9) + complianceString = "9"; + else if (highestLevel <= CompilerOptions.getFirstSupportedJdkLevel()) + complianceString = CompilerOptions.getFirstSupportedJavaVersion(); + else { + highestLevel = ClassFileConstants.getLatestJDKLevel(); + if (highestLevel > 0) { + complianceString = CompilerOptions.versionFromJdkLevel(highestLevel); + } else { + complianceString = "unknown"; + } + + } + + System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+complianceString+"!"); + return new TestSuite(); + } + TestSuite complianceSuite = new RegressionTestSetup(uniqueCompliance); + List tests = buildTestsList(evaluationTestClass, inheritedDepth); + for (int index=0, size=tests.size(); index= ClassFileConstants.JDK1_8 - ? "@Target(ElementType.TYPE_USE)\n" - : ""; + return useDeclarationAnnotations() + ? "" + : "@Target(ElementType.TYPE_USE)\n"; } String cancenNonNullByDefault() { - return this.complianceLevel < ClassFileConstants.JDK1_8 - ? " @NonNullByDefault(false)\n" - : " @NonNullByDefault({})\n"; + return useDeclarationAnnotations() + ? " @NonNullByDefault(false)\n" + : " @NonNullByDefault({})\n"; } /** @@ -129,11 +133,7 @@ String cancenNonNullByDefault() { @Override protected void setUp() throws Exception { super.setUp(); - if (this.complianceLevel >= ClassFileConstants.JDK1_8) - this.TEST_JAR_SUFFIX = "_1.8.jar"; - if (this.LIBS == null) { - this.LIBS = getLibsWithNullAnnotations(this.complianceLevel); - } + this.TEST_JAR_SUFFIX = "_1.8.jar"; } // a nullable argument is dereferenced without a check @@ -539,13 +539,13 @@ public void test_nonnull_parameter_015() { "X.java", "import org.eclipse.jdt.annotation.*;\n" + "public class X {\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? " void foo(@NonNull Object ... o) {\n" : " void foo(Object @NonNull... o) {\n") + " if (o != null)\n" + " System.out.print(o.toString());\n" + " }\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? " void foo2(int i, @NonNull Object ... o) {\n" : " void foo2(int i, Object @NonNull ... o) {\n" ) + @@ -592,19 +592,19 @@ public void test_nonnull_parameter_016() { "X.java", "import org.eclipse.jdt.annotation.*;\n" + "public class X {\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? " X(@NonNull Object ... o) {\n" : " X(Object @NonNull... o) {\n") + " if (o != null)\n" + " System.out.print(o.toString());\n" + " }\n" + " class Y extends X {\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? " Y(int i, @NonNull Object ... o) {\n" : " Y(int i, Object @NonNull... o) {\n") + " super(i, (Object)null);\n" + " }\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? " Y(char c, @NonNull Object ... o) {\n" : " Y(char c, Object @NonNull... o) {\n") + " this(1, new Object(), null);\n" + @@ -727,7 +727,7 @@ public void test_nonnull_local_001() { "----------\n" + "1. ERROR in X.java (at line 4)\n" + " @NonNull Object o1 = b ? null : new Object();\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? " ^^^^^^^^^^^^^^^^^^^^^^^\n" + "Null type mismatch: required \'@NonNull Object\' but the provided value is inferred as @Nullable\n" : @@ -766,7 +766,7 @@ public void test_nonnull_local_002() { "----------\n" + "1. ERROR in X.java (at line 5)\n" + " o1 = b ? null : new Object();\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? " ^^^^^^^^^^^^^^^^^^^^^^^\n" + "Null type mismatch: required \'@NonNull Object\' but the provided value is inferred as @Nullable\n" : @@ -1281,7 +1281,7 @@ public void test_parameter_specification_inheritance_014() { "}\n", }, customOptions, - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? "----------\n" + "1. ERROR in p1\\Y.java (at line 2)\n" + " public class Y extends X implements IY {\n" + @@ -1804,7 +1804,7 @@ public void test_nonnull_return_011() { "1. ERROR in X.java (at line 5)\n" + " if (dubious == null)\n" + " ^^^^^^^\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? "Null comparison always yields false: The variable dubious is specified as @NonNull\n" : "Redundant null check: comparing '@NonNull Object' against null\n" ) + "----------\n" + @@ -2067,7 +2067,7 @@ public void test_illegal_annotation_001() { "1. ERROR in X.java (at line 2)\n" + " @NonNull public class X {\n" + " ^^^^^^^^\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? "The annotation @NonNull is disallowed for this location\n" : "The nullness annotation 'NonNull' is not applicable at this location\n") + "----------\n"); @@ -2110,7 +2110,7 @@ public void test_illegal_annotation_003() { "1. ERROR in X.java (at line 3)\n" + " @NonNull void foo() {}\n" + " ^^^^^^^^\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) + (useDeclarationAnnotations() ? "The nullness annotation @NonNull is not applicable for the primitive type void\n" : "Type annotation is illegal for a method that returns void\n") + "----------\n", @@ -2261,9 +2261,15 @@ public void test_illegal_annotation_008() { "1. ERROR in X.java (at line 3)\n" + " @NonNull X() {}\n" + " ^^^^^^^^\n" + - ((this.complianceLevel < ClassFileConstants.JDK1_8) - ? "The annotation @NonNull is disallowed for this location\n" - : "The nullness annotation 'NonNull' is not applicable at this location\n" ) + + "The nullness annotation 'NonNull' is not applicable at this location\n" + + (useDeclarationAnnotations() + ? // in this case the above error is redundant, but acceptable. + "----------\n" + + "2. ERROR in X.java (at line 3)\n" + + " @NonNull X() {}\n" + + " ^^^^^^^^\n" + + "The annotation @NonNull is disallowed for this location\n" + : "") + "----------\n"); } @@ -2519,7 +2525,7 @@ public void test_default_nullness_003b() { } // package level default is consumed from package-info.class, similarly for type level default - fine tuned default public void test_default_nullness_003c() { - if (this.complianceLevel < ClassFileConstants.JDK1_8) return; // uses version 2.0 of @NonNullByDefault + if (useDeclarationAnnotations()) return; // uses version 2.0 of @NonNullByDefault Map customOptions = getCompilerOptions(); runConformTestWithLibs( new String[] { @@ -2804,7 +2810,7 @@ public void test_default_nullness_010() { "----------\n" + "2. WARNING in p2\\Y.java (at line 5)\n" + " protected @NonNull Object getObject(@NonNull Object o) {\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? " ^^^^^^^^^^^^^^^^^\n" : " ^^^^^^^^^^^^^^^\n" ) + @@ -3490,7 +3496,7 @@ public void test_nonnull_var_in_constrol_structure_1() { "----------\n" + "1. WARNING in X.java (at line 4)\n" + " void print4(@NonNull String s) {\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? " ^^^^^^^^^^^^^^^^^\n" : " ^^^^^^^^^^^^^^^\n" ) + @@ -3508,7 +3514,7 @@ public void test_nonnull_var_in_constrol_structure_1() { "----------\n" + "4. WARNING in X.java (at line 17)\n" + " void print(@NonNull String s) {\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? " ^^^^^^^^^^^^^^^^^\n" : " ^^^^^^^^^^^^^^^\n" ) + @@ -5494,7 +5500,7 @@ public void test_nullable_field_16() { "1. ERROR in X.java (at line 19)\n" + " test(this.prop);\n" + " ^^^^^^^^^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Null type mismatch: required '@NonNull Object' but the provided value is specified as @Nullable\n" : "Null type mismatch (type annotations): required \'@NonNull Object\' but this expression has type \'@Nullable Object\'\n") + "----------\n"); @@ -6175,7 +6181,7 @@ public void testBug388281_06() { // whereas I2A cancels that same default "}\n" }, - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? "----------\n" + "1. ERROR in ctest\\C.java (at line 2)\n" + " public class C extends c.C2 implements i2.I2A {\n" + @@ -6609,7 +6615,7 @@ public void testBug412076() { new String[] { "FooImpl.java", "import org.eclipse.jdt.annotation.*;\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "@NonNullByDefault\n" : "@NonNullByDefault({DefaultLocation.PARAMETER,DefaultLocation.RETURN_TYPE})\n" // avoid @NonNull on type argument ) + @@ -7032,7 +7038,7 @@ public void testBug418235() { " }\n" + "}\n" }; - if (this.complianceLevel < ClassFileConstants.JDK1_8) { + if (useDeclarationAnnotations()) { runNegativeTestWithLibs( testFiles, "----------\n" + @@ -7048,7 +7054,7 @@ public void testBug418235() { } } public void testBug418235b() { - if (this.complianceLevel < ClassFileConstants.JDK1_8) + if (useDeclarationAnnotations()) return; runNegativeTestWithLibs( new String[] { @@ -7084,7 +7090,7 @@ public void testTypeAnnotationProblemNotIn17() { " return local;\n" + " }\n" + "}\n"; - if (this.complianceLevel < ClassFileConstants.JDK1_8) + if (useDeclarationAnnotations()) runConformTestWithLibs( new String[] { "X.java", @@ -7230,7 +7236,7 @@ public void testBug424624a() { " static class DeepNested {}\n" + " }\n" + " static public final @NonNull Inner field1 = new Test3().new Inner();\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? " static public final @NonNull Inner.DeepInner field2 = field1.new DeepInner();\n" + " static public final @NonNull Nested.InnerInNested field3 = new Nested().new InnerInNested();\n" + " static public final @NonNull Nested.DeepNested field4 = new Nested.DeepNested();\n" @@ -7297,7 +7303,7 @@ public void testBug424624b() { " static class DeepNested {}\n" + " }\n" + " static public final @NonNull Inner field1 = new Test3().new Inner();\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? " static public final @NonNull Inner.DeepInner field2 = field1.new DeepInner();\n" + " static public final @NonNull Nested.InnerInNested field3 = new Nested().new InnerInNested();\n" + " static public final @NonNull Nested.DeepNested field4 = new Nested.DeepNested();\n" @@ -7361,7 +7367,7 @@ public void testBug432348() { "public enum E {\n" + " @Marker @NonNull A, B, C\n" + "}\n"; - if (this.complianceLevel < ClassFileConstants.JDK1_8) { + if (useDeclarationAnnotations()) { runConformTestWithLibs( new String[] { "E.java", @@ -7444,7 +7450,7 @@ public void testBug403674a() { "2. ERROR in X.java (at line 10)\n" + " switch (value) {}\n" + " ^^^^^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Potential null pointer access: The variable value may be null at this location\n" : @@ -7738,7 +7744,7 @@ public void testBug443347b() { "1. ERROR in X.java (at line 11)\n" + " new Super(s) {\n" + " ^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Null type mismatch: required \'@NonNull String\' but the provided value is specified as @Nullable\n" : "Null type mismatch (type annotations): required \'@NonNull String\' but this expression has type \'@Nullable String\'\n") + "----------\n"); @@ -7772,7 +7778,7 @@ public void testBug443347c() { "1. ERROR in X.java (at line 12)\n" + " new Super(s) {\n" + " ^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Null type mismatch: required \'@NonNull String\' but the provided value is specified as @Nullable\n" : "Null type mismatch (type annotations): required \'@NonNull String\' but this expression has type \'@Nullable String\'\n") + "----------\n"); @@ -7934,7 +7940,7 @@ public void testBug445708() { "3. ERROR in SwitchTest.java (at line 26)\n" + " switch (stringValue)\n" + " ^^^^^^^^^^^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Potential null pointer access: The variable stringValue may be null at this location\n" : "Potential null pointer access: this expression has a \'@Nullable\' type\n" ) + "----------\n" + @@ -7951,7 +7957,7 @@ public void testBug445708() { } // same as above but 1.8 with declaration annotations public void testBug445708b() { - if (this.complianceLevel < ClassFileConstants.JDK1_8) return; // only one combination tested + if (useDeclarationAnnotations()) return; // only one combination tested Map customOptions = getCompilerOptions(); customOptions.put(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, "org.foo.NonNull"); customOptions.put(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, "org.foo.Nullable"); @@ -8042,7 +8048,7 @@ public void testBug445708b() { } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=452780 - Internal compiler error: arrayIndexOutOfBounds public void testBug452780() { - if (this.complianceLevel < ClassFileConstants.JDK1_8) return; + if (useDeclarationAnnotations()) return; runConformTestWithLibs( new String[] { "Tools2.java", @@ -8098,7 +8104,7 @@ public void testBug455557() { "1. WARNING in X.java (at line 10)\n" + " for (@NonNull Object y : list) { \n" + " ^^^^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Null type safety: The expression of type \'String\' needs unchecked conversion to conform to \'@NonNull Object\'\n" : "Null type safety (type annotations): The expression of type \'String\' needs unchecked conversion to conform to \'@NonNull Object\'\n" ) + @@ -8199,7 +8205,7 @@ public void test_null_with_apt_comment4() { "1. WARNING in Test.java (at line 6)\n" + " public static final Test t = new Test(Integer.valueOf(0));\n" + " ^^^^^^^^^^^^^^^^^^\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "Null type safety: The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" : "Null type safety (type annotations): The expression of type \'Integer\' needs unchecked conversion to conform to \'@NonNull Integer\'\n" ) + @@ -8284,7 +8290,7 @@ public void testBug462790() { " ^^^^^^\n" + "The type parameter T should not be bounded by the final type String. Final types cannot be further extended\n" + "----------\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? "3. WARNING in EclipseBug.java (at line 10)\n" + " return commandType.newInstance();\n" + @@ -8341,7 +8347,7 @@ public void testBug459967_Enum_values() { "X.java", "import org.eclipse.jdt.annotation.*;\n" + "public class X {\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? " @NonNull MyEnum[] getValues() {\n" : @@ -8355,7 +8361,7 @@ public void testBug459967_Enum_values() { " }\n" + "}\n" }; - if (this.complianceLevel < ClassFileConstants.JDK1_8) { + if (useDeclarationAnnotations()) { runConformTestWithLibs( testFiles, getCompilerOptions(), @@ -8377,7 +8383,7 @@ public void testBug459967_Enum_values_binary() { "X.java", "import org.eclipse.jdt.annotation.*;\n" + "public class X {\n" + - (this.complianceLevel < ClassFileConstants.JDK1_8 + (useDeclarationAnnotations() ? " @NonNull MyEnum[] getValues() {\n" : @@ -8396,7 +8402,7 @@ public void testBug459967_Enum_values_binary() { "MyEnum.java", "public enum MyEnum { V1, V2 }\n", }); - if (this.complianceLevel < ClassFileConstants.JDK1_8) { + if (useDeclarationAnnotations()) { runConformTestWithLibs( false /*flush*/, testFiles, @@ -9190,7 +9196,7 @@ public void testBug502214() { "", }, getCompilerOptions(), - (this.complianceLevel < ClassFileConstants.JDK1_8 ? + (useDeclarationAnnotations() ? "----------\n" + "1. ERROR in test\\X.java (at line 22)\n" + " class Y extends A implements I {\n" + @@ -10546,7 +10552,7 @@ public void testBug542707_002() { ); } public void testBug542707_003() { - if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + if (this.complianceLevel < ClassFileConstants.JDK12 || useDeclarationAnnotations()) return; // switch expression // outer expected type (from assignment) is propagated deeply into a switch expression Runner runner = new Runner(); runner.customOptions = getCompilerOptions(); @@ -10617,7 +10623,7 @@ public void _testBug542707_004() { runner.runNegativeTest(); } public void testBug542707_005() { - if (this.complianceLevel < ClassFileConstants.JDK12) return; // switch expression + if (this.complianceLevel < ClassFileConstants.JDK12 || useDeclarationAnnotations()) return; // switch expression // switch value must not be null (@Nullable) Runner runner = new Runner(); runner.customOptions = getCompilerOptions(); @@ -10714,7 +10720,7 @@ public void testBug545715() { new String[] {"--enable-preview"}); } public void testBug548418_001a() { - if (this.complianceLevel < ClassFileConstants.JDK14) return; + if (this.complianceLevel < ClassFileConstants.JDK14 || useDeclarationAnnotations()) return; runNegativeTestWithLibs( new String[] { "X.java", @@ -10765,7 +10771,7 @@ public void testBug548418_001a() { "----------\n"); } public void testBug548418_001b() { - if (this.complianceLevel < ClassFileConstants.JDK14) return; + if (this.complianceLevel < ClassFileConstants.JDK14 || useDeclarationAnnotations()) return; runNegativeTestWithLibs( new String[] { "X.java", @@ -11239,7 +11245,7 @@ public void testBug565246() { runner.customOptions.put(CompilerOptions.OPTION_ReportLocalVariableHiding, CompilerOptions.IGNORE); runner.customOptions.put(CompilerOptions.OPTION_ReportNullUncheckedConversion, CompilerOptions.ERROR); runner.classLibraries = this.LIBS; - if (this.complianceLevel >= ClassFileConstants.JDK1_8) { + if (!useDeclarationAnnotations()) { runner.expectedCompilerLog = "----------\n" + "1. ERROR in bug\\B.java (at line 39)\n" + diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullDeclarationAnnotationTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullDeclarationAnnotationTest.java new file mode 100644 index 00000000000..4e047231416 --- /dev/null +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/NullDeclarationAnnotationTest.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2024 GK Software SE and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Stephan Herrmann - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.compiler.regression; + +import java.io.IOException; +import junit.framework.Test; +import junit.framework.TestSuite; + +/** Run tests from the super class with (legacy) declaration annotations. */ +public class NullDeclarationAnnotationTest extends NullAnnotationTest { + + public NullDeclarationAnnotationTest(String name) { + super(name); + } + + // 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[] { "testBug545715" }; +// TESTS_NUMBERS = new int[] { 561 }; +// TESTS_RANGE = new int[] { 1, 2049 }; + } + + public static Test suite() { + TestSuite suite = new TestSuite(testClass().getName()); + buildMinimalComplianceTestSuite(FIRST_SUPPORTED_JAVA_VERSION, 1, suite, testClass()); + return suite; + } + + public static Class testClass() { + return NullDeclarationAnnotationTest.class; + } + + public boolean useDeclarationAnnotations() { + return true; + } + + /** + * @deprecated + */ + @Override + protected void setUp() throws Exception { + super.setUp(); + this.TEST_JAR_SUFFIX = ".jar"; + } + + @Override + protected String getAnnotationLibPath() throws IOException { + return getAnnotationV1LibPath(); + } + +} diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakAnnotatedTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakAnnotatedTests.java index f3399e7895f..0b3d03ee0d2 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakAnnotatedTests.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ResourceLeakAnnotatedTests.java @@ -13,11 +13,9 @@ *******************************************************************************/ package org.eclipse.jdt.core.tests.compiler.regression; -import java.util.List; import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; -import org.eclipse.jdt.core.tests.util.AbstractCompilerTest; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; @@ -36,63 +34,10 @@ public ResourceLeakAnnotatedTests(String name) { } public static Test suite() { TestSuite suite = new TestSuite(ResourceLeakAnnotatedTests.class.getName()); - // argument 'inheritedDepth' is not exposed in original API, therefore these helpers are copied below with this arg added buildMinimalComplianceTestSuite(FIRST_SUPPORTED_JAVA_VERSION, 1, suite, ResourceLeakAnnotatedTests.class); return suite; } -private static void buildMinimalComplianceTestSuite(int minimalCompliance, int inheritedDepth, TestSuite suite, Class evaluationTestClass) { - int complianceLevels = AbstractCompilerTest.getPossibleComplianceLevels(); - for (int[] map : complianceTestLevelMapping) { - if ((complianceLevels & map[0]) != 0) { - long complianceLevelForJavaVersion = ClassFileConstants.getComplianceLevelForJavaVersion(map[1]); - checkCompliance(evaluationTestClass, minimalCompliance, suite, complianceLevels, inheritedDepth, map[0], map[1], getVersionString(complianceLevelForJavaVersion)); - } - } -} -protected static void checkCompliance(Class evaluationTestClass, int minimalCompliance, TestSuite suite, int complianceLevels, - int inheritedDepth, int abstractCompilerTestCompliance, int classFileConstantsVersion, String release) { - int lev = complianceLevels & abstractCompilerTestCompliance; - if (lev != 0) { - if (lev < minimalCompliance) { - System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance " + release + "!"); - } else { - suite.addTest(buildUniqueComplianceTestSuite(evaluationTestClass, ClassFileConstants.getComplianceLevelForJavaVersion(classFileConstantsVersion), inheritedDepth)); - } - } -} -public static Test buildUniqueComplianceTestSuite(Class evaluationTestClass, long uniqueCompliance, int inheritedDepth) { - long highestLevel = highestComplianceLevels(); - if (highestLevel < uniqueCompliance) { - String complianceString; - if (highestLevel == ClassFileConstants.JDK10) - complianceString = "10"; - else if (highestLevel == ClassFileConstants.JDK9) - complianceString = "9"; - else if (highestLevel <= CompilerOptions.getFirstSupportedJdkLevel()) - complianceString = CompilerOptions.getFirstSupportedJavaVersion(); - else { - highestLevel = ClassFileConstants.getLatestJDKLevel(); - if (highestLevel > 0) { - complianceString = CompilerOptions.versionFromJdkLevel(highestLevel); - } else { - complianceString = "unknown"; - } - - } - - System.err.println("Cannot run "+evaluationTestClass.getName()+" at compliance "+complianceString+"!"); - return new TestSuite(); - } - TestSuite complianceSuite = new RegressionTestSetup(uniqueCompliance); - List tests = buildTestsList(evaluationTestClass, inheritedDepth); - for (int index=0, size=tests.size(); index getCompilerOptions() { Map options = super.getCompilerOptions(); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java index 49939b89280..9d841ef817b 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/StackMapAttributeTest.java @@ -25,7 +25,6 @@ import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; -import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; @SuppressWarnings({ "unchecked", "rawtypes" }) public class StackMapAttributeTest extends AbstractRegressionTest { @@ -8315,7 +8314,7 @@ public void testBug412203_a() throws Exception { "}\n", }, "", - getLibsWithNullAnnotations(CompilerOptions.getFirstSupportedJdkLevel()), + getLibsWithNullAnnotations(), true/*flush*/, null/*vmArgs*/, options, @@ -8437,7 +8436,7 @@ public void testBug412203_b() throws Exception { "}\n", }, "", - getLibsWithNullAnnotations(CompilerOptions.getFirstSupportedJdkLevel()), + getLibsWithNullAnnotations(), true/*flush*/, null/*vmArgs*/, options, @@ -8554,7 +8553,7 @@ public void testBug412203_c() throws Exception { "}\n", }, "", - getLibsWithNullAnnotations(CompilerOptions.getFirstSupportedJdkLevel()), + getLibsWithNullAnnotations(), true/*flush*/, null/*vmArgs*/, options, 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 bf7f3f4b751..894edc7c2a5 100644 --- a/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF +++ b/org.eclipse.jdt.core.tests.model/META-INF/MANIFEST.MF @@ -27,7 +27,6 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)", org.eclipse.text;bundle-version="[3.2.0,4.0.0)", com.ibm.icu;bundle-version="3.4.4", org.eclipse.core.filesystem;bundle-version="[1.2.0,2.0.0)", - org.eclipse.jdt.annotation;bundle-version="[1.1.0,2.0.0)";resolution:=optional, org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional Bundle-RequiredExecutionEnvironment: JavaSE-17 Eclipse-BundleShape: dir diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java index 89c2bb089d3..50dc3b52bfd 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ExternalAnnotations17Test.java @@ -37,10 +37,10 @@ import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.tests.compiler.regression.AbstractNullAnnotationTest; import org.eclipse.jdt.core.util.ExternalAnnotationUtil; import org.eclipse.jdt.core.util.ExternalAnnotationUtil.MergeStrategy; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; -import org.osgi.framework.Bundle; public class ExternalAnnotations17Test extends ExternalAnnotations18Test { @@ -62,6 +62,11 @@ public static Test suite() { return buildModelTestSuite(ExternalAnnotations17Test.class, BYTECODE_DECLARATION_ORDER); } + @Override + public void setUpSuite() throws Exception { + super.setUpSuite(); + this.ANNOTATION_LIB = AbstractNullAnnotationTest.getAnnotationV1LibPath(); + } /** * @deprecated */ @@ -69,14 +74,6 @@ static int getJLS8() { return AST.JLS8; } - /** - * @deprecated indirectly uses deprecated class PackageAdmin - */ - @Override - protected Bundle[] getAnnotationBundles() { - return org.eclipse.jdt.core.tests.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[1.1.0,2.0.0)"); - } - @Override public String getSourceWorkspacePath() { // we read individual projects from within this folder: diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java index 10e4796e962..82a9c043e96 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/NullAnnotationModelTests.java @@ -44,6 +44,7 @@ import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.dom.*; +import org.eclipse.jdt.core.tests.compiler.regression.AbstractNullAnnotationTest; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.osgi.framework.Bundle; @@ -76,9 +77,7 @@ public void setUp() throws Exception { File bundleFile = FileLocator.getBundleFileLocation(bundles[0]).get(); this.ANNOTATION_LIB = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); - bundles = org.eclipse.jdt.core.tests.Activator.getPackageAdmin().getBundles("org.eclipse.jdt.annotation", "[1.1.0,2.0.0)"); - bundleFile = FileLocator.getBundleFileLocation(bundles[0]).get(); - this.ANNOTATION_LIB_V1 = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); + this.ANNOTATION_LIB_V1 = AbstractNullAnnotationTest.getAnnotationV1LibPath(); } protected String testJarPath(String jarName) throws IOException {