8324342: Doclet should default @since for a nested class to that of its enclosing class
Reviewed-by: prappo, hannesw
This commit is contained in:
parent
235ba9a702
commit
6ee8407758
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -29,10 +29,13 @@ import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.NestingKind;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
|
||||
import com.sun.source.doctree.BlockTagTree;
|
||||
import com.sun.source.doctree.DocTree;
|
||||
@ -100,6 +103,7 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
* @param tagName the name of this tag
|
||||
* @param header the header to output
|
||||
* @param locations the possible locations that this tag can appear in
|
||||
* @param enabled whether this tag is enabled
|
||||
*/
|
||||
private SimpleTaglet(HtmlConfiguration config, String tagName, String header, Set<Taglet.Location> locations, boolean enabled) {
|
||||
super(config, tagName, false, locations);
|
||||
@ -113,6 +117,7 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
* @param tagKind the kind of this tag
|
||||
* @param header the header to output
|
||||
* @param locations the possible locations that this tag can appear in
|
||||
* @param enabled whether this tag is enabled
|
||||
*/
|
||||
protected SimpleTaglet(HtmlConfiguration config, DocTree.Kind tagKind, String header, Set<Taglet.Location> locations, boolean enabled) {
|
||||
super(config, tagKind, false, locations);
|
||||
@ -120,6 +125,37 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code SimpleTaglet} that will look for tags on enclosing type elements
|
||||
* if there are no relevant tags on a nested (member) type element.
|
||||
*
|
||||
* @param tagKind the kind of this tag
|
||||
* @param header the header to output
|
||||
* @param locations the possible locations that this tag can appear in
|
||||
* @param enabled whether this tag is enabled
|
||||
*/
|
||||
static SimpleTaglet createWithDefaultForNested(HtmlConfiguration config, DocTree.Kind tagKind, String header, Set<Taglet.Location> locations, boolean enabled) {
|
||||
return new SimpleTaglet(config, tagKind, header, locations, enabled) {
|
||||
@Override
|
||||
protected List<? extends BlockTagTree> getDefaultBlockTags(Element e, Predicate<? super BlockTagTree> accepts) {
|
||||
while (isNestedType(e)) {
|
||||
e = e.getEnclosingElement();
|
||||
var tags = utils.getBlockTags(e, accepts);
|
||||
if (!tags.isEmpty()) {
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
|
||||
return List.of();
|
||||
}
|
||||
|
||||
private boolean isNestedType(Element e) {
|
||||
return e.getKind().isDeclaredType()
|
||||
&& ((TypeElement) e).getNestingKind() == NestingKind.MEMBER;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Output inherit(Element dst, Element src, DocTree tag, boolean isFirstSentence) {
|
||||
assert dst.getKind() == ElementKind.METHOD;
|
||||
@ -153,8 +189,8 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
|
||||
/**
|
||||
* Returns whether this taglet accepts a {@code BlockTagTree} node.
|
||||
* The taglet accepts a tree node if it has the same kind, and
|
||||
* if the kind is {@code UNKNOWN_BLOCK_TAG} the same tag name.
|
||||
* The taglet accepts a tree node if it has the same kind, or
|
||||
* if the kind is {@code UNKNOWN_BLOCK_TAG} with the same tag name.
|
||||
*
|
||||
* @param tree the tree node
|
||||
* @return {@code true} if this taglet accepts this tree node
|
||||
@ -168,7 +204,7 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
record Documentation(DocTree tag, List<? extends DocTree> description, ExecutableElement method) { }
|
||||
|
||||
private Optional<Documentation> extractFirst(ExecutableElement m) {
|
||||
List<? extends DocTree> tags = utils.getBlockTags(m, this::accepts);
|
||||
List<? extends DocTree> tags = getBlockTags(m);
|
||||
if (tags.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
@ -179,13 +215,25 @@ public class SimpleTaglet extends BaseTaglet implements InheritableTaglet {
|
||||
@Override
|
||||
public Content getAllBlockTagOutput(Element holder, TagletWriter tagletWriter) {
|
||||
this.tagletWriter = tagletWriter;
|
||||
List<? extends DocTree> tags = utils.getBlockTags(holder, this::accepts);
|
||||
List<? extends DocTree> tags = getBlockTags(holder);
|
||||
if (header == null || tags.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return simpleBlockTagOutput(holder, tags, header);
|
||||
}
|
||||
|
||||
private List<? extends BlockTagTree> getBlockTags(Element e) {
|
||||
var tags = utils.getBlockTags(e, this::accepts);
|
||||
if (tags.isEmpty()) {
|
||||
tags = getDefaultBlockTags(e, this::accepts);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
protected List<? extends BlockTagTree> getDefaultBlockTags(Element e, Predicate<? super BlockTagTree> accepts) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output for a series of simple tags.
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 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
|
||||
@ -590,13 +590,13 @@ public class TagletManager {
|
||||
addStandardTaglet(new ReturnTaglet(config));
|
||||
addStandardTaglet(new ThrowsTaglet(config), EXCEPTION);
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(config, SINCE, resources.getText("doclet.Since"),
|
||||
SimpleTaglet.createWithDefaultForNested(config, SINCE, resources.getText("doclet.Since"),
|
||||
EnumSet.allOf(Location.class), !nosince));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(config, VERSION, resources.getText("doclet.Version"),
|
||||
SimpleTaglet.createWithDefaultForNested(config, VERSION, resources.getText("doclet.Version"),
|
||||
EnumSet.of(Location.OVERVIEW, Location.MODULE, Location.PACKAGE, Location.TYPE), showversion));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(config, AUTHOR, resources.getText("doclet.Author"),
|
||||
SimpleTaglet.createWithDefaultForNested(config, AUTHOR, resources.getText("doclet.Author"),
|
||||
EnumSet.of(Location.OVERVIEW, Location.MODULE, Location.PACKAGE, Location.TYPE), showauthor));
|
||||
addStandardTaglet(
|
||||
new SimpleTaglet(config, SERIAL_DATA, resources.getText("doclet.SerialData"),
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
.\" Copyright (c) 1994, 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
|
||||
@ -110,8 +110,8 @@ also recommended to check the generated output with any appropriate
|
||||
conformance and other checking tools.
|
||||
.PP
|
||||
For more details on the conformance requirements for HTML5 documents,
|
||||
see \f[B]Conformance requirements\f[R]
|
||||
[https://www.w3.org/TR/html5/infrastructure.html#conformance-requirements]
|
||||
see \f[B]Conformance requirements for authors\f[R]
|
||||
[https://html.spec.whatwg.org/multipage/introduction.html#conformance-requirements-for-authors]
|
||||
in the HTML5 Specification.
|
||||
For more details on security issues related to web pages, see the
|
||||
\f[B]Open Web Application Security Project (OWASP)\f[R]
|
||||
@ -489,7 +489,8 @@ Allow JavaScript in documentation comments, and options whose value is
|
||||
\f[I]html-code\f[R].
|
||||
.TP
|
||||
\f[V]-author\f[R]
|
||||
Includes the \f[V]\[at]author\f[R] text in the generated docs.
|
||||
Includes the text of any \f[V]author\f[R] tags in the generated
|
||||
documentation.
|
||||
.TP
|
||||
\f[V]-bottom\f[R] \f[I]html-code\f[R]
|
||||
Specifies the text to be placed at the bottom of each generated page.
|
||||
@ -512,18 +513,16 @@ javadoc -charset \[dq]iso-8859-1\[dq] mypackage
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
This command inserts the following line in the head of every generated
|
||||
page:
|
||||
This command inserts the following line, containing a
|
||||
\f[B]\f[VB]meta\f[B] element\f[R]
|
||||
[https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element]
|
||||
in the head of every generated page:
|
||||
.IP
|
||||
.nf
|
||||
\f[CB]
|
||||
<meta http-equiv=\[dq]Content-Type\[dq] content=\[dq]text/html; charset=ISO-8859-1\[dq]>
|
||||
\f[R]
|
||||
.fi
|
||||
.PP
|
||||
The \f[V]meta\f[R] tag is described in the \f[B]HTML standard (4197265
|
||||
and 4137321), HTML Document Representation\f[R]
|
||||
[http://www.w3.org/TR/REC-html40/charset.html#h-5.2.2].
|
||||
.RE
|
||||
.TP
|
||||
\f[V]-d\f[R] \f[I]directory\f[R]
|
||||
@ -723,8 +722,8 @@ documentation shares the same file system.
|
||||
In all cases, and on all operating systems, use a slash as the
|
||||
separator, whether the URL is absolute or relative, and
|
||||
\f[V]https:\f[R], \f[V]http:\f[R], or \f[V]file:\f[R] as specified in
|
||||
the \f[B]URL Memo: Uniform Resource Locators\f[R]
|
||||
[http://www.ietf.org/rfc/rfc1738.txt].
|
||||
the \f[B]RFC 1738: Uniform Resource Locators (URL)\f[R]
|
||||
[https://www.rfc-editor.org/info/rfc1738].
|
||||
.IP
|
||||
.nf
|
||||
\f[CB]
|
||||
@ -950,8 +949,8 @@ is used.
|
||||
.RE
|
||||
.TP
|
||||
\f[V]-nosince\f[R]
|
||||
Omits from the generated documents the \f[V]Since\f[R] sections
|
||||
associated with the \f[V]\[at]since\f[R] tags.
|
||||
Omits from the generated documentation the \f[V]Since\f[R] sections
|
||||
derived from any \f[V]since\f[R] tags.
|
||||
.TP
|
||||
\f[V]-notimestamp\f[R]
|
||||
Suppresses the time stamp, which is hidden in an HTML comment in the
|
||||
@ -1181,10 +1180,11 @@ To access the generated Use page, go to the class or package and click
|
||||
the \f[B]USE\f[R] link in the navigation bar.
|
||||
.TP
|
||||
\f[V]-version\f[R]
|
||||
Includes the version text in the generated docs.
|
||||
Includes the text of any \f[V]version\f[R] tags in the generated
|
||||
documentation.
|
||||
This text is omitted by default.
|
||||
To find out what version of the \f[V]javadoc\f[R] tool you are using,
|
||||
use the \f[V]--version\f[R] option (with two hyphens).
|
||||
Note: To find out what version of the \f[V]javadoc\f[R] tool you are
|
||||
using, use the \f[V]--version\f[R] option (with two hyphens).
|
||||
.TP
|
||||
\f[V]-windowtitle\f[R] \f[I]title\f[R]
|
||||
Specifies the title to be placed in the HTML \f[V]<title>\f[R] tag.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8202947 8239804
|
||||
* @bug 8202947 8239804 8324342
|
||||
* @summary test the at-author tag, and corresponding option
|
||||
* @library /tools/lib ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
@ -129,4 +129,104 @@ public class TestAuthor extends JavadocTester {
|
||||
<dd>anonymous</dd>
|
||||
</dl>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorDefault(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @author J. Duke
|
||||
*/
|
||||
public class C {
|
||||
/** Class Nested, with no explicit at-author. */
|
||||
public class Nested { }
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-author",
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke</dd>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorDefault_Multiple(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @author J. Duke
|
||||
* @author A. N. Other
|
||||
*/
|
||||
public class C {
|
||||
/** Class Nested, with no explicit at-author. */
|
||||
public class Nested { }
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-author",
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke, A. N. Other</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke, A. N. Other</dd>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthorDefault_Nested(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @author J. Duke
|
||||
* @author A. N. Other
|
||||
*/
|
||||
public class C {
|
||||
public class Nested1 {
|
||||
/** Class Nested, with no explicit at-author. */
|
||||
public class Nested { }
|
||||
}
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-author",
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke, A. N. Other</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested1.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Author:</dt>
|
||||
<dd>J. Duke, A. N. Other</dd>""");
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 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
|
||||
@ -23,15 +23,18 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7180906 8026567 8239804
|
||||
* @bug 7180906 8026567 8239804 8324342
|
||||
* @summary Test to make sure that the since tag works correctly
|
||||
* @library ../../lib
|
||||
* @library /tools/lib ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
* @build javadoc.tester.*
|
||||
* @build toolbox.ToolBox javadoc.tester.*
|
||||
* @run main TestSinceTag
|
||||
*/
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javadoc.tester.JavadocTester;
|
||||
import toolbox.ToolBox;
|
||||
|
||||
public class TestSinceTag extends JavadocTester {
|
||||
|
||||
@ -41,6 +44,8 @@ public class TestSinceTag extends JavadocTester {
|
||||
tester.printSummary();
|
||||
}
|
||||
|
||||
private final ToolBox tb = new ToolBox();
|
||||
|
||||
@Test
|
||||
public void testSince() {
|
||||
javadoc("-d", "out-since",
|
||||
@ -75,4 +80,70 @@ public class TestSinceTag extends JavadocTester {
|
||||
<dt>Since:</dt>
|
||||
<dd>1.4</dd>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSinceDefault(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @since 99
|
||||
*/
|
||||
public class C {
|
||||
/** Class Nested, with no explicit at-since. */
|
||||
public class Nested { }
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Since:</dt>
|
||||
<dd>99</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Since:</dt>
|
||||
<dd>99</dd>""");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSinceDefault_Nested(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @since 99
|
||||
*/
|
||||
public class C {
|
||||
public class Nested1 {
|
||||
/** Class Nested, with no explicit at-since. */
|
||||
public class Nested { }
|
||||
}
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Since:</dt>
|
||||
<dd>99</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested1.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Since:</dt>
|
||||
<dd>99</dd>""");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2018, 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
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8202947 8239804
|
||||
* @bug 8202947 8239804 8324342
|
||||
* @summary test the at-version tag, and corresponding option
|
||||
* @library /tools/lib ../../lib
|
||||
* @modules jdk.javadoc/jdk.javadoc.internal.tool
|
||||
@ -129,4 +129,37 @@ public class TestVersionTag extends JavadocTester {
|
||||
<dd>1.2.3</dd>
|
||||
</dl>""");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVersionDefault(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
tb.writeJavaFiles(src, """
|
||||
package p;
|
||||
/**
|
||||
* Class C.
|
||||
* @version 42
|
||||
*/
|
||||
public class C {
|
||||
/** Class Nested, with no explicit at-version. */
|
||||
public class Nested { }
|
||||
}""");
|
||||
javadoc("-d", base.resolve("api").toString(),
|
||||
"-version",
|
||||
"-sourcepath", src.toString(),
|
||||
"p");
|
||||
checkExit(Exit.OK);
|
||||
|
||||
checkOutput("p/C.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Version:</dt>
|
||||
<dd>42</dd>""");
|
||||
|
||||
checkOutput("p/C.Nested.html", true,
|
||||
"""
|
||||
<dl class="notes">
|
||||
<dt>Version:</dt>
|
||||
<dd>42</dd>""");
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user