8261079: Fix support for @hidden in classes and interfaces
Reviewed-by: jjg
This commit is contained in:
parent
9c0ec8d848
commit
3210095a17
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets
formats/html
HtmlConfiguration.javaHtmlDocletWriter.javaHtmlLinkFactory.javaMethodWriterImpl.javaPropertyWriterImpl.javaSerializedFormWriterImpl.java
toolkit
test/langtools/jdk/javadoc/doclet/testHiddenTag
@ -265,7 +265,7 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
}
|
||||
docPaths = new DocPaths(utils);
|
||||
setCreateOverview();
|
||||
setTopFile(docEnv);
|
||||
setTopFile();
|
||||
initDocLint(options.doclintOpts(), tagletManager.getAllTagletNames());
|
||||
return true;
|
||||
}
|
||||
@ -277,11 +277,9 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
* "package-summary.html" of the respective package if there is only one
|
||||
* package to document. It will be a class page(first in the sorted order),
|
||||
* if only classes are provided on the command line.
|
||||
*
|
||||
* @param docEnv the doclet environment
|
||||
*/
|
||||
protected void setTopFile(DocletEnvironment docEnv) {
|
||||
if (!checkForDeprecation(docEnv)) {
|
||||
protected void setTopFile() {
|
||||
if (!checkForDeprecation()) {
|
||||
return;
|
||||
}
|
||||
if (options.createOverview()) {
|
||||
@ -313,7 +311,7 @@ public class HtmlConfiguration extends BaseConfiguration {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean checkForDeprecation(DocletEnvironment docEnv) {
|
||||
protected boolean checkForDeprecation() {
|
||||
for (TypeElement te : getIncludedTypeElements()) {
|
||||
if (isGeneratedDoc(te)) {
|
||||
return true;
|
||||
|
@ -313,7 +313,7 @@ public class HtmlDocletWriter {
|
||||
// printed. If no overridden or implementation info needs to be
|
||||
// printed, do not print this section.
|
||||
if ((!intfacs.isEmpty()
|
||||
&& vmt.getImplementedMethods(method).isEmpty() == false)
|
||||
&& !vmt.getImplementedMethods(method).isEmpty())
|
||||
|| overriddenMethod != null) {
|
||||
MethodWriterImpl.addImplementsInfo(this, method, dl);
|
||||
if (overriddenMethod != null) {
|
||||
@ -806,13 +806,6 @@ public class HtmlDocletWriter {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isClassLinkable(TypeElement typeElement) {
|
||||
if (utils.isIncluded(typeElement)) {
|
||||
return configuration.isGeneratedDoc(typeElement);
|
||||
}
|
||||
return configuration.extern.isExternal(typeElement);
|
||||
}
|
||||
|
||||
public DocLink getCrossPackageLink(PackageElement element) {
|
||||
return configuration.extern.getExternalLink(element, pathToRoot,
|
||||
DocPaths.PACKAGE_SUMMARY.getPath());
|
||||
|
@ -105,7 +105,7 @@ public class HtmlLinkFactory extends LinkFactory {
|
||||
|
||||
Content link = new ContentBuilder();
|
||||
if (utils.isIncluded(typeElement)) {
|
||||
if (configuration.isGeneratedDoc(typeElement)) {
|
||||
if (configuration.isGeneratedDoc(typeElement) && !utils.hasHiddenTag(typeElement)) {
|
||||
DocPath filename = getPath(classLinkInfo);
|
||||
if (linkInfo.linkToSelf ||
|
||||
!(docPaths.forName(typeElement)).equals(m_writer.filename)) {
|
||||
|
@ -149,20 +149,22 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
|
||||
utils.isLinkable(holder))) {
|
||||
writer.addInlineComment(method, methodDocTree);
|
||||
} else {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.EXECUTABLE_ELEMENT_COPY,
|
||||
holder, method,
|
||||
utils.isIncluded(holder)
|
||||
? utils.getSimpleName(holder)
|
||||
: utils.getFullyQualifiedName(holder));
|
||||
Content codeLink = HtmlTree.CODE(link);
|
||||
Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel,
|
||||
utils.isClass(holder)
|
||||
? contents.descfrmClassLabel
|
||||
: contents.descfrmInterfaceLabel);
|
||||
descfrmLabel.add(Entity.NO_BREAK_SPACE);
|
||||
descfrmLabel.add(codeLink);
|
||||
methodDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel));
|
||||
if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(method)) {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.EXECUTABLE_ELEMENT_COPY,
|
||||
holder, method,
|
||||
utils.isIncluded(holder)
|
||||
? utils.getSimpleName(holder)
|
||||
: utils.getFullyQualifiedName(holder));
|
||||
Content codeLink = HtmlTree.CODE(link);
|
||||
Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel,
|
||||
utils.isClass(holder)
|
||||
? contents.descfrmClassLabel
|
||||
: contents.descfrmInterfaceLabel);
|
||||
descfrmLabel.add(Entity.NO_BREAK_SPACE);
|
||||
descfrmLabel.add(codeLink);
|
||||
methodDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel));
|
||||
}
|
||||
writer.addInlineComment(method, methodDocTree);
|
||||
}
|
||||
}
|
||||
@ -265,36 +267,37 @@ public class MethodWriterImpl extends AbstractExecutableMemberWriter
|
||||
//is not visible so don't document this.
|
||||
return;
|
||||
}
|
||||
|
||||
if (method != null) {
|
||||
Contents contents = writer.contents;
|
||||
Content label;
|
||||
HtmlLinkInfo.Kind context;
|
||||
if (utils.isAbstract(holder) && utils.isAbstract(method)){
|
||||
//Abstract method is implemented from abstract class,
|
||||
//not overridden
|
||||
label = contents.specifiedByLabel;
|
||||
context = HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY;
|
||||
} else {
|
||||
label = contents.overridesLabel;
|
||||
context = HtmlLinkInfo.Kind.METHOD_OVERRIDES;
|
||||
}
|
||||
dl.add(HtmlTree.DT(label));
|
||||
Content overriddenTypeLink =
|
||||
writer.getLink(new HtmlLinkInfo(writer.configuration, context, overriddenType));
|
||||
Content codeOverriddenTypeLink = HtmlTree.CODE(overriddenTypeLink);
|
||||
Content methlink = writer.getLink(
|
||||
new HtmlLinkInfo(writer.configuration, HtmlLinkInfo.Kind.MEMBER, holder)
|
||||
.where(writer.htmlIds.forMember(method).name())
|
||||
.label(method.getSimpleName()));
|
||||
Content codeMethLink = HtmlTree.CODE(methlink);
|
||||
Content dd = HtmlTree.DD(codeMethLink);
|
||||
dd.add(Entity.NO_BREAK_SPACE);
|
||||
dd.add(contents.inClass);
|
||||
dd.add(Entity.NO_BREAK_SPACE);
|
||||
dd.add(codeOverriddenTypeLink);
|
||||
dl.add(dd);
|
||||
if (utils.hasHiddenTag(holder) || utils.hasHiddenTag(method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Contents contents = writer.contents;
|
||||
Content label;
|
||||
HtmlLinkInfo.Kind context;
|
||||
if (utils.isAbstract(holder) && utils.isAbstract(method)) {
|
||||
//Abstract method is implemented from abstract class,
|
||||
//not overridden
|
||||
label = contents.specifiedByLabel;
|
||||
context = HtmlLinkInfo.Kind.METHOD_SPECIFIED_BY;
|
||||
} else {
|
||||
label = contents.overridesLabel;
|
||||
context = HtmlLinkInfo.Kind.METHOD_OVERRIDES;
|
||||
}
|
||||
dl.add(HtmlTree.DT(label));
|
||||
Content overriddenTypeLink =
|
||||
writer.getLink(new HtmlLinkInfo(writer.configuration, context, overriddenType));
|
||||
Content codeOverriddenTypeLink = HtmlTree.CODE(overriddenTypeLink);
|
||||
Content methlink = writer.getLink(
|
||||
new HtmlLinkInfo(writer.configuration, HtmlLinkInfo.Kind.MEMBER, holder)
|
||||
.where(writer.htmlIds.forMember(method).name())
|
||||
.label(method.getSimpleName()));
|
||||
Content codeMethLink = HtmlTree.CODE(methlink);
|
||||
Content dd = HtmlTree.DD(codeMethLink);
|
||||
dd.add(Entity.NO_BREAK_SPACE);
|
||||
dd.add(contents.inClass);
|
||||
dd.add(Entity.NO_BREAK_SPACE);
|
||||
dd.add(codeOverriddenTypeLink);
|
||||
dl.add(dd);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -111,19 +111,21 @@ public class PropertyWriterImpl extends AbstractMemberWriter
|
||||
(!utils.isPublic(holder) || utils.isLinkable(holder))) {
|
||||
writer.addInlineComment(property, propertyDocTree);
|
||||
} else {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.PROPERTY_COPY,
|
||||
holder, property,
|
||||
utils.isIncluded(holder)
|
||||
? holder.getSimpleName() : holder.getQualifiedName());
|
||||
Content codeLink = HtmlTree.CODE(link);
|
||||
Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel,
|
||||
utils.isClass(holder)
|
||||
? contents.descfrmClassLabel
|
||||
: contents.descfrmInterfaceLabel);
|
||||
descfrmLabel.add(Entity.NO_BREAK_SPACE);
|
||||
descfrmLabel.add(codeLink);
|
||||
propertyDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel));
|
||||
if (!utils.hasHiddenTag(holder) && !utils.hasHiddenTag(property)) {
|
||||
Content link =
|
||||
writer.getDocLink(HtmlLinkInfo.Kind.PROPERTY_COPY,
|
||||
holder, property,
|
||||
utils.isIncluded(holder)
|
||||
? holder.getSimpleName() : holder.getQualifiedName());
|
||||
Content codeLink = HtmlTree.CODE(link);
|
||||
Content descfrmLabel = HtmlTree.SPAN(HtmlStyle.descfrmTypeLabel,
|
||||
utils.isClass(holder)
|
||||
? contents.descfrmClassLabel
|
||||
: contents.descfrmInterfaceLabel);
|
||||
descfrmLabel.add(Entity.NO_BREAK_SPACE);
|
||||
descfrmLabel.add(codeLink);
|
||||
propertyDocTree.add(HtmlTree.DIV(HtmlStyle.block, descfrmLabel));
|
||||
}
|
||||
writer.addInlineComment(property, propertyDocTree);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2021, 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
|
||||
@ -137,7 +137,8 @@ public class SerializedFormWriterImpl extends SubWriterHolderWriter
|
||||
* @return true if the class, that is being processed, is generated and is visible.
|
||||
*/
|
||||
public boolean isVisibleClass(TypeElement typeElement) {
|
||||
return visibleClasses.contains(typeElement) && configuration.isGeneratedDoc(typeElement);
|
||||
return visibleClasses.contains(typeElement) && configuration.isGeneratedDoc(typeElement)
|
||||
&& !utils.hasHiddenTag(typeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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,6 +409,9 @@ public abstract class MemberSummaryBuilder extends AbstractMemberBuilder {
|
||||
if (inheritedClass == typeElement) {
|
||||
continue;
|
||||
}
|
||||
if (utils.hasHiddenTag(inheritedClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<Element> members = inheritedMembersFromMap.stream()
|
||||
.filter(e -> utils.getEnclosingTypeElement(e) == inheritedClass)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2021, 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
|
||||
@ -552,10 +552,8 @@ public class SerializedFormBuilder extends AbstractBuilder {
|
||||
if (utils.isSerializable(te)) {
|
||||
if (utils.hasDocCommentTree(te) && !utils.getSerialTrees(te).isEmpty()) {
|
||||
return serialDocInclude(utils, te);
|
||||
} else if (utils.isPublic(te) || utils.isProtected(te)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
return utils.isPublic(te) || utils.isProtected(te);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -609,7 +609,8 @@ public class Utils {
|
||||
}
|
||||
|
||||
public boolean isUndocumentedEnclosure(TypeElement enclosingTypeElement) {
|
||||
return (isPackagePrivate(enclosingTypeElement) || isPrivate(enclosingTypeElement))
|
||||
return (isPackagePrivate(enclosingTypeElement) || isPrivate(enclosingTypeElement)
|
||||
|| hasHiddenTag(enclosingTypeElement))
|
||||
&& !isLinkable(enclosingTypeElement);
|
||||
}
|
||||
|
||||
@ -1157,10 +1158,11 @@ public class Utils {
|
||||
*/
|
||||
public boolean isLinkable(TypeElement typeElem) {
|
||||
return
|
||||
(typeElem != null &&
|
||||
(isIncluded(typeElem) && configuration.isGeneratedDoc(typeElem))) ||
|
||||
typeElem != null &&
|
||||
((isIncluded(typeElem) && configuration.isGeneratedDoc(typeElem) &&
|
||||
!hasHiddenTag(typeElem)) ||
|
||||
(configuration.extern.isExternal(typeElem) &&
|
||||
(isPublic(typeElem) || isProtected(typeElem)));
|
||||
(isPublic(typeElem) || isProtected(typeElem))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1183,7 +1185,7 @@ public class Utils {
|
||||
return isLinkable((TypeElement) elem); // defer to existing behavior
|
||||
}
|
||||
|
||||
if (isIncluded(elem)) {
|
||||
if (isIncluded(elem) && !hasHiddenTag(elem)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1553,16 +1555,17 @@ public class Utils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the element is included, contains @hidden tag,
|
||||
* 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
|
||||
*/
|
||||
public boolean hasHiddenTag(Element e) {
|
||||
// prevent needless tests on elements which are not included
|
||||
// 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.
|
||||
if (!isIncluded(e)) {
|
||||
return false;
|
||||
return hasBlockTagUnchecked(e, HIDDEN);
|
||||
}
|
||||
if (options.javafx() &&
|
||||
hasBlockTag(e, DocTree.Kind.UNKNOWN_BLOCK_TAG, "treatAsPrivate")) {
|
||||
@ -2265,12 +2268,14 @@ public class Utils {
|
||||
}
|
||||
|
||||
public TypeElement getEnclosingTypeElement(Element e) {
|
||||
if (e.getKind() == ElementKind.PACKAGE)
|
||||
if (isPackage(e) || isModule(e)) {
|
||||
return null;
|
||||
}
|
||||
Element encl = e.getEnclosingElement();
|
||||
ElementKind kind = encl.getKind();
|
||||
if (kind == ElementKind.PACKAGE)
|
||||
if (isPackage(encl)) {
|
||||
return null;
|
||||
}
|
||||
ElementKind kind = encl.getKind();
|
||||
while (!(kind.isClass() || kind.isInterface())) {
|
||||
encl = encl.getEnclosingElement();
|
||||
kind = encl.getKind();
|
||||
@ -2591,7 +2596,10 @@ public class Utils {
|
||||
}
|
||||
|
||||
public List<? extends DocTree> getBlockTags(Element element) {
|
||||
DocCommentTree dcTree = getDocCommentTree(element);
|
||||
return getBlockTags(getDocCommentTree(element));
|
||||
}
|
||||
|
||||
public List<? extends DocTree> getBlockTags(DocCommentTree dcTree) {
|
||||
return dcTree == null ? Collections.emptyList() : dcTree.getBlockTags();
|
||||
}
|
||||
|
||||
@ -2641,14 +2649,26 @@ public class Utils {
|
||||
public boolean hasBlockTag(Element element, DocTree.Kind kind, final String tagName) {
|
||||
if (hasDocCommentTree(element)) {
|
||||
CommentHelper ch = getCommentHelper(element);
|
||||
String tname = tagName != null && tagName.startsWith("@")
|
||||
? tagName.substring(1)
|
||||
: tagName;
|
||||
for (DocTree dt : getBlockTags(element, kind)) {
|
||||
for (DocTree dt : getBlockTags(ch.dcTree)) {
|
||||
if (dt.getKind() == kind && (tagName == null || ch.getTagName(dt).equals(tagName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests whether an element's doc comment contains a block tag without caching it or
|
||||
* running doclint on it. This is done by using getDocCommentInfo(Element) to retrieve
|
||||
* the doc comment info.
|
||||
*/
|
||||
boolean hasBlockTagUnchecked(Element element, DocTree.Kind kind) {
|
||||
DocCommentInfo dcInfo = getDocCommentInfo(element);
|
||||
if (dcInfo != null && dcInfo.dcTree != null) {
|
||||
for (DocTree dt : getBlockTags(dcInfo.dcTree)) {
|
||||
if (dt.getKind() == kind) {
|
||||
if (tname == null || ch.getTagName(dt).equals(tname)) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2701,7 +2721,7 @@ public class Utils {
|
||||
|
||||
/**
|
||||
* Retrieves the doc comments for a given element.
|
||||
* @param element
|
||||
* @param element the element
|
||||
* @return DocCommentTree for the Element
|
||||
*/
|
||||
public DocCommentTree getDocCommentTree0(Element element) {
|
||||
@ -2759,7 +2779,7 @@ public class Utils {
|
||||
|
||||
private DocCommentInfo getDocCommentInfo0(Element element) {
|
||||
// prevent nasty things downstream with overview element
|
||||
if (element.getKind() != ElementKind.OTHER) {
|
||||
if (!isOverviewElement(element)) {
|
||||
TreePath path = getTreePath(element);
|
||||
if (path != null) {
|
||||
DocCommentTree docCommentTree = docTrees.getDocCommentTree(path);
|
||||
|
@ -126,7 +126,7 @@ public class VisibleMemberTable {
|
||||
private Map<ExecutableElement, PropertyMembers> propertyMap = new HashMap<>();
|
||||
|
||||
// Keeps track of method overrides
|
||||
Map<ExecutableElement, OverridingMethodInfo> overriddenMethodTable
|
||||
Map<ExecutableElement, OverriddenMethodInfo> overriddenMethodTable
|
||||
= new LinkedHashMap<>();
|
||||
|
||||
protected VisibleMemberTable(TypeElement typeElement, BaseConfiguration configuration,
|
||||
@ -240,10 +240,10 @@ public class VisibleMemberTable {
|
||||
public ExecutableElement getOverriddenMethod(ExecutableElement e) {
|
||||
ensureInitialized();
|
||||
|
||||
OverridingMethodInfo found = overriddenMethodTable.get(e);
|
||||
OverriddenMethodInfo found = overriddenMethodTable.get(e);
|
||||
if (found != null
|
||||
&& (found.simpleOverride || utils.isUndocumentedEnclosure(utils.getEnclosingTypeElement(e)))) {
|
||||
return found.overrider;
|
||||
return found.overridden;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -256,9 +256,9 @@ public class VisibleMemberTable {
|
||||
public ExecutableElement getSimplyOverriddenMethod(ExecutableElement e) {
|
||||
ensureInitialized();
|
||||
|
||||
OverridingMethodInfo found = overriddenMethodTable.get(e);
|
||||
OverriddenMethodInfo found = overriddenMethodTable.get(e);
|
||||
if (found != null && found.simpleOverride) {
|
||||
return found.overrider;
|
||||
return found.overridden;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -475,9 +475,9 @@ public class VisibleMemberTable {
|
||||
for (VisibleMemberTable pvmt : parents) {
|
||||
// Merge the lineage overrides into local table
|
||||
pvmt.overriddenMethodTable.entrySet().forEach(e -> {
|
||||
OverridingMethodInfo p = e.getValue();
|
||||
OverriddenMethodInfo p = e.getValue();
|
||||
if (!p.simpleOverride) { // consider only real overrides
|
||||
List<ExecutableElement> list = overriddenByTable.computeIfAbsent(p.overrider,
|
||||
List<ExecutableElement> list = overriddenByTable.computeIfAbsent(p.overridden,
|
||||
k -> new ArrayList<>());
|
||||
list.add(e.getKey());
|
||||
}
|
||||
@ -486,19 +486,19 @@ public class VisibleMemberTable {
|
||||
}
|
||||
|
||||
// Filter out inherited methods that:
|
||||
// a. cannot override (private instance members)
|
||||
// a. cannot be overridden (private instance members)
|
||||
// b. are overridden and should not be visible in this type
|
||||
// c. are hidden in the type being considered
|
||||
// see allowInheritedMethods, which performs the above actions
|
||||
// see allowInheritedMethod, which performs the above actions
|
||||
List<Element> list = inheritedMethods.stream()
|
||||
.filter(e -> allowInheritedMethods((ExecutableElement) e, overriddenByTable, lmt))
|
||||
.filter(e -> allowInheritedMethod((ExecutableElement) e, overriddenByTable, lmt))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Filter out the local methods, that do not override or simply
|
||||
// overrides a super method, or those methods that should not
|
||||
// be visible.
|
||||
Predicate<ExecutableElement> isVisible = m -> {
|
||||
OverridingMethodInfo p = overriddenMethodTable.getOrDefault(m, null);
|
||||
OverriddenMethodInfo p = overriddenMethodTable.getOrDefault(m, null);
|
||||
return p == null || !p.simpleOverride;
|
||||
};
|
||||
List<Element> localList = lmt.getOrderedMembers(Kind.METHODS)
|
||||
@ -529,9 +529,9 @@ public class VisibleMemberTable {
|
||||
return utils.isInterface(enclosing);
|
||||
}
|
||||
|
||||
boolean allowInheritedMethods(ExecutableElement inheritedMethod,
|
||||
Map<ExecutableElement, List<ExecutableElement>> inheritedOverriddenTable,
|
||||
LocalMemberTable lmt) {
|
||||
boolean allowInheritedMethod(ExecutableElement inheritedMethod,
|
||||
Map<ExecutableElement, List<ExecutableElement>> overriddenByTable,
|
||||
LocalMemberTable lmt) {
|
||||
if (!isInherited(inheritedMethod))
|
||||
return false;
|
||||
|
||||
@ -552,7 +552,7 @@ public class VisibleMemberTable {
|
||||
// in favor of concrete overriding methods, for instance those that have
|
||||
// API documentation and are not abstract OR default methods.
|
||||
if (inInterface) {
|
||||
List<ExecutableElement> list = inheritedOverriddenTable.get(inheritedMethod);
|
||||
List<ExecutableElement> list = overriddenByTable.get(inheritedMethod);
|
||||
if (list != null) {
|
||||
boolean found = list.stream()
|
||||
.anyMatch(this::isEnclosureInterface);
|
||||
@ -586,16 +586,19 @@ public class VisibleMemberTable {
|
||||
TypeElement encl = utils.getEnclosingTypeElement(inheritedMethod);
|
||||
if (utils.isUndocumentedEnclosure(encl)) {
|
||||
overriddenMethodTable.computeIfAbsent(lMethod,
|
||||
l -> new OverridingMethodInfo(inheritedMethod, false));
|
||||
l -> new OverriddenMethodInfo(inheritedMethod, false));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Even with --override-methods=summary we want to include details of
|
||||
// overriding method if something noteworthy has been added or changed.
|
||||
// overriding method if something noteworthy has been added or changed
|
||||
// either in the local overriding method or an in-between overriding method
|
||||
// (as evidenced by an entry in overriddenByTable).
|
||||
boolean simpleOverride = utils.isSimpleOverride(lMethod)
|
||||
&& !overridingSignatureChanged(lMethod, inheritedMethod);
|
||||
&& !overridingSignatureChanged(lMethod, inheritedMethod)
|
||||
&& !overriddenByTable.containsKey(inheritedMethod);
|
||||
overriddenMethodTable.computeIfAbsent(lMethod,
|
||||
l -> new OverridingMethodInfo(inheritedMethod, simpleOverride));
|
||||
l -> new OverriddenMethodInfo(inheritedMethod, simpleOverride));
|
||||
return simpleOverride;
|
||||
}
|
||||
}
|
||||
@ -1031,21 +1034,21 @@ public class VisibleMemberTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple container to encapsulate an overriding method
|
||||
* A simple container to encapsulate an overridden method
|
||||
* and the type of override.
|
||||
*/
|
||||
static class OverridingMethodInfo {
|
||||
final ExecutableElement overrider;
|
||||
static class OverriddenMethodInfo {
|
||||
final ExecutableElement overridden;
|
||||
final boolean simpleOverride;
|
||||
|
||||
public OverridingMethodInfo(ExecutableElement overrider, boolean simpleOverride) {
|
||||
this.overrider = overrider;
|
||||
public OverriddenMethodInfo(ExecutableElement overridden, boolean simpleOverride) {
|
||||
this.overridden = overridden;
|
||||
this.simpleOverride = simpleOverride;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "OverridingMethodInfo[" + overrider + ",simple:" + simpleOverride + "]";
|
||||
return "OverriddenMethodInfo[" + overridden + ",simple:" + simpleOverride + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, 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
|
||||
* @bug 8073100 8182765 8196202 8261079
|
||||
* @summary ensure the hidden tag works as intended
|
||||
* @library ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
@ -63,9 +63,8 @@ public class TestHiddenTag extends JavadocTester {
|
||||
n pkg1">A.VisibleInnerExtendsInvisibleInner</a></code></dd>""");
|
||||
|
||||
checkOutput("pkg1/A.html", false,
|
||||
"<h3 id=\"inVisibleField\">",
|
||||
"""
|
||||
<h3><span id="inVisibleMethod()">""");
|
||||
"invisibleField",
|
||||
"invisibleMethod()");
|
||||
|
||||
checkOutput("pkg1/A.VisibleInner.html", true,
|
||||
"""
|
||||
@ -82,8 +81,8 @@ public class TestHiddenTag extends JavadocTester {
|
||||
|
||||
checkOutput("pkg1/A.VisibleInner.html", false,
|
||||
"../pkg1/A.VisibleInner.html#VisibleInner()",
|
||||
"<a id=\"inVisibleField\">",
|
||||
"<a id=\"inVisibleMethod()\">");
|
||||
"invisibleField",
|
||||
"invisibleMethod()");
|
||||
|
||||
checkOutput("pkg1/A.VisibleInnerExtendsInvisibleInner.html", true,
|
||||
"""
|
||||
@ -100,12 +99,63 @@ public class TestHiddenTag extends JavadocTester {
|
||||
"invisibleMethod",
|
||||
"A.InvisibleInner");
|
||||
|
||||
checkOutput("pkg1/Intf.html", true,
|
||||
"""
|
||||
<section class="detail" id="visibleDefaultMethod()">""",
|
||||
"""
|
||||
<section class="detail" id="visibleInterfaceMethod()">""",
|
||||
"""
|
||||
<dt>All Known Implementing Classes:</dt>
|
||||
<dd><code><a href="Child.html" title="class in pkg1">Child</a></code></dd>
|
||||
</dl>""");
|
||||
|
||||
checkOutput("pkg1/Intf.html", false,
|
||||
"InvisibleParent",
|
||||
"invisibleDefaultMethod",
|
||||
"invisibleInterfaceMethod");
|
||||
|
||||
checkOutput("pkg1/Child.html", true,
|
||||
"""
|
||||
<a href="InvisibleParent.VisibleInner.html" class="type-name-link" title="class \
|
||||
in pkg1">InvisibleParent.VisibleInner</a>""",
|
||||
"""
|
||||
<a href="#visibleField" class="member-name-link">visibleField</a>""",
|
||||
"""
|
||||
<a href="#invisibleInterfaceMethod()" class="member-name-link">invisibleInterfaceMethod</a>""",
|
||||
"""
|
||||
<a href="#visibleInterfaceMethod()" class="member-name-link">visibleInterfaceMethod</a>""",
|
||||
"""
|
||||
<a href="#visibleMethod(pkg1.InvisibleParent)" class="member-name-link">visibleMethod</a>""",
|
||||
"""
|
||||
<a href="Intf.html#visibleDefaultMethod()">visibleDefaultMethod</a>""",
|
||||
// Invisible return or parameter types must not be linked
|
||||
"""
|
||||
<span class="return-type">pkg1.InvisibleParent</span>""",
|
||||
"""
|
||||
<span class="parameters">(pkg1.InvisibleParent<? extends pkg1.InvisibleParent> p)</span>""");
|
||||
|
||||
checkOutput("pkg1/Child.html", false,
|
||||
"InvisibleParent.InvisibleInner",
|
||||
"invisibleField",
|
||||
"invisibleMethod",
|
||||
"invisibleDefaultMethod");
|
||||
|
||||
checkOutput("pkg1/InvisibleParent.VisibleInner.html", true,
|
||||
"""
|
||||
<dt>Enclosing class:</dt>
|
||||
<dd>pkg1.InvisibleParent<T extends pkg1.InvisibleParent></dd>
|
||||
</dl>""");
|
||||
|
||||
checkOutput("pkg1/package-summary.html", false, "A.InvisibleInner");
|
||||
|
||||
checkOutput("pkg1/package-tree.html", false, "A.InvisibleInner");
|
||||
|
||||
checkOutput("pkg1/package-tree.html", false, "InvisibleParent.html");
|
||||
|
||||
checkFiles(false,
|
||||
"pkg1/A.InvisibleInner.html",
|
||||
"pkg1/A.InvisibleInnerExtendsVisibleInner.html");
|
||||
"pkg1/A.InvisibleInnerExtendsVisibleInner.html",
|
||||
"pkg1/InvisibleParent.html",
|
||||
"pkg1/InvisibleParent.InvisibleInner.html");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2021, 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
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
package pkg1;
|
||||
|
||||
import pkg2.UndocumentedParent;
|
||||
|
||||
/**
|
||||
* A visible class, extending invisible classes.
|
||||
*/
|
||||
public class Child extends UndocumentedParent<Child> {
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
package pkg1;
|
||||
|
||||
/**
|
||||
* An visible interface
|
||||
*/
|
||||
public interface Intf {
|
||||
|
||||
/**
|
||||
* A visible interface method.
|
||||
*/
|
||||
void visibleInterfaceMethod();
|
||||
|
||||
/**
|
||||
* An invisible interface method.
|
||||
* @hidden
|
||||
*/
|
||||
void invisibleInterfaceMethod();
|
||||
|
||||
/**
|
||||
* A visible default method.
|
||||
*/
|
||||
default void visibleDefaultMethod() {}
|
||||
|
||||
/**
|
||||
* An invisible default method.
|
||||
* @hidden
|
||||
*/
|
||||
default void invisibleDefaultMethod() {}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
package pkg1;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class InvisibleParent<T extends InvisibleParent> implements Intf {
|
||||
|
||||
@Override
|
||||
public void visibleInterfaceMethod() {}
|
||||
|
||||
/**
|
||||
* An invisible method made visible in an implementing class.
|
||||
*/
|
||||
@Override
|
||||
public void invisibleInterfaceMethod() {}
|
||||
|
||||
/**
|
||||
* A visible inner class.
|
||||
*/
|
||||
public static class VisibleInner {
|
||||
/**
|
||||
* An invisible constructor
|
||||
* @hidden invisible
|
||||
*/
|
||||
public VisibleInner() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* An invisible inner class.
|
||||
* @hidden
|
||||
*/
|
||||
public static class InvisibleInner {}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 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.
|
||||
*/
|
||||
|
||||
package pkg2;
|
||||
|
||||
import pkg1.InvisibleParent;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
* @param <T>
|
||||
*/
|
||||
public class UndocumentedParent<T extends InvisibleParent> extends InvisibleParent<T> {
|
||||
|
||||
/**
|
||||
* A visible field.
|
||||
*/
|
||||
public InvisibleParent visibleField;
|
||||
|
||||
/**
|
||||
* An invisible field.
|
||||
* @hidden
|
||||
*/
|
||||
public InvisibleParent invisibleField;
|
||||
|
||||
/**
|
||||
* A visible method with an invisible parameter type.
|
||||
*/
|
||||
public void visibleMethod(InvisibleParent<? extends InvisibleParent> p) {}
|
||||
|
||||
/**
|
||||
* An invisible method.
|
||||
* @hidden
|
||||
*/
|
||||
public void invisibleMethod() {}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user