mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-28 03:00:41 +00:00
8254622: Hide superclasses from conditionally exported packages
Reviewed-by: kcr, liach
This commit is contained in:
parent
ed756b9700
commit
5d97608970
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -28,8 +28,6 @@ package jdk.internal.event;
|
||||
/**
|
||||
* Base class for events, to be subclassed in order to define events and their
|
||||
* fields.
|
||||
*
|
||||
* @hidden
|
||||
*/
|
||||
public abstract class Event {
|
||||
/**
|
||||
|
||||
@ -157,9 +157,6 @@ public class VectorSupport {
|
||||
|
||||
public static class VectorSpecies<E> {}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public static class VectorPayload {
|
||||
private final Object payload; // array of primitives
|
||||
|
||||
@ -172,26 +169,18 @@ public class VectorSupport {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public static class Vector<E> extends VectorPayload {
|
||||
public Vector(Object payload) {
|
||||
super(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
public static class VectorShuffle<E> extends VectorPayload {
|
||||
public VectorShuffle(Object payload) {
|
||||
super(payload);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
||||
public static class VectorMask<E> extends VectorPayload {
|
||||
public VectorMask(Object payload) {
|
||||
super(payload);
|
||||
|
||||
@ -266,15 +266,12 @@ public abstract class AbstractMemberWriter {
|
||||
var inheritedMembersFromMap = asSortedSet(visibleMemberTable.getAllVisibleMembers(kind));
|
||||
|
||||
for (TypeElement inheritedClass : visibleMemberTable.getVisibleTypeElements()) {
|
||||
if (!(utils.isPublic(inheritedClass) || utils.isLinkable(inheritedClass))) {
|
||||
if (!utils.isVisible(inheritedClass)) {
|
||||
continue;
|
||||
}
|
||||
if (Objects.equals(inheritedClass, typeElement)) {
|
||||
continue;
|
||||
}
|
||||
if (utils.hasHiddenTag(inheritedClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<? extends Element> members = inheritedMembersFromMap.stream()
|
||||
.filter(e -> Objects.equals(utils.getEnclosingTypeElement(e), inheritedClass))
|
||||
|
||||
@ -128,22 +128,20 @@ public abstract class AbstractTreeWriter extends HtmlDocletWriter {
|
||||
if (interfaces.size() > (utils.isPlainInterface(typeElement) ? 1 : 0)) {
|
||||
boolean isFirst = true;
|
||||
for (TypeElement intf : interfaces) {
|
||||
if (parent != intf) {
|
||||
if (utils.isPublic(intf) || utils.isLinkable(intf)) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (utils.isPlainInterface(typeElement)) {
|
||||
content.add(" (");
|
||||
content.add(contents.also);
|
||||
content.add(" extends ");
|
||||
} else {
|
||||
content.add(" (implements ");
|
||||
}
|
||||
if (parent != intf && utils.isVisible(intf)) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
if (utils.isPlainInterface(typeElement)) {
|
||||
content.add(" (");
|
||||
content.add(contents.also);
|
||||
content.add(" extends ");
|
||||
} else {
|
||||
content.add(", ");
|
||||
content.add(" (implements ");
|
||||
}
|
||||
addPreQualifiedClassLink(HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS, intf, content);
|
||||
} else {
|
||||
content.add(", ");
|
||||
}
|
||||
addPreQualifiedClassLink(HtmlLinkInfo.Kind.SHOW_TYPE_PARAMS, intf, content);
|
||||
}
|
||||
}
|
||||
if (!isFirst) {
|
||||
|
||||
@ -111,7 +111,7 @@ public class AllClassesIndexWriter extends HtmlDocletWriter {
|
||||
boolean noDeprecated = options.noDeprecated();
|
||||
Set<TypeElement> includedTypes = configuration.getIncludedTypeElements();
|
||||
for (TypeElement typeElement : includedTypes) {
|
||||
if (utils.hasHiddenTag(typeElement) || !utils.isCoreClass(typeElement)) {
|
||||
if (utils.isHidden(typeElement) || !utils.isCoreClass(typeElement)) {
|
||||
continue;
|
||||
}
|
||||
if (noDeprecated
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 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
|
||||
@ -409,7 +409,7 @@ public class HtmlDoclet extends AbstractDoclet {
|
||||
protected void generateClassFiles(SortedSet<TypeElement> typeElems, ClassTree classTree)
|
||||
throws DocletException {
|
||||
for (TypeElement te : typeElems) {
|
||||
if (utils.hasHiddenTag(te) ||
|
||||
if (utils.isHidden(te) ||
|
||||
!(configuration.isGeneratedDoc(te) && utils.isIncluded(te))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ public class HtmlLinkFactory {
|
||||
|
||||
Content link = new ContentBuilder();
|
||||
if (utils.isIncluded(typeElement)) {
|
||||
if (configuration.isGeneratedDoc(typeElement) && !utils.hasHiddenTag(typeElement)) {
|
||||
if (configuration.isGeneratedDoc(typeElement) && !utils.isHidden(typeElement)) {
|
||||
DocPath fileName = getPath(linkInfo);
|
||||
if (linkInfo.linkToSelf() || typeElement != m_writer.getCurrentTypeElement()) {
|
||||
link.add(m_writer.links.createLink(
|
||||
|
||||
@ -238,12 +238,10 @@ public class MethodWriter extends AbstractExecutableMemberWriter {
|
||||
protected void addComments(TypeMirror holderType, ExecutableElement method, Content methodContent) {
|
||||
TypeElement holder = utils.asTypeElement(holderType);
|
||||
if (!utils.getFullBody(method).isEmpty()) {
|
||||
if (holder.equals(typeElement) ||
|
||||
!(utils.isPublic(holder) ||
|
||||
utils.isLinkable(holder))) {
|
||||
if (holder.equals(typeElement) || !utils.isVisible(holder)) {
|
||||
writer.addInlineComment(method, methodContent);
|
||||
} else {
|
||||
if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(method)) {
|
||||
if (!utils.isHidden(holder) && !utils.isHidden(method)) {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.PLAIN,
|
||||
holder, method,
|
||||
@ -349,7 +347,7 @@ public class MethodWriter extends AbstractExecutableMemberWriter {
|
||||
}
|
||||
Utils utils = writer.utils;
|
||||
TypeElement holder = utils.getEnclosingTypeElement(method);
|
||||
if (!(utils.isPublic(holder) || utils.isLinkable(holder))) {
|
||||
if (!utils.isVisible(holder) || utils.isHidden(method)) {
|
||||
//This is an implementation detail that should not be documented.
|
||||
return;
|
||||
}
|
||||
@ -358,9 +356,6 @@ public class MethodWriter extends AbstractExecutableMemberWriter {
|
||||
//is not visible so don't document this.
|
||||
return;
|
||||
}
|
||||
if (utils.hasHiddenTag(holder) || utils.hasHiddenTag(method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Contents contents = writer.contents;
|
||||
Content label;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -45,7 +45,6 @@ import jdk.javadoc.internal.html.Content;
|
||||
import jdk.javadoc.internal.html.ContentBuilder;
|
||||
import jdk.javadoc.internal.html.Entity;
|
||||
import jdk.javadoc.internal.html.HtmlAttr;
|
||||
import jdk.javadoc.internal.html.HtmlTag;
|
||||
import jdk.javadoc.internal.html.HtmlTree;
|
||||
import jdk.javadoc.internal.html.Text;
|
||||
|
||||
@ -404,7 +403,7 @@ public class Navigation {
|
||||
: Text.of(pkg.getQualifiedName()));
|
||||
// Breadcrumb navigation displays nested classes as separate links.
|
||||
// Enclosing classes may be undocumented, in which case we just display the class name.
|
||||
case TypeElement type -> (configuration.isGeneratedDoc(type) && !configuration.utils.hasHiddenTag(type))
|
||||
case TypeElement type -> (configuration.isGeneratedDoc(type) && !configuration.utils.isHidden(type))
|
||||
? links.createLink(pathToRoot.resolve(
|
||||
docPaths.forClass(type)), type.getSimpleName().toString())
|
||||
: HtmlTree.SPAN(Text.of(type.getSimpleName().toString()));
|
||||
|
||||
@ -199,11 +199,10 @@ public class PropertyWriter extends AbstractMemberWriter {
|
||||
protected void addComments(ExecutableElement property, Content propertyContent) {
|
||||
TypeElement holder = (TypeElement)property.getEnclosingElement();
|
||||
if (!utils.getFullBody(property).isEmpty()) {
|
||||
if (holder.equals(typeElement) ||
|
||||
(!utils.isPublic(holder) || utils.isLinkable(holder))) {
|
||||
if (holder.equals(typeElement) || !utils.isVisible(holder)) {
|
||||
writer.addInlineComment(property, propertyContent);
|
||||
} else {
|
||||
if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(property)) {
|
||||
if (!utils.isHidden(holder) && !utils.isHidden(property)) {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.PLAIN,
|
||||
holder, property,
|
||||
|
||||
@ -608,7 +608,7 @@ public class SerializedFormWriter extends SubWriterHolderWriter {
|
||||
*/
|
||||
public boolean isVisibleClass(TypeElement typeElement) {
|
||||
return visibleClasses.contains(typeElement) && configuration.isGeneratedDoc(typeElement)
|
||||
&& !utils.hasHiddenTag(typeElement);
|
||||
&& !utils.isHidden(typeElement);
|
||||
}
|
||||
|
||||
Content getClassHeader(TypeElement typeElement) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2020, 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
|
||||
@ -162,7 +162,7 @@ public class Signatures {
|
||||
boolean isFirst = true;
|
||||
for (TypeMirror type : interfaces) {
|
||||
TypeElement tDoc = utils.asTypeElement(type);
|
||||
if (!(utils.isPublic(tDoc) || utils.isLinkable(tDoc))) {
|
||||
if (!utils.isVisible(tDoc)) {
|
||||
continue;
|
||||
}
|
||||
if (isFirst) {
|
||||
|
||||
@ -248,8 +248,7 @@ public class LinkTaglet extends BaseTaglet {
|
||||
containing = utils.getEnclosingTypeElement(overriddenMethod);
|
||||
}
|
||||
}
|
||||
if (refSignature.trim().startsWith("#") &&
|
||||
! (utils.isPublic(containing) || utils.isLinkable(containing))) {
|
||||
if (refSignature.trim().startsWith("#") && !utils.isVisible(containing)) {
|
||||
// Since the link is relative and the holder is not even being
|
||||
// documented, this must be an inherited link. Redirect it.
|
||||
// The current class either overrides the referenced member or
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -233,7 +233,7 @@ public class ClassTree {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (utils.hasHiddenTag(te)) {
|
||||
if (utils.isHidden(te)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 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
|
||||
@ -246,7 +246,7 @@ public abstract class IndexBuilder {
|
||||
* Should this element be added to the index?
|
||||
*/
|
||||
private boolean shouldIndex(Element element) {
|
||||
if (utils.hasHiddenTag(element)) {
|
||||
if (utils.isHidden(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -384,7 +384,7 @@ public class Utils {
|
||||
|
||||
public boolean isUndocumentedEnclosure(TypeElement enclosingTypeElement) {
|
||||
return (isPackagePrivate(enclosingTypeElement) || isPrivate(enclosingTypeElement)
|
||||
|| hasHiddenTag(enclosingTypeElement))
|
||||
|| isHidden(enclosingTypeElement))
|
||||
&& !isLinkable(enclosingTypeElement);
|
||||
}
|
||||
|
||||
@ -786,7 +786,7 @@ public class Utils {
|
||||
if (!visited.add(e)) {
|
||||
continue; // seen it before
|
||||
}
|
||||
if (isPublic(e) || isLinkable(e)) {
|
||||
if (isVisible(e)) {
|
||||
results.add(t);
|
||||
}
|
||||
addSuperInterfaces(t, results, visited);
|
||||
@ -849,7 +849,7 @@ public class Utils {
|
||||
return
|
||||
typeElem != null &&
|
||||
((isIncluded(typeElem) && configuration.isGeneratedDoc(typeElem) &&
|
||||
!hasHiddenTag(typeElem)) ||
|
||||
!isHidden(typeElem)) ||
|
||||
(configuration.extern.isExternal(typeElem) &&
|
||||
(isPublic(typeElem) || isProtected(typeElem))));
|
||||
}
|
||||
@ -874,7 +874,7 @@ public class Utils {
|
||||
return isLinkable((TypeElement) elem); // defer to existing behavior
|
||||
}
|
||||
|
||||
if (isIncluded(elem) && !hasHiddenTag(elem)) {
|
||||
if (isIncluded(elem) && !isHidden(elem)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1006,7 +1006,7 @@ public class Utils {
|
||||
t = supertypes.get(0); // if non-empty, the first element is always the superclass
|
||||
var te = asTypeElement(t);
|
||||
assert alreadySeen.add(te); // it should be the first time we see `te`
|
||||
if (!hasHiddenTag(te) && (isPublic(te) || isLinkable(te))) {
|
||||
if (isVisible(te)) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
@ -1237,16 +1237,32 @@ public class Utils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the element is included or selected, contains @hidden tag,
|
||||
* or if javafx flag is present and element contains @treatAsPrivate
|
||||
* tag.
|
||||
* @param e the queried element
|
||||
* @return true if it exists, false otherwise
|
||||
* Returns {@code true} if the type element is visible. This means that it is not hidden,
|
||||
* and is either public or linkable (either internally or externally).
|
||||
*
|
||||
* @param typeElement the type element
|
||||
* @return {@code true} if the type element is visible
|
||||
*/
|
||||
public boolean hasHiddenTag(Element e) {
|
||||
// Non-included elements may still be visible via "transclusion" from undocumented enclosures,
|
||||
// but we don't want to run doclint on them, possibly causing warnings or errors.
|
||||
public boolean isVisible(TypeElement typeElement) {
|
||||
return !isHidden(typeElement) && (isPublic(typeElement) || isLinkable(typeElement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the element is hidden. An element is hidden if it contains a
|
||||
* @hidden tag, or if javafx flag is present and the element contains a
|
||||
* @treatAsPrivate tag, or the element is a type and is not included and
|
||||
* not exported unconditionally by its module.
|
||||
* @param e the queried element
|
||||
* @return true if element is hidden, false otherwise
|
||||
*/
|
||||
public boolean isHidden(Element e) {
|
||||
// Non-included elements may still be visible through the type hierarchy
|
||||
if (!isIncluded(e)) {
|
||||
// Treat types that are not included and not unconditionally exported as hidden
|
||||
if (isClassOrInterface(e) && isUnexportedType((TypeElement) e)) {
|
||||
return true;
|
||||
}
|
||||
// Use unchecked method to avoid running doclint, causing warnings or errors.
|
||||
return hasBlockTagUnchecked(e, HIDDEN);
|
||||
}
|
||||
if (options.javafx() &&
|
||||
@ -1256,6 +1272,21 @@ public class Utils {
|
||||
return hasBlockTag(e, DocTree.Kind.HIDDEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@return true if typeElement is in a package that is not unconditionally exported
|
||||
* by its module}
|
||||
* @param typeElement a type element
|
||||
*/
|
||||
private boolean isUnexportedType(TypeElement typeElement) {
|
||||
var pkg = elementUtils.getPackageOf(typeElement);
|
||||
var mdl = elementUtils.getModuleOf(typeElement);
|
||||
return mdl != null && !mdl.isUnnamed()
|
||||
&& mdl.getDirectives().stream()
|
||||
.filter(d -> d.getKind() == ModuleElement.DirectiveKind.EXPORTS)
|
||||
.map(d -> (ModuleElement.ExportsDirective) d)
|
||||
.noneMatch(e -> e.getPackage().equals(pkg) && e.getTargetModules() == null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the passed method does not change the specification it
|
||||
* inherited.
|
||||
@ -1293,14 +1324,14 @@ public class Utils {
|
||||
new TreeSet<>(comparators.generalPurposeComparator());
|
||||
if (!javafx) {
|
||||
for (TypeElement te : classlist) {
|
||||
if (!hasHiddenTag(te)) {
|
||||
if (!isHidden(te)) {
|
||||
filteredOutClasses.add(te);
|
||||
}
|
||||
}
|
||||
return filteredOutClasses;
|
||||
}
|
||||
for (TypeElement e : classlist) {
|
||||
if (isPrivate(e) || isPackagePrivate(e) || hasHiddenTag(e)) {
|
||||
if (isPrivate(e) || isPackagePrivate(e) || isHidden(e)) {
|
||||
continue;
|
||||
}
|
||||
filteredOutClasses.add(e);
|
||||
@ -2831,7 +2862,7 @@ public class Utils {
|
||||
next = null; // end-of-hierarchy
|
||||
break;
|
||||
}
|
||||
if (isPlainInterface(peek) && !isPublic(peek) && !isLinkable(peek)) {
|
||||
if (isPlainInterface(peek) && !isVisible(peek)) {
|
||||
// we don't consider such interfaces directly, but may consider
|
||||
// their supertypes (subject to this check for each of them)
|
||||
continue;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -502,7 +502,7 @@ public class VisibleMemberTable {
|
||||
|
||||
private boolean mustDocument(Element e) {
|
||||
// these checks are ordered in a particular way to avoid parsing unless absolutely necessary
|
||||
return utils.shouldDocument(e) && !utils.hasHiddenTag(e);
|
||||
return utils.shouldDocument(e) && !utils.isHidden(e);
|
||||
}
|
||||
|
||||
private boolean allowInheritedMembers(Element e, Kind kind, LocalMemberTable lmt) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8073100 8182765 8196202 8261079 8261976
|
||||
* @bug 8073100 8182765 8196202 8261079 8261976 8254622
|
||||
* @summary ensure the hidden tag works as intended
|
||||
* @library ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
@ -139,7 +139,8 @@ public class TestHiddenTag extends JavadocTester {
|
||||
"InvisibleParent.InvisibleInner",
|
||||
"invisibleField",
|
||||
"invisibleMethod",
|
||||
"invisibleDefaultMethod");
|
||||
"invisibleDefaultMethod",
|
||||
"InvisibleInterface");
|
||||
|
||||
checkOutput("pkg1/InvisibleParent.VisibleInner.html", true,
|
||||
"""
|
||||
@ -151,12 +152,13 @@ public class TestHiddenTag extends JavadocTester {
|
||||
|
||||
checkOutput("pkg1/package-tree.html", false, "A.InvisibleInner");
|
||||
|
||||
checkOutput("pkg1/package-tree.html", false, "InvisibleParent.html");
|
||||
checkOutput("pkg1/package-tree.html", false, "InvisibleParent.html", "InvisibleInterface");
|
||||
|
||||
checkFiles(false,
|
||||
"pkg1/A.InvisibleInner.html",
|
||||
"pkg1/A.InvisibleInnerExtendsVisibleInner.html",
|
||||
"pkg1/InvisibleParent.html",
|
||||
"pkg1/InvisibleParent.InvisibleInner.html");
|
||||
"pkg1/InvisibleParent.InvisibleInner.html",
|
||||
"pkg1/InvisibleParent.InvisibleInterface.html");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
@ -27,7 +27,10 @@ import pkg2.UndocumentedParent;
|
||||
|
||||
/**
|
||||
* A visible class, extending invisible classes.
|
||||
*
|
||||
* @see #invisibleInterfaceDefaultMethod()
|
||||
* @see #invisibleInterfaceInterfaceMethod()
|
||||
*/
|
||||
public class Child extends UndocumentedParent<Child> {
|
||||
public class Child extends UndocumentedParent<Child> implements InvisibleParent.InvisibleInterface {
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2021, 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
|
||||
@ -55,4 +55,20 @@ public abstract class InvisibleParent<T extends InvisibleParent> implements Intf
|
||||
*/
|
||||
public static class InvisibleInner {}
|
||||
|
||||
/**
|
||||
* An invisible interface.
|
||||
* @hidden
|
||||
*/
|
||||
public static interface InvisibleInterface {
|
||||
/**
|
||||
* Default method in invisible interface.
|
||||
*/
|
||||
default void invisibleInterfaceDefaultMethod() {}
|
||||
|
||||
/**
|
||||
* Interface method in invisible interface.
|
||||
*/
|
||||
void invisibleInterfaceInterfaceMethod();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* 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
|
||||
* @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", """
|
||||
<div class="inheritance" title="Inheritance Tree">java.lang.Object
|
||||
<div class="inheritance">pa.A</div>
|
||||
""",
|
||||
"""
|
||||
<div class="type-signature"><span class="modifiers">public abstract class </spa\
|
||||
n><span class="element-name type-name-label">A</span>
|
||||
<span class="extends-implements">extends java.lang.Object</span></div>
|
||||
""",
|
||||
"""
|
||||
<section class="detail" id="m()">
|
||||
<h3>m</h3>
|
||||
<div class="horizontal-scroll">
|
||||
<div class="member-signature"><span class="return-type">void</span> <span \
|
||||
class="element-name">m</span>()</div>
|
||||
<div class="block">Method in internal interface.</div>
|
||||
</div>
|
||||
</section>
|
||||
""",
|
||||
"""
|
||||
<section class="detail" id="p()">
|
||||
<h3>p</h3>
|
||||
<div class="horizontal-scroll">
|
||||
<div class="member-signature"><span class="modifiers">public</span> <span \
|
||||
class="return-type">void</span> <span class="element-name">p</span>()</div>
|
||||
<div class="block">Method in internal class.</div>
|
||||
</div>
|
||||
</section>
|
||||
""");
|
||||
|
||||
checkOrder("mb/pb/B.html", """
|
||||
<div class="inheritance" title="Inheritance Tree">java.lang.Object
|
||||
<div class="inheritance">pb.B</div>
|
||||
""",
|
||||
"""
|
||||
<div class="type-signature"><span class="modifiers">public abstract class </spa\
|
||||
n><span class="element-name type-name-label">B</span>
|
||||
<span class="extends-implements">extends java.lang.Object</span></div>
|
||||
""",
|
||||
"""
|
||||
<section class="detail" id="m()">
|
||||
<h3>m</h3>
|
||||
<div class="horizontal-scroll">
|
||||
<div class="member-signature"><span class="return-type">void</span> <span \
|
||||
class="element-name">m</span>()</div>
|
||||
<div class="block">Method in internal interface.</div>
|
||||
</div>
|
||||
</section>
|
||||
""",
|
||||
"""
|
||||
<section class="detail" id="p()">
|
||||
<h3>p</h3>
|
||||
<div class="horizontal-scroll">
|
||||
<div class="member-signature"><span class="modifiers">public</span> <span \
|
||||
class="return-type">void</span> <span class="element-name">p</span>()</div>
|
||||
<div class="block">Method in internal class.</div>
|
||||
</div>
|
||||
</section>
|
||||
""");
|
||||
|
||||
checkOrder("mb/pb/I.html", """
|
||||
<div class="type-signature"><span class="modifiers">public interface </span><sp\
|
||||
an class="element-name type-name-label">I</span></div>
|
||||
""",
|
||||
"""
|
||||
<section class="detail" id="m()">
|
||||
<h3>m</h3>
|
||||
<div class="horizontal-scroll">
|
||||
<div class="member-signature"><span class="return-type">void</span> <span \
|
||||
class="element-name">m</span>()</div>
|
||||
<div class="block">Method in internal interface.</div>
|
||||
</div>
|
||||
</section>
|
||||
""");
|
||||
}
|
||||
|
||||
// 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",
|
||||
"""
|
||||
<div class="inheritance" title="Inheritance Tree">java.lang.Object
|
||||
<div class="inheritance"><a href="internal/InternalClass.html" title="class in \
|
||||
pa.internal">pa.internal.InternalClass</a>
|
||||
<div class="inheritance">pa.A</div>
|
||||
""",
|
||||
"""
|
||||
<div class="type-signature"><span class="modifiers">public abstract class </spa\
|
||||
n><span class="element-name type-name-label">A</span>
|
||||
<span class="extends-implements">extends <a href="internal/InternalClass.html" \
|
||||
title="class in pa.internal">InternalClass</a>
|
||||
implements <a href="internal/InternalInterface.html" title="interface in pa.int\
|
||||
ernal">InternalInterface</a></span></div>
|
||||
""",
|
||||
"""
|
||||
<h3 id="methods-inherited-from-class-pa.internal.InternalClass">Methods inherit\
|
||||
ed from class <a href="internal/InternalClass.html#method-summary" title="\
|
||||
class in pa.internal">InternalClass</a></h3>
|
||||
<code><a href="internal/InternalClass.html#p()" title="p()">p</a></code></div>
|
||||
""",
|
||||
"""
|
||||
<h3 id="methods-inherited-from-class-pa.internal.InternalInterface">Methods inh\
|
||||
erited from interface <a href="internal/InternalInterface.html#method-summ\
|
||||
ary" title="interface in pa.internal">InternalInterface</a></h3>
|
||||
<code><a href="internal/InternalInterface.html#m()" title="m()">m</a></code></div>
|
||||
""");
|
||||
|
||||
checkOrder("mb/pb/B.html",
|
||||
"""
|
||||
<div class="inheritance" title="Inheritance Tree">java.lang.Object
|
||||
<div class="inheritance"><a href="../../ma/pa/internal/InternalClass.html" titl\
|
||||
e="class in pa.internal">pa.internal.InternalClass</a>
|
||||
<div class="inheritance">pb.B</div>
|
||||
""",
|
||||
"""
|
||||
<div class="type-signature"><span class="modifiers">public abstract class </spa\
|
||||
n><span class="element-name type-name-label">B</span>
|
||||
<span class="extends-implements">extends <a href="../../ma/pa/internal/Internal\
|
||||
Class.html" title="class in pa.internal">InternalClass</a>
|
||||
implements <a href="../../ma/pa/internal/InternalInterface.html" title="interfa\
|
||||
ce in pa.internal">InternalInterface</a></span></div>
|
||||
""",
|
||||
"""
|
||||
<h3 id="methods-inherited-from-class-pa.internal.InternalClass">Methods inherit\
|
||||
ed from class <a href="../../ma/pa/internal/InternalClass.html#method-summ\
|
||||
ary" title="class in pa.internal">InternalClass</a></h3>
|
||||
<code><a href="../../ma/pa/internal/InternalClass.html#p()" title="p()">p</a></code></div>
|
||||
""",
|
||||
"""
|
||||
<h3 id="methods-inherited-from-class-pa.internal.InternalInterface">Methods inh\
|
||||
erited from interface <a href="../../ma/pa/internal/InternalInterface.html\
|
||||
#method-summary" title="interface in pa.internal">InternalInterface</a></h3>
|
||||
<code><a href="../../ma/pa/internal/InternalInterface.html#m()" title="m()">m</a></code></div>
|
||||
""");
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user