8173068: ElementUtils getPackageElement does not allow for an unnamed package
authorjlahoda
Thu, 26 Jan 2017 14:14:01 +0100
changeset 43369 aafd33c96bac
parent 43368 cabe410a7a5c
child 43370 5969237f927c
8173068: ElementUtils getPackageElement does not allow for an unnamed package Summary: Removing special handling of unnamed packages in Elements.getPackageElement. Reviewed-by: darcy, jjg, ksrini
langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java
langtools/test/tools/javac/modules/EdgeCases.java
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu Jan 26 14:11:38 2017 +0100
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java	Thu Jan 26 14:14:01 2017 +0100
@@ -52,7 +52,7 @@
      * If running with modules, all modules in the modules graph are searched for matching packages.
      *
      * @param name  fully qualified package name, or an empty string for an unnamed package
-     * @return the named package, or {@code null} if it cannot be uniquely found
+     * @return the specified package, or {@code null} if it cannot be uniquely found
      */
     PackageElement getPackageElement(CharSequence name);
 
@@ -61,7 +61,7 @@
      *
      * @param name  fully qualified package name, or an empty string for an unnamed package
      * @param module module relative to which the lookup should happen
-     * @return the named package, or {@code null} if it cannot be found
+     * @return the specified package, or {@code null} if it cannot be found
      * @since 9
      */
     PackageElement getPackageElement(ModuleElement module, CharSequence name);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Jan 26 14:11:38 2017 +0100
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java	Thu Jan 26 14:14:01 2017 +0100
@@ -140,8 +140,6 @@
 
     private PackageSymbol doGetPackageElement(ModuleElement module, CharSequence name) {
         ensureEntered("getPackageElement");
-        if (name.length() == 0)
-            return syms.unnamedModule.unnamedPackage;
         return doGetElement(module, "getPackageElement", name, PackageSymbol.class);
     }
 
