Draft JEP for upcoming work on snippets

Pavel Rappo pavel.rappo at oracle.com
Tue Feb 2 18:18:06 UTC 2021


Resending my recent email in plain text; apologies for sending it previously in rich text.

***

Dmitry,

8201533 is a Draft JEP for a feature that is currently under active development. As such, that draft is prone to inconsistencies, inaccuracies, typos, etc. As we further develop the feature and receive feedback on it, that draft will improve and eventually reach the high bar of JEP Candidate.

Thank you for the feedback; detailed replies are inline.

> On 29 Jan 2021, at 06:52, Dmitry Timofeev <dmitry.timofeiev at gmail.com> wrote:
> 
> Hi everyone, 
> 
> Happy to see a JEP improving support for code snippets! I’ve got some feedback from the user perspective, and from some prototyping to support Javadoc snippet compilation:
> 
>> hide = regex —
> 
> Would it be possible to have a simpler mechanism? For example, Rust code snippets use # at the beginning of the line to hide it [1]. From the user perspective, it is very easy to use and maintain — you don’t have to design a regex, you won’t get any surprises from its evaluation, or read/maintain some over-complicated pattern that slipped through code review.
> 
> [1]: https://doc.rust-lang.org/rustdoc/documentation-tests.html#hiding-portions-of-the-example

We are open to amending the initial set of markup constructs. We could consider adding the parameterless trailing "@hide" construct which hides the line on which it stands; you won't need regex to use such a construct. Do you see much use for that particular construct or you provided it as an illustration for alternative, regex-less markup?

As for #, I don't think prepending a line with # to hide that line would be apt for snippets in JavaDoc. This is because it breaks invariance, one of the major qualities we sought in markup. Markup is invariant if it doesn't depend on whether it is used in an inline or external snippet. Although using leading # to hide a line seems to work fine with inline snippets, it won't work with external snippets. Indeed, in Java source a line starting with # results in a syntax error, whereas in properties file the leading # starts a comment.

>> lang=name — […] Valid names are java, properties and text
> 
> Would it be possible to specify any language, as the goal seems to be to pass this information to any rendering tools? Some converter libraries might use snippets with configs (xml, json, …), some FFI libs — in C++/Rust, some libs might provide examples for some JVM-based languages.

Currently, we see no reasons for not allowing an arbitrary language. That said, the JEP draft needs to clarify that. The draft needs to convey that while we are not restricting the set of languages, only the specified languages are guaranteed to be recognized by the standard doclet. What "recognized" translates to must also be explained.

>> region=name — 
> 
> Would it make sense to provide some kind of selectors for Java constructs? E.g., block:<method_name, or class_name> selecting the corresponding method or class? This plugin for Mkdocs does that, but it operates on text, not on AST, therefore, some unexpected curly braces break it (e.g., in string literals) [2]. However, even simple text-based selection works well. Does the Javadoc have the luxury of having ready access to the AST? Or is it too complex to implement/maintain?
> 
> [2]: https://github.com/rnorth/mkdocs-codeinclude-plugin#usage

We are considering allowing to specify method bodies as complete snippet source or a region thereof.

>> For inline snippets, especially those that are not a full compilation unit, it will be up to the test infrastructure to "wrap" the code fragment in a full compilation unit, such that it can be compiled and possibly executed.
> 
> Would it be possible to keep the non-goal of not providing a standard tool to test them (to limit the scope of the JEP), but suggest a format/restrictions/expansion procedure on the snippets to support such test infra well (or enable adding it to JDK in the future)? I agree that external snippets work well (especially for large-ish fragments), but for some small things it is an overkill (you have to somehow configure the build system to build these files, but exclude from the final artifact, etc.), yet as a user I’d love to check their correctness. Would it make sense to:
> - Specify a standard way how a snippet is expanded (e.g., wrapped inside Callable#call, or some standard template — Java language designers are in a perfect position to pick a great one). [3]
> - Specify a set of tags that define the expectations of the expanded snippet behaviour (not sure it can be pulled into the scope, but the tools will require that information): [4]
>    - Compiles/fails compilation
>    - Runs successfully/Throws exception
>    - Is totally ignored.
> 
> In Rust doctests, for example, all these things are supported:
> [3] https://doc.rust-lang.org/rustdoc/documentation-tests.html#pre-processing-examples (adds main unless you do that)
> [4] https://doc.rust-lang.org/rustdoc/documentation-tests.html#attributes

The "Snippets" feature's first and foremost use case is JDK itself. Snippets found in "<pre>{@code" compounds in JDK are so different from each other that it doesn't seem possible to provide a solution sufficiently general to test those snippets automatically. Although the concept of "doctest", which you are referring to, offers a highly attractive end-to-end testing, that concept applies cleanly to snippets that were written with that concept in mind, such as snippets structured as tests or executable as-is. The thing is, we don't have many of those in JDK.

Since we cannot generally ensure that every snippet is correct in the resulting documentation, we aim for the next best thing: enabling authors to ensure that the snippets are produced from correct sources. Authors don't have to build these sources, exclude them from the build artifacts, or use external snippets altogether; it's an option.

While doctests are not immediately useful in JDK, we recognize that they might benefit other projects. That's why we are exposing snippets in JavaDoc API. That API may be used to test snippets externally or in JavaDoc. For example, using attributes of the {@snippet} tag, snippet markup and a custom taglet, one should be able to teach JavaDoc doctesting.

> Finally, you might be interested in the previous attempts to implement such a tool for Java: https://github.com/jakewins/javadoctest 
> Beware the docs aren’t updated, its current version does not require writing test manually, and finds and extracts snippets on itself, e.g.:
> https://github.com/jakewins/javadoctest/blob/master/junit-platform-engine/src/test/java/javadoctest/engine/fixture/FixtureDocTestSimple.java#L18-L22
> -- 
> Best regards,
> Dmitry Timofeev

Thanks for providing the links to mkdocs and javadoctest.

-Pavel



More information about the javadoc-dev mailing list