8133884: javac moduleName/className and moduleName/packageName options
authorjlahoda
Thu, 11 Aug 2016 17:26:12 +0200
changeset 40311 bb76098875c8
parent 40310 a979695d72a1
child 40312 4c7bf578577e
8133884: javac moduleName/className and moduleName/packageName options 8162711: javax.lang.model.util.Elements.getModuleElement returns null during annotation processing on class files Summary: Adding a test for annotation processing for <module-name>/<class-name>; ensuring the <module-name> module is in the module graph. Reviewed-by: jjg
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java
langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java
langtools/test/tools/javac/modules/AnnotationProcessing.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Wed Aug 10 16:19:09 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java	Thu Aug 11 17:26:12 2016 +0200
@@ -147,7 +147,9 @@
     private final String addReadsOpt;
     private Map<ModuleSymbol, Set<RequiresDirective>> addReads;
     private final String addModsOpt;
+    private final Set<String> extraAddMods = new HashSet<>();
     private final String limitModsOpt;
+    private final Set<String> extraLimitMods = new HashSet<>();
 
     private Set<ModuleSymbol> rootModules = null;
 
@@ -195,8 +197,16 @@
         System.err.println(msg);
     }
 
+    public void addExtraAddModules(String... extras) {
+        extraAddMods.addAll(Arrays.asList(extras));
+    }
+
+    public void addExtraLimitModules(String... extras) {
+        extraLimitMods.addAll(Arrays.asList(extras));
+    }
+
     boolean inInitModules;
-    public void initModules(List<JCCompilationUnit> trees, Collection<String> extraAddMods, Collection<String> extraLimitMods) {
+    public void initModules(List<JCCompilationUnit> trees) {
         Assert.check(!inInitModules);
         try {
             inInitModules = true;
@@ -205,7 +215,7 @@
                 Assert.checkNull(rootModules);
                 Assert.checkNull(allModules);
                 this.rootModules = modules;
-                setupAllModules(extraAddMods, extraLimitMods); //initialize the module graph
+                setupAllModules(); //initialize the module graph
                 Assert.checkNonNull(allModules);
                 inInitModules = false;
             }, null);
@@ -862,7 +872,7 @@
         return allModules;
     }
 
