<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>javadoc has some changes/fixes/enhancements in this area in JDK
22, both in the code and the Doc Comment Specification.</p>
<p>The intent is to better align the lookup for inherited comments
with the general lookup rules in JLS.</p>
<p>-- Jon<br>
</p>
<div class="moz-cite-prefix">On 2/6/24 7:14 AM, I Al Istannen wrote:<br>
</div>
<blockquote type="cite" cite="mid:e8283d0c-eafc-4744-9fe9-07dd27d75985@ialistannen.de">
Hey,
<div class="moz-forward-container">
<p>I hope this is the right place to ask :)</p>
<p>I was recently implementing javadoc comment inheritance for
spoon[0] and verified it against IntelliJ IDEA and the
standard html doclet. While doing this I found out that
IntelliJ and the standard doclet disagree on comment
inheritance in this example[1]. The doclet algorithm
documented in [2] specifies the following:<br>
</p>
<p> </p>
<ol>
<li>Look in each directly implemented (or extended) interface
in the order they appear following the word implements (or
extends) in the type declaration. <i>Use the first
documentation comment found for this method.</i></li>
<li>If Step 1 failed to find a documentation comment, then
recursively apply this entire algorithm to each directly
implemented (or extended) interface in the same order they
were examined in Step 1.</li>
</ol>
<p>This seems to imply that resolution proceeds in two phases.
First, you look at the direct super interfaces and see if any
doc comment there contains what you need. If this does not
result in a value <i>after</i> looking at <i>all</i> super
interfaces, you try finding it recursively in each super
interface, again in declaration order. </p>
<p>If we now apply this to find the body in the example[1]:</p>
<ol>
<li>Look at the javadoc in <span class="pl-smi">SuperInt2,
find no body</span></li>
<li><span class="pl-smi">Look at the javadoc in SuperInt3,
find the body "</span><span class="pl-c"><span data-rgh-whitespace="space"></span>Never<span data-rgh-whitespace="space"> </span>used,<span data-rgh-whitespace="space"> </span>shadowed<span data-rgh-whitespace="space"> </span>by<span data-rgh-whitespace="space"> </span>body<span data-rgh-whitespace="space"> </span>in<span data-rgh-whitespace="space"> </span>super<span data-rgh-whitespace="space"> </span>int<span data-rgh-whitespace="space"> </span>1."</span></li>
<li><span class="pl-c">Return this value. Body is now "</span><span class="pl-c"><span data-rgh-whitespace="space"></span>Never<span data-rgh-whitespace="space"> </span>used,<span data-rgh-whitespace="space"> </span>shadowed<span data-rgh-whitespace="space"> </span>by<span data-rgh-whitespace="space"> </span>body<span data-rgh-whitespace="space"> </span>in<span data-rgh-whitespace="space"> </span>super<span data-rgh-whitespace="space"> </span>int<span data-rgh-whitespace="space"> </span>1."</span></li>
</ol>
<p>This is the behaviour you can observe in IntelliJ IDEA, as
they split this logic into two distinct phases[3]. It is,
however, not the behaviour of the standard doclet. The
standard doclet finds the body "<span class="pl-c"><span data-rgh-whitespace="space"></span>A<span data-rgh-whitespace="space"> </span>test." declared in
SuperInt1, which SuperInt2 extends from. After glancing at
the doclet source code, the doclet seems to <i>directly</i></span>
explore the full inheritance hierarchy for every
superinterface by doing a depth-first search[4], effectively
interleaving step 1 and 2.</p>
<p>I was whipping up a patch for IntelliJ, but I am actually not
sure it is wrong. My spoon resolver code mirrors the JDK code
by pure coincidence, but I think the spec agrees with IntelliJ
here. Is this a bug in the standard doclet, is the
specification outdated/wrong or did I miss something?<br>
</p>
<p>Have a nice day!<br>
I Al Istannen<br>
<br>
</p>
<p>[0] <a class="moz-txt-link-freetext" href="https://github.com/INRIA/spoon/" moz-do-not-send="true">https://github.com/INRIA/spoon/</a>,
<a class="moz-txt-link-freetext" href="https://github.com/INRIA/spoon/blob/master/spoon-javadoc/src/main/java/spoon/javadoc/api/parsing/InheritanceResolver.java" moz-do-not-send="true">https://github.com/INRIA/spoon/blob/master/spoon-javadoc/src/main/java/spoon/javadoc/api/parsing/InheritanceResolver.java</a><br>
[1] <a class="moz-txt-link-freetext" href="https://gist.github.com/I-Al-Istannen/a95125d20319a999d2255a7fe086e768" moz-do-not-send="true">https://gist.github.com/I-Al-Istannen/a95125d20319a999d2255a7fe086e768</a><br>
[2] <a class="moz-txt-link-freetext" href="https://docs.oracle.com/en/java/javase/21/docs/specs/javadoc/doc-comment-spec.html" moz-do-not-send="true">https://docs.oracle.com/en/java/javase/21/docs/specs/javadoc/doc-comment-spec.html</a><br>
[3] <a class="moz-txt-link-freetext" href="https://github.com/JetBrains/intellij-community/blob/4f20bcc65cd08c53e4734bbe302480eb9b31515d/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java#L3076" moz-do-not-send="true">https://github.com/JetBrains/intellij-community/blob/4f20bcc65cd08c53e4734bbe302480eb9b31515d/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java#L3076</a><br>
[4] <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jdk/blob/e9d19d0fffc47119d0d4f756833ec87cd0a6331e/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java#L2832" moz-do-not-send="true">https://github.com/openjdk/jdk/blob/e9d19d0fffc47119d0d4f756833ec87cd0a6331e/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java#L2832</a><br>
</p>
</div>
</blockquote>
</body>
</html>