Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.
/ jdk19 Public archive

Commit 62fbc3f

Browse files
committed
8287379: Using @inheritdoc in an inapplicable context shouldn't crash javadoc
Reviewed-by: jjg
1 parent fed3af8 commit 62fbc3f

File tree

16 files changed

+260
-276
lines changed

16 files changed

+260
-276
lines changed

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1485,7 +1485,7 @@ public ContentBuilder add(CharSequence text) {
14851485
};
14861486
CommentHelper ch = utils.getCommentHelper(element);
14871487
// Array of all possible inline tags for this javadoc run
1488-
configuration.tagletManager.checkTags(element, trees, true);
1488+
configuration.tagletManager.checkTags(element, trees);
14891489
commentRemoved = false;
14901490

14911491
for (ListIterator<? extends DocTree> iterator = trees.listIterator(); iterator.hasNext();) {

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/InheritDocTaglet.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@
2828
import java.util.EnumSet;
2929

3030
import javax.lang.model.element.Element;
31+
import javax.lang.model.element.ElementKind;
3132
import javax.lang.model.element.ExecutableElement;
32-
import javax.lang.model.element.TypeElement;
33-
import javax.lang.model.type.TypeKind;
3433

3534
import com.sun.source.doctree.DocTree;
3635
import jdk.javadoc.doclet.Taglet.Location;
@@ -42,17 +41,15 @@
4241
import jdk.javadoc.internal.doclets.toolkit.util.Utils;
4342

4443
/**
45-
* An inline taglet representing the {@code {@inheritDoc}} tag.
46-
* It is used to copy documentation from superclass (but not superinterface)
47-
* declarations and from overridden and implemented methods.
44+
* A taglet that represents the {@code {@inheritDoc}} tag.
4845
*/
4946
public class InheritDocTaglet extends BaseTaglet {
5047

5148
/**
5249
* Construct a new InheritDocTaglet.
5350
*/
5451
public InheritDocTaglet() {
55-
super(DocTree.Kind.INHERIT_DOC, true, EnumSet.of(Location.TYPE, Location.METHOD));
52+
super(DocTree.Kind.INHERIT_DOC, true, EnumSet.of(Location.METHOD));
5653
}
5754

5855
/**
@@ -96,14 +93,6 @@ private Content retrieveInheritedDocumentation(TagletWriter writer,
9693
inheritedDoc.inlineTags, isFirstSentence);
9794
}
9895
} else {
99-
// This is to assert that we don't reach here for a class declaration.
100-
// Indeed, every class except for java.lang.Object has a superclass.
101-
// If we ever reach here, we would need a different warning; because
102-
// the below warning is about method declarations, not class declarations.
103-
// Unless @inheritDoc is used inside java.lang.Object itself,
104-
// which would clearly be an error, we shouldn't reach here.
105-
assert !(e instanceof TypeElement typeElement)
106-
|| typeElement.getSuperclass().getKind() == TypeKind.NONE;
10796
String signature = utils.getSimpleName(e) +
10897
((utils.isExecutableElement(e))
10998
? utils.flatSignature((ExecutableElement) e, writer.getCurrentPageElement())
@@ -115,6 +104,9 @@ private Content retrieveInheritedDocumentation(TagletWriter writer,
115104

116105
@Override
117106
public Content getInlineTagOutput(Element e, DocTree inheritDoc, TagletWriter tagletWriter) {
107+
if (e.getKind() != ElementKind.METHOD) {
108+
return tagletWriter.getOutputInstance();
109+
}
118110
return retrieveInheritedDocumentation(tagletWriter, e, inheritDoc, tagletWriter.isFirstSentence);
119111
}
120112
}

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletManager.java

Lines changed: 48 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -350,16 +350,12 @@ void seenTag(String name) {
350350
}
351351

352352
/**
353-
* Given a series of {@code DocTree}s, check for spelling mistakes.
353+
* Given a series of {@code DocTree}s, check for misuse and spelling mistakes.
354354
*
355355
* @param element the tags holder
356356
* @param trees the trees containing the comments
357-
* @param inlineTrees true if the trees are inline and false otherwise
358357
*/
359-
public void checkTags(Element element, Iterable<? extends DocTree> trees, boolean inlineTrees) {
360-
if (trees == null) {
361-
return;
362-
}
358+
public void checkTags(Element element, Iterable<? extends DocTree> trees) {
363359
CommentHelper ch = utils.getCommentHelper(element);
364360
for (DocTree tag : trees) {
365361
String name = tag.getKind().tagName;
@@ -386,73 +382,62 @@ public void checkTags(Element element, Iterable<? extends DocTree> trees, boolea
386382
return;
387383
}
388384

389-
if (inlineTrees && !taglet.isInlineTag()) {
390-
printTagMisuseWarn(ch, taglet, tag, "inline");
391-
}
392-
393-
// nothing more to do
394-
if (element == null) {
395-
return;
396-
}
397-
398-
if (!inlineTrees) {
399-
new SimpleElementVisitor14<Void, Void>() {
400-
@Override
401-
public Void visitModule(ModuleElement e, Void p) {
402-
if (!taglet.inModule()) {
403-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "module");
404-
}
405-
return null;
385+
new SimpleElementVisitor14<Void, Void>() {
386+
@Override
387+
public Void visitModule(ModuleElement e, Void p) {
388+
if (!taglet.inModule()) {
389+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "module");
406390
}
391+
return null;
392+
}
407393

408-
@Override
409-
public Void visitPackage(PackageElement e, Void p) {
410-
if (!taglet.inPackage()) {
411-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "package");
412-
}
413-
return null;
394+
@Override
395+
public Void visitPackage(PackageElement e, Void p) {
396+
if (!taglet.inPackage()) {
397+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "package");
414398
}
399+
return null;
400+
}
415401

416-
@Override
417-
public Void visitType(TypeElement e, Void p) {
418-
if (!taglet.inType()) {
419-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "class");
420-
}
421-
return null;
402+
@Override
403+
public Void visitType(TypeElement e, Void p) {
404+
if (!taglet.inType()) {
405+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "class");
422406
}
407+
return null;
408+
}
423409

424-
@Override
425-
public Void visitExecutable(ExecutableElement e, Void p) {
426-
if (utils.isConstructor(e) && !taglet.inConstructor()) {
427-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "constructor");
428-
} else if (!taglet.inMethod()) {
429-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "method");
430-
}
431-
return null;
410+
@Override
411+
public Void visitExecutable(ExecutableElement e, Void p) {
412+
if (utils.isConstructor(e) && !taglet.inConstructor()) {
413+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "constructor");
414+
} else if (!taglet.inMethod()) {
415+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "method");
432416
}
417+
return null;
418+
}
433419

434-
@Override
435-
public Void visitVariable(VariableElement e, Void p) {
436-
if (utils.isField(e) && !taglet.inField()) {
437-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "field");
438-
}
439-
return null;
420+
@Override
421+
public Void visitVariable(VariableElement e, Void p) {
422+
if (utils.isField(e) && !taglet.inField()) {
423+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "field");
440424
}
425+
return null;
426+
}
441427

442-
@Override
443-
public Void visitUnknown(Element e, Void p) {
444-
if (utils.isOverviewElement(e) && !taglet.inOverview()) {
445-
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "overview");
446-
}
447-
return null;
428+
@Override
429+
public Void visitUnknown(Element e, Void p) {
430+
if (utils.isOverviewElement(e) && !taglet.inOverview()) {
431+
printTagMisuseWarn(utils.getCommentHelper(e), taglet, tag, "overview");
448432
}
433+
return null;
434+
}
449435

450-
@Override
451-
protected Void defaultAction(Element e, Void p) {
452-
return null;
453-
}
454-
}.visit(element);
455-
}
436+
@Override
437+
protected Void defaultAction(Element e, Void p) {
438+
return null;
439+
}
440+
}.visit(element);
456441
}
457442
}
458443
}
@@ -489,22 +474,13 @@ private void printTagMisuseWarn(CommentHelper ch, Taglet taglet, DocTree tag, St
489474
if (taglet.inMethod()) {
490475
locationsSet.add("method");
491476
}
492-
if (taglet.isInlineTag()) {
493-
locationsSet.add("inline text");
494-
}
495477
if (locationsSet.isEmpty()) {
496478
//This known tag is excluded.
497479
return;
498480
}
499-
StringBuilder combined_locations = new StringBuilder();
500-
for (String location: locationsSet) {
501-
if (combined_locations.length() > 0) {
502-
combined_locations.append(", ");
503-
}
504-
combined_locations.append(location);
505-
}
481+
var combined_locations = String.join(", ", locationsSet);
506482
messages.warning(ch.getDocTreePath(tag), "doclet.tag_misuse",
507-
"@" + taglet.getName(), holderType, combined_locations.toString());
483+
"@" + taglet.getName(), holderType, combined_locations);
508484
}
509485

