From 482c10064668d8309873173b1773ca406883fda3 Mon Sep 17 00:00:00 2001 From: Jonathan Gibbons Date: Mon, 12 Feb 2024 19:53:48 +0000 Subject: [PATCH] 8322865: JavaDoc fails on aggregator modules Reviewed-by: hannesw --- .../javadoc/internal/tool/ElementsTable.java | 28 ++++- .../javadoc/internal/tool/JavadocTool.java | 12 +-- .../testModules/TestAggregatorModule.java | 100 ++++++++++++++++++ 3 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 test/langtools/jdk/javadoc/doclet/testModules/TestAggregatorModule.java diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java index 59e5b9ccc04..a531a987f0d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ElementsTable.java @@ -71,7 +71,6 @@ import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; -import jdk.javadoc.doclet.DocletEnvironment; import jdk.javadoc.doclet.DocletEnvironment.ModuleMode; import jdk.javadoc.internal.doclets.toolkit.WorkArounds; @@ -187,7 +186,7 @@ public class ElementsTable { private List classDecList = List.of(); private List classArgList = List.of(); - private com.sun.tools.javac.util.List classTreeList = null; + private com.sun.tools.javac.util.List compilationUnitList = null; private final Set sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE); @@ -352,8 +351,8 @@ public class ElementsTable { initializeIncludedSets(expandedModulePackages); } - ElementsTable classTrees(com.sun.tools.javac.util.List classTrees) { - this.classTreeList = classTrees; + ElementsTable compilationUnits(com.sun.tools.javac.util.List compilationUnits) { + this.compilationUnitList = compilationUnits; return this; } @@ -437,10 +436,29 @@ public class ElementsTable { } }); + // scan any module-info.java files specified on the command line + for (var cu : compilationUnitList) { + loop: + for (var d : cu.defs) { + switch (d.getTag()) { + case IMPORT -> { } + case MODULEDEF -> { + var md = (JCModuleDecl) d; + var mn = md.qualId.toString(); + ModuleSymbol msym = syms.enterModule(names.fromString(mn)); + specifiedModuleElements.add(msym); + } + default -> { + break loop; + } + } + } + } + // all the modules specified on the command line have been scraped // init the module systems this.modules.addExtraAddModules(mlist.toArray(new String[mlist.size()])); - this.modules.initModules(this.classTreeList); + this.modules.initModules(this.compilationUnitList); return this; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java index 2f71422a7d6..8390831b249 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java @@ -150,7 +150,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { return new DocEnvImpl(toolEnv, etable); } - ListBuffer classTrees = new ListBuffer<>(); + ListBuffer compilationUnits = new ListBuffer<>(); try { StandardJavaFileManager fm = toolEnv.fileManager instanceof StandardJavaFileManager sfm @@ -161,7 +161,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { // Parse the files and collect the package names. for (String arg: javaNames) { if (fm != null && arg.endsWith(".java") && isRegularFile(arg)) { - parse(fm.getJavaFileObjects(arg), classTrees, true); + parse(fm.getJavaFileObjects(arg), compilationUnits, true); } else if (isValidPackageName(arg)) { packageNames.add(arg); } else if (arg.endsWith(".java")) { @@ -179,10 +179,10 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { } // Parse file objects provide via the DocumentationTool API - parse(fileObjects, classTrees, true); + parse(fileObjects, compilationUnits, true); etable.packages(packageNames) - .classTrees(classTrees.toList()) + .compilationUnits(compilationUnits.toList()) .scanSpecifiedItems(); // abort, if errors were encountered during modules initialization @@ -192,7 +192,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { // Parse the files in the packages and subpackages to be documented ListBuffer allTrees = new ListBuffer<>(); - allTrees.addAll(classTrees); + allTrees.addAll(compilationUnits); parse(etable.getFilesToParse(), allTrees, false); modules.newRound(); modules.initModules(allTrees.toList()); @@ -209,7 +209,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler { return null; } - etable.setClassDeclList(listClasses(classTrees.toList())); + etable.setClassDeclList(listClasses(compilationUnits.toList())); dcfh.setHandler(dcfh.userCodeHandler); etable.analyze(); diff --git a/test/langtools/jdk/javadoc/doclet/testModules/TestAggregatorModule.java b/test/langtools/jdk/javadoc/doclet/testModules/TestAggregatorModule.java new file mode 100644 index 00000000000..f23364d5b0c --- /dev/null +++ b/test/langtools/jdk/javadoc/doclet/testModules/TestAggregatorModule.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8322865 + * @summary JavaDoc fails on aggregator modules + * @modules jdk.javadoc/jdk.javadoc.internal.api + * jdk.javadoc/jdk.javadoc.internal.tool + * jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + * @library ../../lib /tools/lib + * @build toolbox.ToolBox toolbox.ModuleBuilder javadoc.tester.* + * @run main TestAggregatorModule + */ + +import java.nio.file.Files; +import java.nio.file.Path; + +import javadoc.tester.JavadocTester; +import toolbox.*; + +public class TestAggregatorModule extends JavadocTester { + public static void main(String... args) throws Exception { + new TestAggregatorModule().runTests(); + } + + ToolBox tb = new ToolBox(); + + @Test + public void testSimple_1(Path base) throws Exception { + Path src = base.resolve("src"); + Path api = base.resolve("api"); + + tb.writeJavaFiles(src, + "/** Module m. */ module m { requires java.se; }"); + + javadoc("-d", api.toString(), + "-sourcepath", src.toString(), // override default sourcepath set by JavadocTester + src.resolve("module-info.java").toString()); + checkExit(Exit.OK); + + checkOutput(Output.OUT, false, + "No public"); + checkFiles(true, + "m/module-summary.html"); + } + + /* + * This is a variant of testSimple_1 that uses JavadocTask instead of direct use + * of JavadocTester.javadoc, to avoid setting any value for the source path. + * In other words, test: `javadoc -d api path/to/module-info.java` + */ + @Test + public void testSimple_2(Path base) throws Exception { + Path src = base.resolve("src"); + Path api = base.resolve("api"); + Files.createDirectories(api); + + tb.writeJavaFiles(src, + "/** Module m. */ module m { requires java.se; }"); + + var outputLines = new JavadocTask(tb) + .outdir(api) + .files(src.resolve("module-info.java")) + .run(Task.Expect.SUCCESS) + .writeAll() + .getOutputLines(Task.OutputKind.DIRECT); + + out.println("Checking for error message"); + if (outputLines.stream().anyMatch(l -> l.contains("No public"))) { + throw new Exception("unexpected error message"); + } + + out.println("Checking for generated file"); + if (!Files.exists(api.resolve("m").resolve("module-summary.html"))) { + throw new Exception("expected file not found"); + } + } +}