-    private void setupAllModules(Collection<String> extraAddMods, Collection<String> extraLimitMods) {
+    private void setupAllModules() {
         Assert.checkNonNull(rootModules);
         Assert.checkNull(allModules);
 
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Wed Aug 10 16:19:09 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Aug 11 17:26:12 2016 +0200
@@ -900,6 +900,13 @@
         try {
             initProcessAnnotations(processors);
 
+            for (String className : classnames) {
+                int sep = className.indexOf('/');
+                if (sep != -1) {
+                    modules.addExtraAddModules(className.substring(0, sep));
+                }
+            }
+
             // These method calls must be chained to avoid memory leaks
             processAnnotations(
                 enterTrees(
@@ -1010,7 +1017,7 @@
     }
 
     public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
-        modules.initModules(roots, Collections.emptySet(), Collections.emptySet());
+        modules.initModules(roots);
         if (roots.isEmpty()) {
             enterDone = true;
         }
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Wed Aug 10 16:19:09 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java	Thu Aug 11 17:26:12 2016 +0200
@@ -187,7 +187,7 @@
             // Parse file objects provide via the DocumentationTool API
             parse(fileObjects, classTrees, true);
 
-            modules.initModules(classTrees.toList(), Collections.emptySet(), Collections.emptySet());
+            modules.initModules(classTrees.toList());
 
             // Build up the complete list of any packages to be documented
             Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Wed Aug 10 16:19:09 2016 -0700
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java	Thu Aug 11 17:26:12 2016 +0200
@@ -190,7 +190,7 @@
             // Parse file objects provide via the DocumentationTool API
             parse(fileObjects, classTrees, true);
 
-            modules.initModules(classTrees.toList(), Collections.emptySet(), Collections.emptySet());
+            modules.initModules(classTrees.toList());
 
             // Build up the complete list of any packages to be documented
             Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH
--- a/langtools/test/tools/javac/modules/AnnotationProcessing.java	Wed Aug 10 16:19:09 2016 -0700
+++ b/langtools/test/tools/javac/modules/AnnotationProcessing.java	Thu Aug 11 17:26:12 2016 +0200
@@ -23,6 +23,7 @@
 
 /**
  * @test
+ * @bug 8133884 8162711
  * @summary Verify that annotation processing works.
  * @library /tools/lib
  * @modules
@@ -43,6 +44,7 @@
 import java.util.stream.Collectors;
 
 import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
 import javax.annotation.processing.RoundEnvironment;
 import javax.annotation.processing.SupportedAnnotationTypes;
 import javax.annotation.processing.SupportedOptions;
@@ -53,13 +55,15 @@
 import javax.lang.model.element.ModuleElement.UsesDirective;
 import javax.lang.model.element.PackageElement;
 import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
 import javax.lang.model.type.TypeKind;
 import javax.lang.model.util.ElementFilter;
 import javax.lang.model.util.ElementScanner9;
+import javax.tools.Diagnostic.Kind;
 
 import toolbox.JavacTask;
 import toolbox.Task;
-import toolbox.ToolBox;
+import toolbox.Task.Mode;
 
 public class AnnotationProcessing extends ModuleTestBase {
 
@@ -300,6 +304,76 @@
 
     }
 
+    @Test
+    public void testQualifiedClassForProcessing(Path base) throws Exception {
+        Path moduleSrc = base.resolve("module-src");
+        Path m1 = moduleSrc.resolve("m1");
+        Path m2 = moduleSrc.resolve("m2");
+
+        Path classes = base.resolve("classes");
+
+        Files.createDirectories(classes);
+
+        tb.writeJavaFiles(m1,
+                          "module m1 { }",
+                          "package impl; public class Impl { int m1; }");
+
+        tb.writeJavaFiles(m2,
+                          "module m2 { }",
+                          "package impl; public class Impl { int m2; }");
+
+        new JavacTask(tb)
+            .options("--module-source-path", moduleSrc.toString())
+            .outdir(classes)
+            .files(findJavaFiles(moduleSrc))
+            .run()
+            .writeAll()
+            .getOutput(Task.OutputKind.DIRECT);
+
+        List<String> expected = Arrays.asList("Note: field: m1");
+
+        for (Mode mode : new Mode[] {Mode.API, Mode.CMDLINE}) {
+            List<String> log = new JavacTask(tb, mode)
+                    .options("-processor", QualifiedClassForProcessing.class.getName(),
+                             "--module-path", classes.toString())
+                    .classes("m1/impl.Impl")
+                    .outdir(classes)
+                    .run()
+                    .writeAll()
+                    .getOutputLines(Task.OutputKind.DIRECT);
+
+            if (!expected.equals(log))
+                throw new AssertionError("Unexpected output: " + log);
+        }
+    }
+
+    @SupportedAnnotationTypes("*")
+    public static final class QualifiedClassForProcessing extends AbstractProcessor {
+
+        @Override
+        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+            if (processingEnv.getElementUtils().getModuleElement("m1") == null) {
+                throw new AssertionError("No m1 module found.");
+            }
+
+            Messager messager = processingEnv.getMessager();
+
+            for (TypeElement clazz : ElementFilter.typesIn(roundEnv.getRootElements())) {
+                for (VariableElement field : ElementFilter.fieldsIn(clazz.getEnclosedElements())) {
+                    messager.printMessage(Kind.NOTE, "field: " + field.getSimpleName());
+                }
+            }
+
+            return false;
+        }
+
+        @Override
+        public SourceVersion getSupportedSourceVersion() {
+            return SourceVersion.latest();
+        }
+
+    }
+
     private static void assertNonNull(String msg, Object val) {
         if (val == null) {
             throw new AssertionError(msg);