8157682: @inheritDoc doesn't work with @exception

Jonathan Gibbons jonathan.gibbons at oracle.com
Wed Mar 3 22:32:06 UTC 2021


Hi,

I looked in detail at your patch. I understand the problem you're trying  
to solve, but this is not the best way to solve the problem. You're  
introducing a new `ExceptionTaglet` class that provides a subset of the  
functionality of the equivalent `ThrowsTaglet` class. A better way to  
solve the problem is to simply reuse the `ThrowsTaglet` by registering  
it under an additional name.

I looked at your test and rewrote it somewhat to check more combinations  
of `@throws` and `@exception`.

You can see the latest version in this PR on GitHub:  
https://github.com/openjdk/jdk/pull/2818

Thank you for your interest in helping to fix this issue.

-- 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


More information about the javadoc-dev mailing list