Javadoc unexpectedly reports that hybrid snippet contents mismatch

XMLWordPrintable

    • Type: CSR
    • Resolution: Unresolved
    • Priority: P4
    • 27
    • Component/s: tools
    • None
    • behavioral
    • minimal
    • JDK

      Summary

      Remove leading and trailing newline characters when comparing inline and external snippet contents in hybrid snippets.

      Problem

      The {@snippet} tag supports hybrid snippets, where snippet content is provided both inline and in an external file. The rationale is to have the snippet content viewable directly in in the source code, but also as a compilable and testable unit in an external file. A requirement of hybrid snippets is that inline and external contents must match, otherwise an error is raised.

      Since external snippet content is usually part of a larger compilable unit, actual snippet content is often defined using region based snippet markup. The following example is simplified version of the one provided in the bug report:

      Hybrid snippet with reference to external file and inline content:

      /**
       * {@snippet class="Test" region=reg:
       * void method() {}} 
       */
      

      External snippet file:

      class Test {
          // @start region=reg
          void method() {}
          // @end
      }
      

      Processing this with javadoc produces the following error:

      MyTest.java:2: error: contents mismatch:
       * {@snippet class="Test" region=reg:
         ^
        ----------------- inline -------------------
        void method() {}  
        ----------------- external -----------------
        
        void method() {}
        
        --------------------------------------------
      

      Note that the above inline and external snippet contents only differ in leading and trailing newline characters, and that despite of these differences, they look identical when processed and viewed in the browser. The underlying bug report contains an example which shows how the problem becomes even worse when combining multiple markup regions, such as @replace or @highlight.

      While it is sometimes possible to tweak the snippet contents and markup to bypass the error, this is not a productive use of developer time. More importantly, leading and trailing line breaks are not an important aspect of the underlying intention to keep snippet contents consistent.

      Solution

      Update the Hybrid Snippets section in the Documentation Comment Specification for the Standard Doclet by adding that line breaks are normalized, and leading and trailing line breaks are removed before comparing inline and external snippet contents.

      Although not directly related to the current issue, also mention in the External Snippets and Hybrid Snippets sections that Unicode escapes are not supported in external snippets, since it may affect what can be represented in an external snippet file.

      Alternatives

      It was considered to change the rules for whitespace production in lines consisting only of markup. However, that would require developers who have made their hybrid snippets compliant with the current rules to update their code again. So while this may be an enhancement worth considering, it woud cause compatibility issues without the changes described in this CSR.

      Specification

      The section for hybrid snippets in the JavaDoc Documentation Comment Specification for the Standard Doclet is updated as follows:

      Inline diff of spec change:

      diff --git a/closed/src/jdk.javadoc/share/specs/javadoc/doc-comment-spec.md b/closed/src/jdk.javadoc/share/specs/javadoc/doc-comment-spec.md
      index 82264815756..eefd2c8324e 100644
      --- a/closed/src/jdk.javadoc/share/specs/javadoc/doc-comment-spec.md
      +++ b/closed/src/jdk.javadoc/share/specs/javadoc/doc-comment-spec.md
      @@ -1312,6 +1312,11 @@ of `doc-files` subdirectories for auxiliary documentation files.
       The file for an external snippet may contain multiple regions, to be referenced
       in different snippet tags, appearing in different parts of the documentation.
       
      +Note that [Unicode escapes][jls.unicode-escapes] are unsupported in external
      +snippets, while they are supported in inline snippets.
      +
      +[jls.unicode-escapes]: https://docs.oracle.com/javase/specs/jls/se@@VERSION_SPECIFICATION@@/html/jls-3.html#jls-3.3
      +
       #### Hybrid snippets
       
       A hybrid snippet is both an internal snippet and an external snippet. It
      @@ -1320,8 +1325,14 @@ of anyone reading the source code for the class being documented, and it also
       refers to a separate file that contains the content of the snippet.
       
       It is an error if the result of processing a hybrid snippet as an inline snippet
      -does not match the result of processing it as an external snippet.
      -
      +does not match the result of processing it as an external snippet. Line breaks
      +are normalized to a canonical representation, and leading and trailing line
      +breaks are removed before inline and external snippet contents are compared
      +as specified by [String::equals].
      +Note that [Unicode escapes][jls.unicode-escapes] are only supported in inline
      +snippets, but not in external snippets.
      +
      +[String::equals]: https://docs.oracle.com/en/java/javase/@@VERSION_SPECIFICATION@@/docs/api/java.base/java/lang/String.html#equals(java.lang.Object)
       
       #### Markup tags
       
      

            Assignee:
            Hannes Wallnoefer
            Reporter:
            Tagir Valeev
            Chen Liang
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: