javadoc has some changes/fixes/enhancements in this area in JDK 22, both
in the code and the Doc Comment Specification.
The intent is to better align the lookup for inherited comments with the
general lookup rules in JLS.
-- Jon
On 2/6/24 7:14 AM, I Al Istannen wrote:
Hey,
I hope this is the right place to ask :)
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:
1. Look in each directly implemented (or extended) interface in the
order they appear following the word implements (or extends) in
the type declaration. /Use the first documentation comment found
for this method./
2. 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.
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 /after/
looking at /all/ super interfaces, you try finding it recursively in
each super interface, again in declaration order.
If we now apply this to find the body in the example[1]:
1. Look at the javadoc in SuperInt2, find no body
2. Look at the javadoc in SuperInt3, find the body
"Neverused,shadowedbybodyinsuperint1."
3. Return this value. Body is now "Neverused,shadowedbybodyinsuperint1."
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
"Atest." declared in SuperInt1, which SuperInt2 extends from. After
glancing at the doclet source code, the doclet seems to /directly/
explore the full inheritance hierarchy for every superinterface by
doing a depth-first search[4], effectively interleaving step 1 and 2.
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?
Have a nice day!
I Al Istannen
[0] https://github.com/INRIA/spoon/,
https://github.com/INRIA/spoon/blob/master/spoon-javadoc/src/main/java/spoon/javadoc/api/parsing/InheritanceResolver.java
[1] https://gist.github.com/I-Al-Istannen/a95125d20319a999d2255a7fe086e768
[2]
https://docs.oracle.com/en/java/javase/21/docs/specs/javadoc/doc-comment-spec.html
[3]
https://github.com/JetBrains/intellij-community/blob/4f20bcc65cd08c53e4734bbe302480eb9b31515d/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java#L3076
[4]
https://github.com/openjdk/jdk/blob/e9d19d0fffc47119d0d4f756833ec87cd0a6331e/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java#L2832