8133884: javac moduleName/className and moduleName/packageName options

8162711: javax.lang.model.util.Elements.getModuleElement returns null during annotation processing on class files

Adding a test for annotation processing for <module-name>/<class-name>; ensuring the <module-name> module is in the module graph.

Reviewed-by: jjg
This commit is contained in:
Jan Lahoda 2016-08-11 17:26:12 +02:00
parent b620ed93e6
commit ec9ca2997f
5 changed files with 98 additions and 7 deletions

View file

@ -147,7 +147,9 @@ public class Modules extends JCTree.Visitor {
private final String addReadsOpt; private final String addReadsOpt;
private Map<ModuleSymbol, Set<RequiresDirective>> addReads; private Map<ModuleSymbol, Set<RequiresDirective>> addReads;
private final String addModsOpt; private final String addModsOpt;
private final Set<String> extraAddMods = new HashSet<>();
private final String limitModsOpt; private final String limitModsOpt;
private final Set<String> extraLimitMods = new HashSet<>();
private Set<ModuleSymbol> rootModules = null; private Set<ModuleSymbol> rootModules = null;
@ -195,8 +197,16 @@ public class Modules extends JCTree.Visitor {
System.err.println(msg); 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; boolean inInitModules;
public void initModules(List<JCCompilationUnit> trees, Collection<String> extraAddMods, Collection<String> extraLimitMods) { public void initModules(List<JCCompilationUnit> trees) {
Assert.check(!inInitModules); Assert.check(!inInitModules);
try { try {
inInitModules = true; inInitModules = true;
@ -205,7 +215,7 @@ public class Modules extends JCTree.Visitor {
Assert.checkNull(rootModules); Assert.checkNull(rootModules);
Assert.checkNull(allModules); Assert.checkNull(allModules);
this.rootModules = modules; this.rootModules = modules;
setupAllModules(extraAddMods, extraLimitMods); //initialize the module graph setupAllModules(); //initialize the module graph
Assert.checkNonNull(allModules); Assert.checkNonNull(allModules);
inInitModules = false; inInitModules = false;
}, null); }, null);
@ -862,7 +872,7 @@ public class Modules extends JCTree.Visitor {
return allModules; return allModules;
} }
private void setupAllModules(Collection<String> extraAddMods, Collection<String> extraLimitMods) { private void setupAllModules() {
Assert.checkNonNull(rootModules); Assert.checkNonNull(rootModules);
Assert.checkNull(allModules); Assert.checkNull(allModules);

View file

@ -900,6 +900,13 @@ public class JavaCompiler {
try { try {
initProcessAnnotations(processors); 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 // These method calls must be chained to avoid memory leaks
processAnnotations( processAnnotations(
enterTrees( enterTrees(
@ -1010,7 +1017,7 @@ public class JavaCompiler {
} }
public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) { public List<JCCompilationUnit> initModules(List<JCCompilationUnit> roots) {
modules.initModules(roots, Collections.emptySet(), Collections.emptySet()); modules.initModules(roots);
if (roots.isEmpty()) { if (roots.isEmpty()) {
enterDone = true; enterDone = true;
} }

View file

@ -187,7 +187,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
// Parse file objects provide via the DocumentationTool API // Parse file objects provide via the DocumentationTool API
parse(fileObjects, classTrees, true); 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 // Build up the complete list of any packages to be documented
Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH

View file

@ -190,7 +190,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
// Parse file objects provide via the DocumentationTool API // Parse file objects provide via the DocumentationTool API
parse(fileObjects, classTrees, true); 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 // Build up the complete list of any packages to be documented
Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH Location location = modules.multiModuleMode ? StandardLocation.MODULE_SOURCE_PATH

View file

@ -23,6 +23,7 @@
/** /**
* @test * @test
* @bug 8133884 8162711
* @summary Verify that annotation processing works. * @summary Verify that annotation processing works.
* @library /tools/lib * @library /tools/lib
* @modules * @modules
@ -43,6 +44,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions; import javax.annotation.processing.SupportedOptions;
@ -53,13 +55,15 @@ import javax.lang.model.element.ModuleElement.ProvidesDirective;
import javax.lang.model.element.ModuleElement.UsesDirective; import javax.lang.model.element.ModuleElement.UsesDirective;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeKind;
import javax.lang.model.util.ElementFilter; import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.ElementScanner9; import javax.lang.model.util.ElementScanner9;
import javax.tools.Diagnostic.Kind;
import toolbox.JavacTask; import toolbox.JavacTask;
import toolbox.Task; import toolbox.Task;
import toolbox.ToolBox; import toolbox.Task.Mode;
public class AnnotationProcessing extends ModuleTestBase { public class AnnotationProcessing extends ModuleTestBase {
@ -300,6 +304,76 @@ public class AnnotationProcessing extends ModuleTestBase {
} }
@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) { private static void assertNonNull(String msg, Object val) {
if (val == null) { if (val == null) {
throw new AssertionError(msg); throw new AssertionError(msg);