8322865: JavaDoc fails on aggregator modules

Reviewed-by: hannesw
This commit is contained in:
Jonathan Gibbons 2024-02-12 19:53:48 +00:00
parent b3e0587ea0
commit 482c100646
3 changed files with 129 additions and 11 deletions

View File

@ -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<JCClassDecl> classDecList = List.of();
private List<String> classArgList = List.of();
private com.sun.tools.javac.util.List<JCCompilationUnit> classTreeList = null;
private com.sun.tools.javac.util.List<JCCompilationUnit> compilationUnitList = null;
private final Set<JavaFileObject.Kind> sourceKinds = EnumSet.of(JavaFileObject.Kind.SOURCE);
@ -352,8 +351,8 @@ public class ElementsTable {
initializeIncludedSets(expandedModulePackages);
}
ElementsTable classTrees(com.sun.tools.javac.util.List<JCCompilationUnit> classTrees) {
this.classTreeList = classTrees;
ElementsTable compilationUnits(com.sun.tools.javac.util.List<JCCompilationUnit> 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;
}

View File

@ -150,7 +150,7 @@ public class JavadocTool extends com.sun.tools.javac.main.JavaCompiler {
return new DocEnvImpl(toolEnv, etable);
}
ListBuffer<JCCompilationUnit> classTrees = new ListBuffer<>();
ListBuffer<JCCompilationUnit> 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<JCCompilationUnit> 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();

View File

@ -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");
}
}
}