<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>Hey,</p>
    <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>
      <br>
    </p>
    <p>[0] <a class="moz-txt-link-freetext"
        href="https://github.com/INRIA/spoon/">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">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">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">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">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">https://github.com/openjdk/jdk/blob/e9d19d0fffc47119d0d4f756833ec87cd0a6331e/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java#L2832</a><br>
    </p>
  </body>
</html>