/* * Copyright (c) 2025, 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 8254622 * @summary Hide superclasses from conditionally exported packages * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool * jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * @build javadoc.tester.* toolbox.ToolBox * @run main TestUnexported */ import java.io.IOException; import java.nio.file.Path; import toolbox.ModuleBuilder; import toolbox.ToolBox; import javadoc.tester.JavadocTester; public class TestUnexported extends JavadocTester { final ToolBox tb; final Path src; public static void main(String... args) throws Exception { var tester = new TestUnexported(); tester.runTests(); } TestUnexported() throws IOException { tb = new ToolBox(); src = Path.of("src"); new ModuleBuilder(tb, "ma") .classes(""" package pa; import pa.internal.*; /** * Class with unexported super types. */ public abstract class A extends InternalClass implements InternalInterface {} """, """ package pa.internal; /** * Conditionally exported class. */ public class InternalClass { /** * Method in internal class. */ public void p() {} } """, """ package pa.internal; /** * Conditionally exported interface. */ public interface InternalInterface { /** * Method in internal interface. */ public void m(); } """) .exports("pa") .exportsTo("pa.internal", "mb") .write(src); new ModuleBuilder(tb, "mb") .classes(""" package pb; import pa.internal.*; /** * Class with conditionally exported super types. */ public abstract class B extends InternalClass implements InternalInterface {} """, """ package pb; import pa.internal.*; /** * Interface with conditionally exported super interface. */ public interface I extends InternalInterface {} """) .requires("ma") .exports("pb") .write(src); } // Types in packages that are exported conditionally are hidden in public API documentation. @Test public void test(Path base) throws Exception { Path outDir = base.resolve("out"); javadoc("-d", outDir.toString(), "--no-platform-links", "--module-source-path", src.toString(), "--show-packages", "exported", "--module", "ma,mb"); checkExit(Exit.OK); checkFiles(false, "ma/pa/internal/InternalClass.html", "ma/pa/internal/InternalInterface.html"); checkOutput("ma/pa/A.html", false, "InternalInterface", "InternalClass"); checkOutput("mb/pb/B.html", false, "InternalInterface", "InternalClass"); checkOutput("mb/pb/I.html", false, "InternalInterface"); checkOrder("ma/pa/A.html", """
java.lang.Object
pa.A
""", """
public abstract class A extends java.lang.Object
""", """

m

void m()
Method in internal interface.
""", """

p

public void p()
Method in internal class.
"""); checkOrder("mb/pb/B.html", """
java.lang.Object
pb.B
""", """
public abstract class B extends java.lang.Object
""", """

m

void m()
Method in internal interface.
""", """

p

public void p()
Method in internal class.
"""); checkOrder("mb/pb/I.html", """
public interface I
""", """

m

void m()
Method in internal interface.
"""); } // Types in packages that are exported conditionally are shown when documenting // all module packages including internal ones. @Test public void testIncluded(Path base) throws Exception { Path outDir = base.resolve("out"); javadoc("-d", outDir.toString(), "--no-platform-links", "--module-source-path", src.toString(), "--show-module-contents", "all", "--show-packages", "all", "--module", "ma,mb"); checkExit(Exit.OK); checkFiles(true, "ma/pa/internal/InternalClass.html", "ma/pa/internal/InternalInterface.html"); checkOutput("ma/pa/A.html", true, "InternalInterface", "InternalClass"); checkOutput("mb/pb/B.html", true, "InternalInterface", "InternalClass"); checkOutput("mb/pb/I.html", true, "InternalInterface"); checkOrder("ma/pa/A.html", """
java.lang.Object
pa.internal.InternalClass
pa.A
""", """
public abstract class A extends InternalClass implements InternalInterface
""", """

Methods inherit\ ed from class InternalClass

p """, """

Methods inh\ erited from interface InternalInterface

m """); checkOrder("mb/pb/B.html", """
java.lang.Object
pa.internal.InternalClass
pb.B
""", """
public abstract class B extends InternalClass implements InternalInterface
""", """

Methods inherit\ ed from class InternalClass

p """, """

Methods inh\ erited from interface InternalInterface

m """); } }