Correctly escape Javadoc code snippets #1397
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Escaping code snippets for use in Javadoc comments is non-trivial. By default, Javadoc comments are expected to be HTML markup. While HTML offers
<pre>
and<code>
tags, these only handle formatting and do not remove the need to escape e.g. characters such as<
and>
. To this end, Javadoc provides options such as{@code ...}
for embedding text verbatim. However, these only handle escaping and not formatting. One thus generally combines the two approaches to yield comments like<pre>{@code ...}</pre>
. However, this combination itself introduces challenges around escaping:@
, which normally indicates a Javadoc tag (such as@code
itself), needs to be escaped in some situations but not others:{
and}
) need to be escaped if they are not balanced, since Javadoc counts braces in order to work out when to end the@code
block.*/
always needs to be escaped since it would otherwise premutately terminate the Javadoc comment.Our escaping code is currently broken (see #1363), causing crashes because it fails to handle the case of unbalanced braces. Even in the cases where it does not cause crashes, the Javadoc generated is not necessarily faithful to the input, due to incorrect escaping of
@
and*/
depending on the context. For instance, while many sources state that{@literal @}
is the correct escaping of@
within a@code
block, this is not in general true and will result in{@literal @}
being produced in the rendered output instead of the desired@
.This commit attempts to fix it once and for all. We do this by adopting a strategy whereby we leave the
@code
block temporarily when the need to escape a character arises. For example, given:we now generate:
with the expectation that this will end up inside a
<pre>{@code ...}</pre>
context. This results in generated comments that are harder to read, but render successfully and accurately, both as HTML Javadoc pages and e.g. hover documentation in most IDEs. We attempt to minimise the impact this will have on real-world SDKs/programs by only escaping if there is a need (that is, if a comment contains@
,*/
, or unbalanced braces). The test suite for Javadoc processing has been bulked out so that hopefully this does not bite again (famous last words!).Fixes #1363