# HG changeset patch # User jjg # Date 1539022499 25200 # Node ID 50dc6dd40e6a1186c5ae61b9ad62fda5fb1c8b84 # Parent ba67866e9c12de0eecfc04ecc3b80e13906dcd5f 8211407: Bad links to non-existent entries on serialized-form page Reviewed-by: jlahoda diff -r ba67866e9c12 -r 50dc6dd40e6a src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Mon Oct 08 07:18:40 2018 -0400 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/JavadocTool.java Mon Oct 08 11:14:59 2018 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, 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 @@ -34,6 +34,8 @@ import java.util.Map; import java.util.Set; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; @@ -41,6 +43,7 @@ import com.sun.tools.javac.code.DeferredCompletionFailureHandler; import com.sun.tools.javac.code.Symbol.Completer; import com.sun.tools.javac.code.Symbol.CompletionFailure; +import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCClassDecl; @@ -213,6 +216,17 @@ dcfh.setHandler(dcfh.userCodeHandler); etable.analyze(); + + // Ensure that package-info is read for all included packages + for (Element e : etable.getIncludedElements()) { + if (e.getKind() == ElementKind.PACKAGE) { + PackageSymbol packge = (PackageSymbol) e; + if (packge.package_info != null) { + packge.package_info.complete(); + } + } + } + } catch (CompletionFailure cf) { throw new ToolException(ABNORMAL, cf.getMessage(), cf); } catch (Abort abort) { diff -r ba67866e9c12 -r 50dc6dd40e6a test/langtools/jdk/javadoc/doclet/testSerialTag/TestSerialTag.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testSerialTag/TestSerialTag.java Mon Oct 08 11:14:59 2018 -0700 @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2018, 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 8207214 + * @summary Test package-level at-serial tags + * @library /tools/lib ../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build JavadocTester toolbox.ToolBox + * @run main TestSerialTag + */ + +import java.io.IOException; +import java.nio.file.Path; + +import toolbox.ToolBox; + +public class TestSerialTag extends JavadocTester { + public static void main(String... args) throws Exception { + TestSerialTag tester = new TestSerialTag(); + tester.runTests(m -> new Object[] { Path.of(m.getName()) }); + } + + private final ToolBox tb; + + TestSerialTag() { + tb = new ToolBox(); + } + + @Test + public void testCombo(Path base) throws IOException { + boolean[] moduleValues = { false, true }; + String[] tagValues = { "", "@serial include", "@serial exclude" }; + for (boolean module : moduleValues ) { + for (String tag : tagValues ) { + String name = (module ? "module-" : "") + + (tag.isEmpty() ? "default" : tag.replace("@serial ", "")); + Path dir = base.resolve(name); + test(dir, module, tag); + } + } + + } + + void test(Path base, boolean module, String tag) throws IOException { + out.println("Test: module:" + module + ", tag:" + tag); + + Path srcDir = generateSource(base, module, tag); + + Path outDir = base.resolve("out"); + if (module) { + javadoc("-d", outDir.toString(), + "--module-source-path", srcDir.toString(), + "--module", "m"); + } else { + javadoc("-d", outDir.toString(), + "-sourcepath", srcDir.toString(), + "p", "q"); + } + checkExit(Exit.OK); + + boolean expectLink = !tag.equals("@serial exclude"); + checkSeeSerializedForm(module, expectLink); + } + + /** + * Generates source for a test case. + * Two classes are generated, in two different packages. + * One package has a variable at-serial tag to test; + * The other package is a control and always has no special tag. + * + * @param base the working directory for the test case + * @param module whether or not to enclose the packages in a module + * @param tag the at-serial tag to be tested + * @return the directory in which the source was created + */ + Path generateSource(Path base, boolean module, String tag) throws IOException { + Path srcDir = base.resolve("src"); + + Path dir; + if (module) { + dir = srcDir.resolve("m"); + tb.writeJavaFiles(dir, + "module m { exports p; exports q; }"); + } else { + dir = srcDir; + } + + tb.writeJavaFiles(dir, + "/** This is package p;\n * " + tag + "\n */\n" + + "package p;", + "/** This is class p.C1;\n */\n" + + "package p; public class C1 implements java.io.Serializable { }", + "/** This is package q;\n */\n" + + "package q;", + "/** This is class q.C2;\n */\n" + + "package q; public class C2 implements java.io.Serializable { }" + ); + + return srcDir; + } + + /** + * Checks the link to the serialized form page, + * and whether classes are documented on that page. + * + * @param module whether or not the output is module-oriented + * @param b whether or not class p.C1 should be documented as serializable + */ + void checkSeeSerializedForm(boolean module, boolean b) { + String prefix = module ? "m/" : ""; + + checkOutput(prefix + "p/C1.html", b, + "serialized-form.html"); + checkOutput("serialized-form.html", b, + "C1"); + + checkOutput(prefix + "q/C2.html", true, + "serialized-form.html"); + checkOutput("serialized-form.html", true, + "C2"); + } +} +