Hi Masanori, Thank you for your contribution.
I see you are covered by an OCA, but you are not yet an OpenJDK Author, is that correct?
I'll sponsor your change, filing an issue, posting a webrev and getting a review.
-- Jon On 9/25/19 6:41 PM, Yano, Masanori wrote:
Hello. TagletManager registers a SimpleTaglet for handling @exception tags. But because inherit() method of SimpleTaglet handles only the first encountered tag, two or more @exception tags cannot be handled by this way. In addition, this method cannot inherit description from @throws tags of super class. I propose to create a new ExceptionTaglet specific for handling @exception tags rather than use SimpleTaglet. Please review the following changes. diff -r 046533575954 -r 34fe25800df3 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ExceptionTaglet.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/ExceptionTaglet.java Wed Sep 25 16:21:24 2019 +0900 @@ -0,0 +1,69 @@ +package jdk.javadoc.internal.doclets.toolkit.taglets; + +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; + +import com.sun.source.doctree.DocTree; + +import jdk.javadoc.internal.doclets.toolkit.Content; +import jdk.javadoc.internal.doclets.toolkit.util.CommentHelper; +import jdk.javadoc.internal.doclets.toolkit.util.DocFinder; +import jdk.javadoc.internal.doclets.toolkit.util.DocFinder.Input; +import jdk.javadoc.internal.doclets.toolkit.util.Utils; + +import static com.sun.source.doctree.DocTree.Kind.EXCEPTION; + +/** + * A taglet that represents the @exception tag. + * + * <p><b>This is NOT part of any supported API. + * If you write code that depends on this, you do so at your own risk. + * This code and its internal interfaces are subject to change or + * deletion without notice.</b> + */ + +public class ExceptionTaglet extends SimpleTaglet { + + /** + * Construct a <code>ExceptionTaglet</code>. + */ + public ExceptionTaglet() { + super(EXCEPTION.tagName, null, EnumSet.of(Site.CONSTRUCTOR, Site.METHOD), true); + } + + @Override + public void inherit(DocFinder.Input input, DocFinder.Output output) { + Utils utils = input.utils; + Element exception; + CommentHelper ch = utils.getCommentHelper(input.element); + if (input.tagId == null) { + exception = ch.getException(utils.configuration, input.docTreeInfo.docTree); + input.tagId = exception == null + ? ch.getExceptionName(input.docTreeInfo.docTree).getSignature() + : utils.getFullyQualifiedName(exception); + } else { + TypeElement element = input.utils.findClass(input.element, input.tagId); + exception = (element == null) ? null : element; + } + + for (DocTree dt : input.utils.getThrowsTrees(input.element)) { + Element texception = ch.getException(utils.configuration, dt); + if (texception != null && (input.tagId.equals(utils.getSimpleName(texception)) || + (input.tagId.equals(utils.getFullyQualifiedName(texception))))) { + output.holder = input.element; + output.holderTag = dt; + output.inlineTags = ch.getBody(input.utils.configuration, output.holderTag); + output.tagList.add(dt); + } else if (exception != null && texception != null && + utils.isTypeElement(texception) && utils.isTypeElement(exception) && + utils.isSubclassOf((TypeElement)texception, (TypeElement)exception)) { + output.tagList.add(dt); + } + } + } +} + diff -r 046533575954 -r 34fe25800df3 src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java Sat Jan 26 15:47:50 2019 +0900 +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java Wed Sep 25 16:21:24 2019 +0900 @@ -608,9 +608,7 @@ addStandardTaglet(new ParamTaglet()); addStandardTaglet(new ReturnTaglet()); addStandardTaglet(new ThrowsTaglet()); - addStandardTaglet( - new SimpleTaglet(EXCEPTION.tagName, null, - EnumSet.of(Site.METHOD, Site.CONSTRUCTOR))); + addStandardTaglet(new ExceptionTaglet()); addStandardTaglet( new SimpleTaglet(SINCE.tagName, resources.getText("doclet.Since"), EnumSet.allOf(Site.class), !nosince)); diff -r f54e328f0c60 -r 66621f0835f2 test/langtools/jdk/javadoc/doclet/testExceptionInheritence/A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritence/A.java Tue Sep 24 15:29:17 2019 +0900 @@ -0,0 +1,8 @@ +public class A { + /** + * @param x a number + * @exception NullPointerException if x is null + * @exception IllegalArgumentException if {@code x < 0} + */ + public void m(Integer x) { } +} diff -r f54e328f0c60 -r 66621f0835f2 test/langtools/jdk/javadoc/doclet/testExceptionInheritence/A_Sub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritence/A_Sub.java Tue Sep 24 15:29:17 2019 +0900 @@ -0,0 +1,9 @@ +public class A_Sub extends A { + /** + * @param x {@inheritDoc} + * @exception NullPointerException {@inheritDoc} + * @exception IllegalArgumentException {@inheritDoc} + */ + @Override + public void m(Integer x) { } +} diff -r f54e328f0c60 -r 66621f0835f2 test/langtools/jdk/javadoc/doclet/testExceptionInheritence/B.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritence/B.java Tue Sep 24 15:29:17 2019 +0900 @@ -0,0 +1,8 @@ +public class B { + /** + * @param x a number + * @throws NullPointerException if x is null + * @throws IllegalArgumentException if {@code x < 0} + */ + public void m(Integer x) { } +} diff -r f54e328f0c60 -r 66621f0835f2 test/langtools/jdk/javadoc/doclet/testExceptionInheritence/B_Sub.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritence/B_Sub.java Tue Sep 24 15:29:17 2019 +0900 @@ -0,0 +1,9 @@ +public class B_Sub extends B { + /** + * @param x {@inheritDoc} + * @exception NullPointerException {@inheritDoc} + * @exception IllegalArgumentException {@inheritDoc} + */ + @Override + public void m(Integer x) { } +} diff -r f54e328f0c60 -r 66621f0835f2 test/langtools/jdk/javadoc/doclet/testExceptionInheritence/Bug8157682.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/jdk/javadoc/doclet/testExceptionInheritence/Bug8157682.java Tue Sep 24 15:29:17 2019 +0900 @@ -0,0 +1,43 @@ +/* + * @test + * @bug 8157682 + * @summary This test verifies that exception tags can inherit property. + * @library ../../lib + * @modules jdk.javadoc/jdk.javadoc.internal.tool + * @build javadoc.tester.* + * @run main Bug8157682 + */ + +import javadoc.tester.JavadocTester; + +public class Bug8157682 extends JavadocTester { + + public static void main(String... args) throws Exception { + Bug8157682 tester = new Bug8157682(); + tester.runTests(); + } + + @Test + public void test() { + javadoc("-d", "out", + "-sourcepath", testSrc, + testSrc("A.java"), + testSrc("B.java"), + testSrc("A_Sub.java"), + testSrc("B_Sub.java")); + checkExit(Exit.OK); + + checkOutput("A_Sub.html", true, + "<code>java.lang.NullPointerException</code> - if x is null"); + + checkOutput("A_Sub.html", true, + "<code>java.lang.IllegalArgumentException</code> - if <code>x < 0</code>"); + + checkOutput("B_Sub.html", true, + "<code>java.lang.NullPointerException</code> - if x is null"); + + checkOutput("B_Sub.html", true, + "<code>java.lang.IllegalArgumentException</code> - if <code>x < 0</code>"); + } + +} Regards, Masanori Yano