This PR is primarily informational: aside from adding a few code comments and
`assert` statements, it acts as a place to record observations on unknown
JavaDoc tag reporting mechanics. Because it's a PR, this text will be
automatically sent to the javadoc-dev mailing list and archived for future
reference.
---
DocLint can be run in three modes:
* from javac (i.e. `javac -Xdoclint`)
* from javadoc (i.e. `javadoc -Xdoclint`)
* as a standalone test tool (i.e.
`test/langtools/tools/doclint/DocLintTester.java`)
While the core of all these modes is the same,
`jdk.javadoc.internal.doclint.DocLint`, and is capable of reporting on unknown
tags, whether an unknown tag will be reported, depends on the core
configuration, which differs significantly among these modes.
The latter mode is for testing only and can be configured flexibly, but it's of
little interest to us. The former two modes are important as they face end
user, but are limited in their configuration and, additionally, each has own
peculiarities.
In javac mode, DocLint cannot be passed with a list of custom tags: the
required wiring is missing. So, when a potentially unknown tag is detected, the
error is not raised because `env.customTags == null`:
private void checkUnknownTag(DocTree tree, String tagName) {
if (env.customTags != null && !env.customTags.contains(tagName))
^^^^^^^^^^^^^^^^^^^^^^
env.messages.error(SYNTAX, tree, "dc.tag.unknown", tagName);
}
This is why we don't see errors for JDK-specific tags (e.g. `@implSpec`,
`@implNote`, `@apiNote`, `@jls`) when `make images`, during which DocLint is
run from javac.
In javadoc mode DocLint is passed with a list of custom tags, containing tags
captured from `-tag` and `-taglet` options. Because `make docs` runs javadoc
with such options for each of the JDK-specific tags, all tags are known, and no
errors are reported.
Here's a twist though: javadoc has its own machinery for reporting unknown
tags. So why don't we see doubling of diagnostics? There should be an error
from DocLint and a warning [sic!] from javadoc, but there's only an error.
Here's why:
public void checkTags(Element element, Iterable<? extends DocTree> trees) {
CommentHelper ch = utils.getCommentHelper(element);
for (DocTree tag : trees) {
String name = tag.getKind().tagName;
^^^^^^^^^^^^^^^^^
if (name == null) {
continue;
}
if (!name.isEmpty() && name.charAt(0) == '@') {
name = name.substring(1);
}
if (! (standardTags.contains(name) ||
allTaglets.containsKey(name))) {
if (standardTagsLowercase.contains(Utils.toLowerCase(name))) {
messages.warning(ch.getDocTreePath(tag),
"doclet.UnknownTagLowercase", ch.getTagName(tag));
continue;
} else {
messages.warning(ch.getDocTreePath(tag),
"doclet.UnknownTag", ch.getTagName(tag));
continue;
}
}
Unknown tags are modelled by two `DocTree` subinterfaces,
`UnknownInlineTagTree` and `UnknownBlockTagTree`, each of which return the name
of the captured tag from `getTagName()`, not from `getKind().tagName`, which
(unsurprisingly) returns null for those two kinds. That means that the body of
this `if` block is dead code (i.e. DocLint or not, it's never reached for an
unknown tag):
if (! (standardTags.contains(name) ||
allTaglets.containsKey(name))) {
Here's another twist: DocLint can be disabled for a javadoc run:
`-Xdoclint:none`. When coupled with defunct javadoc reporting, disabled DocLint
means that no unknown tags are reported.
I don't know which of the above is by mistake and which by design, but it's how
it works today. We could address (some of) that in a later PR. Personally, I
wouldn't provide missing wiring in javac, given that javac mode has been
recently somewhat de-emphasized. That said, I think we should repair javadoc
reporting and make sure that either DocLint or javadoc, but not both, report on
unknown tags at all times (i.e. whatever the javadoc configuration might be).
-------------
Commit messages:
- Initial commit
Changes: https://git.openjdk.org/jdk/pull/15314/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=15314&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8314213
Stats: 16 lines in 2 files changed: 15 ins; 0 del; 1 mod
Patch: https://git.openjdk.org/jdk/pull/15314.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/15314/head:pull/15314
PR: https://git.openjdk.org/jdk/pull/15314