/******************************************************************************* * Copyright (c) 2000, 2015 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 *******************************************************************************/ package org.eclipse.jdt.core.tests.builder; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.Arrays; import junit.framework.Test; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; 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.util.Util; @SuppressWarnings("rawtypes") public class PackageInfoTest extends BuilderTests { public PackageInfoTest(String name) { super(name); } // 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[] { "testBug374063" }; // TESTS_NUMBERS = new int[] { 3 }; // TESTS_RANGE = new int[] { 21, 50 }; } public static Test suite() { return buildTestSuite(PackageInfoTest.class); } public void test001() throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addClass(root, "pack", "Annot", //$NON-NLS-1$ //$NON-NLS-2$ "package pack;\n" + //$NON-NLS-1$ "public @interface Annot {}" //$NON-NLS-1$ ); incrementalBuild(projectPath); IPath packageInfoPath = env.addFile(root, "pack/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "@Annot package p1" //$NON-NLS-1$ ); incrementalBuild(projectPath); expectingOnlyProblemsFor(packageInfoPath); final Problem[] problems = env.getProblems(); Arrays.sort(problems); assertNotNull(problems); final StringWriter stringWriter = new StringWriter(); final PrintWriter writer = new PrintWriter(stringWriter); final int problemsLength = problems.length; if (problemsLength == 1) { writer.print(problems[0].getMessage()); } else { for (int i = 0; i < problemsLength - 1; i++) writer.println(problems[i].getMessage()); writer.print(problems[problemsLength - 1].getMessage()); } writer.close(); final String expectedOutput = "Syntax error on token \"p1\", ; expected after this token\n" + "The declared package \"p1\" does not match the expected package \"pack\""; assertSourceEquals("Different messages", expectedOutput, stringWriter.toString()); } public void test002() throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addClass(root, "testcase", "Main", //$NON-NLS-1$ //$NON-NLS-2$ "package testcase;\n" + "\n" + "public class Main {\n" + " public static void main(String[] argv) throws Exception {\n" + " Package pkg = Package.getPackage(\"testcase\");\n" + " System.out.print(pkg.getAnnotation(TestAnnotation.class));\n" + " pkg = Class.forName(\"testcase.package-info\").getPackage();\n" + " System.out.print(pkg.getAnnotation(TestAnnotation.class));\n" + " }\n" + "}" ); env.addClass(root, "testcase", "TestAnnotation", //$NON-NLS-1$ //$NON-NLS-2$ "package testcase;\n" + "\n" + "import static java.lang.annotation.ElementType.PACKAGE;\n" + "import static java.lang.annotation.RetentionPolicy.RUNTIME;\n" + "\n" + "import java.lang.annotation.Retention;\n" + "import java.lang.annotation.Target;\n" + "\n" + "@Target(PACKAGE)\n" + "@Retention(RUNTIME)\n" + "public @interface TestAnnotation {\n" + "}" ); env.addFile(root, "testcase/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "@TestAnnotation package testcase;" //$NON-NLS-1$ ); incrementalBuild(projectPath); expectingNoProblems(); executeClass(projectPath, "testcase.Main", "@testcase.TestAnnotation()@testcase.TestAnnotation()", ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } public void test003() throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addPackage(root, "testcase"); IPath packageInfoPath = env.addFile(root, "testcase/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "" //$NON-NLS-1$ ); incrementalBuild(projectPath); expectingOnlySpecificProblemFor( packageInfoPath, new Problem("testcase/package-info.java", "The declared package \"\" does not match the expected package \"testcase\"", packageInfoPath, 0, 0, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ } // test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=252555 : NPE // on duplicate package-info public void test004() throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ IPath otherRoot = env.addPackageFragmentRoot(projectPath, "test"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addPackage(root, "my.foo"); env.addPackage(otherRoot, "my.foo"); env.addFile(root, "my/foo/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "/**\n" + "* A demo package for foo.\n" + "*/\n" + "package my.foo;\n" ); IPath otherPackageInfoPath = env.addFile(otherRoot, "my/foo/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "/**\n" + "* A demo package for foo.\n" + "*/\n" + "package my.foo;\n" ); incrementalBuild(projectPath); expectingOnlySpecificProblemFor( otherPackageInfoPath, new Problem("my/foo/package-info.java", "The type package-info is already defined", otherPackageInfoPath, 0, 0, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ } // test for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=258145 : JME // on duplicate package-info public void test258145() throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath root = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ IPath otherRoot = env.addPackageFragmentRoot(projectPath, "test"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addPackage(root, "my.foo"); env.addFile(root, "my/foo/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "/**\n" + "* A demo package for foo.\n" + "*/\n" + "package my.foo;\n" ); fullBuild(projectPath); env.addPackage(otherRoot, "my.foo"); IPath otherPackageInfoPath = env.addFile(otherRoot, "my/foo/package-info.java", //$NON-NLS-1$ //$NON-NLS-2$ "/**\n" + "* A demo package for foo.\n" + "*/\n" + "package my.foo;\n" ); incrementalBuild(projectPath); expectingOnlySpecificProblemFor( otherPackageInfoPath, new Problem("my/foo/package-info.java", "The type package-info is already defined", otherPackageInfoPath, 0, 0, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=323785 // (NPE upon creation/deletion of package-info.java in default package) public void test323785 () throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath root = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); fullBuild(projectPath); env.addFile(root, "package-info.java", ""); incrementalBuild(projectPath); expectingNoProblems(); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=323785 // verify that changes to package info containing secondary types do trigger incremental build. public void test323785a () throws JavaModelException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath root = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); IPath xJavaPath = env.addFile(root, "X.java", "class X extends Y {}\n"); fullBuild(projectPath); env.addFile(root, "package-info.java", "class Y {}\n"); incrementalBuild(projectPath); expectingNoProblems(); env.addFile(root, "package-info.java", "final class Y {}\n"); incrementalBuild(projectPath); expectingOnlySpecificProblemFor( xJavaPath, new Problem("X.java", "The type X cannot subclass the final class Y", xJavaPath, 16, 17, CategorizedProblem.CAT_TYPE, IMarker.SEVERITY_ERROR)); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012 // test missing default nullness annotation for a package without package-info // test when the package-info is added with the default annotation, the problem disappears public void testBug372012() throws JavaModelException, IOException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; String test2Code = "package p1;\n" + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "public class Test2 {\n" + " public void bar(String str) {}\n" + "}"; String test3Code = "package p1;\n" + "public class Test3 {\n" + " public void bar(String str) {}\n" + "}"; IPath test1Path = env.addClass(srcRoot, "p1", "Test1", test1Code); env.addClass(srcRoot, "p1", "Test2", test2Code); env.addClass(srcRoot, "p1", "Test3", test3Code); fullBuild(projectPath); expectingNoProblemsFor(test1Path); // should have only one marker expectingProblemsFor(srcRoot, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]"); // add package-info.java with default annotation String packageInfoCode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); incrementalBuild(projectPath); expectingProblemsFor(projectPath, "Problem : Nullness default is redundant with a default specified for the enclosing package p1 [ resource : </Project/src/p1/Test2.java> range : <12,56> category : <120> severity : <2>]"); // verify that all package CU's were recompiled expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test1$Test1Inner", "p1.Test2", "p1.Test3", "p1.package-info" }); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012 // test missing default nullness annotation for a package without package-info // test when the the default annotations are added to all top level types, the problem stays public void testBug372012a() throws JavaModelException, IOException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; String test2Code = "package p1;\n" + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "public class Test2 {\n" + " public void bar(String str) {}\n" + "}"; IPath test1Path = env.addClass(srcRoot, "p1", "Test1", test1Code); env.addClass(srcRoot, "p1", "Test2", test2Code); fullBuild(projectPath); expectingNoProblemsFor(test1Path); // should have only one marker expectingProblemsFor(srcRoot, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]"); // add default annotation to Test1 test1Code = "package p1;\n" + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; env.addClass(srcRoot, "p1", "Test1", test1Code); incrementalBuild(projectPath); // should have only one marker expectingProblemsFor(srcRoot, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]"); // verify that all package CU's were recompiled expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test1$Test1Inner"}); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012 // test missing default nullness annotation for a package without package-info // test when the the default annotations is added to only 1 top level type, the problem stays public void testBug372012b() throws JavaModelException, IOException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; String test2Code = "package p1;\n" + "public class Test2 {\n" + " public void bar(String str) {}\n" + "}"; IPath test1Path = env.addClass(srcRoot, "p1", "Test1", test1Code); env.addClass(srcRoot, "p1", "Test2", test2Code); fullBuild(projectPath); expectingNoProblemsFor(test1Path); // should have only one marker expectingProblemsFor(srcRoot, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]"); // add default annotation to Test1 test1Code = "package p1;\n" + "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; env.addClass(srcRoot, "p1", "Test1", test1Code); incrementalBuild(projectPath); // should have only one marker expectingProblemsFor(srcRoot, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]"); // verify that only Test1's CU's were recompiled expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test1$Test1Inner"}); } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=372012 // test missing default nullness annotation for a package with package-info // test when the the default annotation is removed from package-info, the problem comes back public void testBug372012c() throws JavaModelException, IOException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public void foo() {\n" + " new Test2().bar(\"\");\n" + " }\n" + " class Test1Inner{}\n" + "}"; String test2Code = "package p1;\n" + "public class Test2 {\n" + " public void bar(String str) {}\n" + "}"; // add package-info.java with default annotation String packageInfoCode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); env.addClass(srcRoot, "p1", "Test1", test1Code); env.addClass(srcRoot, "p1", "Test2", test2Code); env.addClass(srcRoot, "p1", "package-info", packageInfoCode); fullBuild(projectPath); // default annotation present, so no problem expectingNoProblemsFor(srcRoot); // add package-info.java with default annotation packageInfoCode = "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); incrementalBuild(projectPath); expectingProblemsFor(projectPath, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1/package-info.java> range : <8,10> category : <90> severity : <2>]"); // verify that all package CU's were recompiled expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.Test1$Test1Inner", "p1.Test2", "p1.package-info" }); } /** * https://bugs.eclipse.org/bugs/show_bug.cgi?id=367836 */ public void testBug367836() throws JavaModelException { IPath projectPath = env.addProject("Project"); //$NON-NLS-1$ env.addExternalJars(projectPath, Util.getJavaClassLibs()); env.removePackageFragmentRoot(projectPath, ""); //$NON-NLS-1$ IPath src = env.addPackageFragmentRoot(projectPath, "src"); //$NON-NLS-1$ env.setOutputFolder(projectPath, "bin"); //$NON-NLS-1$ env.addClass(src, "p", "A", //$NON-NLS-1$ //$NON-NLS-2$ "package p;\n"+ //$NON-NLS-1$ "public class A {}" //$NON-NLS-1$ ); IPath bPath = env.addClass(src, "p", "package-info", //$NON-NLS-1$ //$NON-NLS-2$ "" //$NON-NLS-1$ ); fullBuild(); expectingOnlySpecificProblemFor(bPath, new Problem("", "The declared package \"\" does not match the expected package \"p\"", bPath, 0, 0, CategorizedProblem.CAT_INTERNAL, IMarker.SEVERITY_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$ } // https://bugs.eclipse.org/bugs/show_bug.cgi?id=374063 // verify that markers are created on the correct resource public void testBug374063() throws JavaModelException, IOException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); // remove old package fragment root so that names don't collide env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_REDUNDANT_NULL_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public String output(List<Integer> integers) {\n" + " return \"\";\n" + " }\n" + " public void output(List<Double> doubles) {}\n" + "}"; env.addClass(srcRoot, "p1", "Test1", test1Code); fullBuild(projectPath); // resource for compile errors should be Test1 and not p1 expectingProblemsFor(projectPath, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1> range : <8,10> category : <90> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <130,134> category : <40> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <58,62> category : <40> severity : <2>]"); // add package-info.java with default annotation String packageInfoCode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); incrementalBuild(projectPath); expectingProblemsFor(projectPath, "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <130,134> category : <40> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <58,62> category : <40> severity : <2>]"); // verify that all package CU's were recompiled expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.package-info" }); } // 382960 public void testBug382960() throws JavaModelException, IOException, CoreException { IPath projectPath = env.addProject("Project", "1.5"); env.addExternalJars(projectPath, Util.getJavaClassLibs()); fullBuild(projectPath); env.removePackageFragmentRoot(projectPath, ""); IPath srcRoot = env.addPackageFragmentRoot(projectPath, "src"); env.setOutputFolder(projectPath, "bin"); // prepare the project: setupProjectForNullAnnotations(projectPath); env.getJavaProject(projectPath).setOption(JavaCore.COMPILER_PB_MISSING_NONNULL_BY_DEFAULT_ANNOTATION, JavaCore.ERROR); String test1Code = "package p1;\n" + "public class Test1 {\n" + " public String output(List<Integer> integers) {\n" + " return \"\";\n" + " }\n" + " public void output(List<Double> doubles) {}\n" + "}"; env.addClass(srcRoot, "p1", "Test1", test1Code); String packageInfoCode = "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); fullBuild(projectPath); expectingProblemsFor(projectPath, "Problem : A default nullness annotation has not been specified for the package p1 [ resource : </Project/src/p1/package-info.java> range : <8,10> category : <90> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <130,134> category : <40> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <58,62> category : <40> severity : <2>]"); packageInfoCode = "@org.eclipse.jdt.annotation.NonNullByDefault\n" + "package p1;\n"; env.addClass(srcRoot, "p1", "package-info", packageInfoCode); incrementalBuild(projectPath); expectingProblemsFor(projectPath, "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <130,134> category : <40> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <58,62> category : <40> severity : <2>]"); expectingUniqueCompiledClasses(new String[] { "p1.Test1", "p1.package-info" }); IProject project = env.getProject(projectPath); IFile packageInfo = project.getFile("/src/p1/package-info.java"); packageInfo.touch(null); incrementalBuild(projectPath); expectingProblemsFor(projectPath, "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <130,134> category : <40> severity : <2>]\n" + "Problem : List cannot be resolved to a type [ resource : </Project/src/p1/Test1.java> range : <58,62> category : <40> severity : <2>]"); // verify that only package-info was recompiled expectingUniqueCompiledClasses(new String[] { "p1.package-info" }); } void setupProjectForNullAnnotations(IPath projectPath) throws IOException, JavaModelException { // add the org.eclipse.jdt.annotation library (bin/ folder or jar) to the project: File bundleFile = FileLocator.getBundleFile(Platform.getBundle("org.eclipse.jdt.annotation")); String annotationsLib = bundleFile.isDirectory() ? bundleFile.getPath()+"/bin" : bundleFile.getPath(); IJavaProject javaProject = env.getJavaProject(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); } protected void assertSourceEquals(String message, String expected, String actual) { if (actual == null) { assertEquals(message, expected, null); return; } actual = org.eclipse.jdt.core.tests.util.Util.convertToIndependantLineDelimiter(actual); if (!actual.equals(expected)) { System.out.print(org.eclipse.jdt.core.tests.util.Util.displayString(actual.toString(), 0)); } assertEquals(message, expected, actual); } public static Class testClass() { return PackageInfoTest.class; } }