Skip to content

Commit a6dc4bc

Browse files
committed
8326332: Unclosed inline tags cause misalignment in summary tables
Reviewed-by: gli, jjg
1 parent 33aa4b2 commit a6dc4bc

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
import jdk.javadoc.internal.doclint.HtmlTag;
114114

115115
import static com.sun.source.doctree.DocTree.Kind.COMMENT;
116+
import static com.sun.source.doctree.DocTree.Kind.START_ELEMENT;
116117
import static com.sun.source.doctree.DocTree.Kind.TEXT;
117118

118119

@@ -1171,21 +1172,28 @@ private void addCommentTags(Element element, List<? extends DocTree> tags, boole
11711172
}
11721173
}
11731174

1174-
boolean ignoreNonInlineTag(DocTree dtree) {
1175+
boolean ignoreNonInlineTag(DocTree dtree, List<Name> openTags) {
11751176
Name name = null;
1176-
if (dtree.getKind() == Kind.START_ELEMENT) {
1177-
StartElementTree setree = (StartElementTree)dtree;
1178-
name = setree.getName();
1179-
} else if (dtree.getKind() == Kind.END_ELEMENT) {
1180-
EndElementTree eetree = (EndElementTree)dtree;
1181-
name = eetree.getName();
1177+
Kind kind = dtree.getKind();
1178+
if (kind == Kind.START_ELEMENT) {
1179+
name = ((StartElementTree)dtree).getName();
1180+
} else if (kind == Kind.END_ELEMENT) {
1181+
name = ((EndElementTree)dtree).getName();
11821182
}
11831183

11841184
if (name != null) {
11851185
HtmlTag htmlTag = HtmlTag.get(name);
1186-
if (htmlTag != null &&
1187-
htmlTag.blockType != jdk.javadoc.internal.doclint.HtmlTag.BlockType.INLINE) {
1188-
return true;
1186+
if (htmlTag != null) {
1187+
if (htmlTag.blockType != HtmlTag.BlockType.INLINE) {
1188+
return true;
1189+
}
1190+
// Keep track of open inline tags that need to be closed, see 8326332
1191+
if (kind == START_ELEMENT && htmlTag.endKind == HtmlTag.EndKind.REQUIRED) {
1192+
openTags.add(name);
1193+
} else if (kind == Kind.END_ELEMENT && !openTags.isEmpty()
1194+
&& openTags.getLast().equals(name)) {
1195+
openTags.removeLast();
1196+
}
11891197
}
11901198
}
11911199
return false;
@@ -1257,6 +1265,7 @@ public ContentBuilder add(CharSequence text) {
12571265
CommentHelper ch = utils.getCommentHelper(element);
12581266
configuration.tagletManager.checkTags(element, trees);
12591267
commentRemoved = false;
1268+
List<Name> openTags = new ArrayList<>();
12601269

12611270
for (ListIterator<? extends DocTree> iterator = trees.listIterator(); iterator.hasNext();) {
12621271
boolean isFirstNode = !iterator.hasPrevious();
@@ -1265,14 +1274,16 @@ public ContentBuilder add(CharSequence text) {
12651274

12661275
if (context.isFirstSentence) {
12671276
// Ignore block tags
1268-
if (ignoreNonInlineTag(tag))
1277+
if (ignoreNonInlineTag(tag, openTags)) {
12691278
continue;
1279+
}
12701280

12711281
// Ignore any trailing whitespace OR whitespace after removed html comment
12721282
if ((isLastNode || commentRemoved)
12731283
&& tag.getKind() == TEXT
1274-
&& ((tag instanceof TextTree tt) && tt.getBody().isBlank()))
1284+
&& ((tag instanceof TextTree tt) && tt.getBody().isBlank())) {
12751285
continue;
1286+
}
12761287

12771288
// Ignore any leading html comments
12781289
if ((isFirstNode || commentRemoved) && tag.getKind() == COMMENT) {
@@ -1466,6 +1477,10 @@ protected Boolean defaultAction(DocTree node, Content content) {
14661477
if (allDone)
14671478
break;
14681479
}
1480+
// Close any open inline tags
1481+
while (!openTags.isEmpty()) {
1482+
result.add(RawHtml.endElement(openTags.removeLast()));
1483+
}
14691484
return result;
14701485
}
14711486

test/langtools/jdk/javadoc/doclet/testBreakIterator/TestBreakIterator.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 4165985
26+
* @bug 4165985 8326332
2727
* @summary Determine the end of the first sentence using BreakIterator.
2828
* If the first sentence of "method" is parsed correctly, the test passes.
2929
* Correct Answer: "This is a class (i.e. it is indeed a class)."
@@ -76,5 +76,10 @@ public void test() {
7676
"""
7777
<div class="block">A constant indicating that the keyLocation is indeterminate
7878
or not relevant.</div>""");
79+
80+
checkOutput("pkg/BreakIteratorTest.html", true,
81+
"""
82+
<div class="block">Inline tags <i><a href="../index-all.html">extending
83+
beyond the first sentence.</a></i></div>""");
7984
}
8085
}

test/langtools/jdk/javadoc/doclet/testBreakIterator/pkg/BreakIteratorTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,9 @@ public void foobar(){}
5656
*/
5757
public void fe(){}
5858

59+
/**
60+
* Inline tags <i><a href="{@docRoot}/index-all.html">extending
61+
* beyond the first sentence. Tags are closed here.</a></i>
62+
*/
63+
public void meh(){}
5964
}

0 commit comments

Comments
 (0)