510486
/**

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/taglets/TagletWriter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ public Content getBlockTagOutput(TagletManager tagletManager,
275275

276276
Content output = getOutputInstance();
277277
Utils utils = configuration().utils;
278-
tagletManager.checkTags(element, utils.getBlockTags(element), false);
279-
tagletManager.checkTags(element, utils.getFullBody(element), true);
278+
tagletManager.checkTags(element, utils.getBlockTags(element));
279+
tagletManager.checkTags(element, utils.getFullBody(element));
280280
for (Taglet taglet : taglets) {
281281
if (utils.isTypeElement(element) && taglet instanceof ParamTaglet) {
282282
// The type parameters and state components are documented in a special

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/DocFinder.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import javax.lang.model.element.Element;
3131
import javax.lang.model.element.ExecutableElement;
3232
import javax.lang.model.element.TypeElement;
33-
import javax.lang.model.type.TypeMirror;
3433

3534
import com.sun.source.doctree.DocTree;
3635
import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration;
@@ -258,17 +257,6 @@ public static Output search(BaseConfiguration configuration, Input input) {
258257
return output;
259258
}
260259
}
261-
} else if (utils.isTypeElement(input.element)) {
262-
TypeMirror t = ((TypeElement) input.element).getSuperclass();
263-
Element superclass = utils.asTypeElement(t);
264-
if (superclass != null) {
265-
inheritedSearchInput.element = superclass;
266-
output = search(configuration, inheritedSearchInput);
267-
output.isValidInheritDocTag = true;
268-
if (!output.inlineTags.isEmpty()) {
269-
return output;
270-
}
271-
}
272260
}
273261
return output;
274262
}

src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclint/Checker.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public Void scan(DocCommentTree tree, TreePath p) {
193193
reportMissing("dc.missing.comment");
194194
}
195195
return null;
196-
} else if (tree.getFirstSentence().isEmpty() && !isOverridingMethod) {
196+
} else if (tree.getFirstSentence().isEmpty() && !isOverridingMethod && !pseudoElement(p)) {
197197
if (tree.getBlockTags().isEmpty()) {
198198
reportMissing("dc.empty.comment");
199199
return null;
@@ -224,7 +224,7 @@ public Void scan(DocCommentTree tree, TreePath p) {
224224

225225
// this is for html files
226226
// ... if it is a legacy package.html, the doc comment comes after the <h1> page title
227-
// ... otherwise, (e.g. overview file and doc-files/*.html files) no additional headings are inserted
227+
// ... otherwise, (e.g. overview file and doc-files/**/*.html files) no additional headings are inserted
228228
case COMPILATION_UNIT -> fo.isNameCompatible("package", JavaFileObject.Kind.HTML) ? 1 : 0;
229229

230230

@@ -292,6 +292,13 @@ private boolean isCanonicalRecordConstructor(ExecutableElement ee) {
292292
return true;
293293
}
294294

295+
// Checks if the passed tree path corresponds to an entity, such as
296+
// the overview file and doc-files/**/*.html files.
297+
private boolean pseudoElement(TreePath p) {
298+
return p.getLeaf().getKind() == Tree.Kind.COMPILATION_UNIT
299+
&& p.getCompilationUnit().getSourceFile().getKind() == JavaFileObject.Kind.HTML;
300+
}
301+
295302
private void reportMissing(String code, Object... args) {
296303
env.messages.report(MISSING, Kind.WARNING, env.currPath.getLeaf(), code, args);
297304
}

0 commit comments

Comments
 (0)