@@ -165,7 +163,7 @@
     private <S extends Symbol> S doGetElement(ModuleElement module, String methodName,
                                               CharSequence name, Class<S> clazz) {
         String strName = name.toString();
-        if (!SourceVersion.isName(strName)) {
+        if (!SourceVersion.isName(strName) && (!strName.isEmpty() || clazz == ClassSymbol.class)) {
             return null;
         }
         if (module == null) {
--- a/langtools/test/tools/javac/modules/EdgeCases.java	Thu Jan 26 14:11:38 2017 +0100
+++ b/langtools/test/tools/javac/modules/EdgeCases.java	Thu Jan 26 14:14:01 2017 +0100
@@ -23,13 +23,14 @@
 
 /*
  * @test
- * @bug 8154283 8167320 8171098 8172809 8173117
+ * @bug 8154283 8167320 8171098 8172809 8173068 8173117
  * @summary tests for multi-module mode compilation
  * @library /tools/lib
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.code
  *      jdk.compiler/com.sun.tools.javac.main
+ *      jdk.compiler/com.sun.tools.javac.processing
  *      jdk.compiler/com.sun.tools.javac.util
  * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask ModuleTestBase
  * @run main EdgeCases
@@ -53,8 +54,10 @@
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.ModuleElement.RequiresDirective;
+import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 import javax.tools.StandardJavaFileManager;
@@ -64,7 +67,10 @@
 //import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask
 import com.sun.tools.javac.api.JavacTaskImpl;
 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.util.Context;
 
 import toolbox.JarTask;
 import toolbox.JavacTask;
@@ -654,4 +660,156 @@
         }
     }
 
+    @Test
+    public void testUnnamedPackage(Path base) throws Exception {
+        List<String> out;
+        List<String> expected;
+
+        //-source 8:
+        Path src8 = base.resolve("src8");
+        Files.createDirectories(src8);
+        tb.writeJavaFiles(src8,
+                          "package test; public class Test {}");
+        Path classes = base.resolve("classes");
+        tb.createDirectories(classes);
+
+        out = new JavacTask(tb)
+                .options("--source-path", src8.toString(),
+                         "-processor", UnnamedPackageProcessor.class.getName(),
+                         "-source", "8")
+                .outdir(classes)
+                .files(findJavaFiles(src8))
+                .run()
+                .writeAll()
+                .getOutputLines(OutputKind.STDOUT);
+
+        expected = Arrays.asList("noModule");
+
+        if (!expected.equals(out)) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+
+        //-source 9, unnamed:
+        Path srcUnnamed = base.resolve("srcUnnamed");
+        Files.createDirectories(srcUnnamed);
+        tb.writeJavaFiles(srcUnnamed,
+                          "public class Test {}");
+        Path classesUnnamed = base.resolve("classesUnnamed");
+        tb.createDirectories(classesUnnamed);
+
+        out = new JavacTask(tb)
+                .options("--source-path", srcUnnamed.toString(),
+                         "-processor", UnnamedPackageProcessor.class.getName())
+                .outdir(classesUnnamed)
+                .files(findJavaFiles(srcUnnamed))
+                .run()
+                .writeAll()
+                .getOutputLines(OutputKind.STDOUT);
+
+        expected = Arrays.asList("unnamedModule");
+
+        if (!expected.equals(out)) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+
+        //-source 9, named:
+        Path srcNamed = base.resolve("srcNamed");
+        Files.createDirectories(srcNamed);
+        tb.writeJavaFiles(srcNamed,
+                          "module m {}",
+                          "public class Test {}");
+        Path classesNamed = base.resolve("classesNamed");
+        tb.createDirectories(classesNamed);
+
+        out = new JavacTask(tb)
+                .options("--source-path", srcNamed.toString(),
+                         "-classpath", "",
+                         "-processorpath", System.getProperty("test.class.path"),
+                         "-processor", UnnamedPackageProcessor.class.getName())
+                .outdir(classesNamed)
+                .files(findJavaFiles(srcNamed))
+                .run()
+                .writeAll()
+                .getOutputLines(OutputKind.STDOUT);
+
+        expected = Arrays.asList("m");
+
+        if (!expected.equals(out)) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+
+        //-source 9, conflict:
+        Path srcNamed2 = base.resolve("srcNamed2");
+        Path srcNamed2m1 = srcNamed2.resolve("m1x");
+        Files.createDirectories(srcNamed2m1);
+        tb.writeJavaFiles(srcNamed2m1,
+                          "module m1x {}",
+                          "public class Test {}");
+        Path srcNamed2m2 = srcNamed2.resolve("m2x");
+        Files.createDirectories(srcNamed2m2);
+        tb.writeJavaFiles(srcNamed2m2,
+                          "module m2x {}",
+                          "public class Test {}");
+        Path classesNamed2 = base.resolve("classesNamed2");
+        tb.createDirectories(classesNamed2);
+
+        out = new JavacTask(tb)
+                .options("--module-source-path", srcNamed2.toString(),
+                         "-classpath", "",
+                         "-processorpath", System.getProperty("test.class.path"),
+                         "-processor", UnnamedPackageProcessor.class.getName(),
+                         "-XDshould-stop.ifError=FLOW")
+                .outdir(classesNamed2)
+                .files(findJavaFiles(srcNamed2))
+                .run(Expect.FAIL)
+                .writeAll()
+                .getOutputLines(OutputKind.STDOUT);
+
+        expected = Arrays.asList("null",
+                                 "m1x: true",
+                                 "m2x: true");
+
+        if (!expected.equals(out)) {
+            throw new AssertionError("Unexpected output: " + out);
+        }
+    }
+
+    @SupportedAnnotationTypes("*")
+    public static final class UnnamedPackageProcessor extends AbstractProcessor {
+
+        int round = 0;
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            if (round++ != 0)
+                return false;
+
+            Elements elements = processingEnv.getElementUtils();
+            PackageElement pe = elements.getPackageElement("");
+
+            if (pe == null) {
+                System.out.println("null");
+            } else {
+                ModuleElement mod = (ModuleElement) pe.getEnclosingElement();
+                if (mod == null) {
+                    System.out.println("noModule");
+                } else if (mod.isUnnamed()) {
+                    System.out.println("unnamedModule");
+                } else {
+                    System.out.println(mod);
+                }
+            }
+
+            ModuleElement m1x = elements.getModuleElement("m1x");
+            ModuleElement m2x = elements.getModuleElement("m2x");
+
+            if (m1x != null && m2x != null) {
+                System.out.println("m1x: " + (elements.getPackageElement(m1x, "") != null));
+                System.out.println("m2x: " + (elements.getPackageElement(m2x, "") != null));
+            }
+
+            return false;
+        }
+
+    }
 }