<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
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>
</body>
</html>