8241780: Allow \n@ inside inline tags

Reviewed-by: prappo
This commit is contained in:
Jonathan Gibbons 2020-04-23 16:10:45 -07:00
parent 0c56c3511a
commit 009dd60ea3
6 changed files with 113 additions and 43 deletions

View File

@ -30,18 +30,18 @@ import java.util.HashMap;
import java.util.Map;
import com.sun.source.doctree.AttributeTree.ValueKind;
import com.sun.source.doctree.ErroneousTree;
import com.sun.source.doctree.UnknownBlockTagTree;
import com.sun.tools.javac.parser.DocCommentParser.TagParser.Kind;
import com.sun.tools.javac.parser.Tokens.Comment;
import com.sun.tools.javac.parser.Tokens.TokenKind;
import com.sun.tools.javac.tree.DCTree;
import com.sun.tools.javac.tree.DCTree.DCAttribute;
import com.sun.tools.javac.tree.DCTree.DCDocComment;
import com.sun.tools.javac.tree.DCTree.DCEndElement;
import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
import com.sun.tools.javac.tree.DCTree.DCErroneous;
import com.sun.tools.javac.tree.DCTree.DCIdentifier;
import com.sun.tools.javac.tree.DCTree.DCReference;
import com.sun.tools.javac.tree.DCTree.DCStartElement;
import com.sun.tools.javac.tree.DCTree.DCText;
import com.sun.tools.javac.tree.DocTreeMaker;
import com.sun.tools.javac.tree.JCTree;
@ -54,7 +54,7 @@ import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Position;
import com.sun.tools.javac.util.StringUtils;
import static com.sun.tools.javac.util.LayoutCharacters.*;
import static com.sun.tools.javac.util.LayoutCharacters.EOI;
/**
*
@ -261,7 +261,7 @@ public class DocCommentParser {
/**
* Read a series of block tags, including their content.
* Standard tags parse their content appropriately.
* Non-standard tags are represented by {@link UnknownBlockTag}.
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
*/
protected List<DCTree> blockTags() {
ListBuffer<DCTree> tags = new ListBuffer<>();
@ -273,7 +273,7 @@ public class DocCommentParser {
/**
* Read a single block tag, including its content.
* Standard tags parse their content appropriately.
* Non-standard tags are represented by {@link UnknownBlockTag}.
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
*/
protected DCTree blockTag() {
int p = bp;
@ -321,8 +321,8 @@ public class DocCommentParser {
/**
* Read a single inline tag, including its content.
* Standard tags parse their content appropriately.
* Non-standard tags are represented by {@link UnknownBlockTag}.
* Malformed tags may be returned as {@link Erroneous}.
* Non-standard tags are represented by {@link UnknownBlockTagTree}.
* Malformed tags may be returned as {@link ErroneousTree}.
*/
protected DCTree inlineTag() {
int p = bp - 1;
@ -413,13 +413,6 @@ public class DocCommentParser {
lastNonWhite = bp;
break;
case '@':
if (newline)
break loop;
newline = false;
lastNonWhite = bp;
break;
default:
newline = false;
lastNonWhite = bp;

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 7021614
* @bug 7021614 8241780
* @summary extend com.sun.source API to support parsing javadoc comments
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@ -97,6 +97,42 @@ DocComment[DOC_COMMENT, pos:1
body: empty
block tags: empty
]
*/
/**
* {@code
* @tag
* }
*/
void embedded_at() { }
/*
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Literal[CODE, pos:1, |_@tag|_]
body: empty
block tags: empty
]
*/
/**
* <pre>{@code
* @Override
* void m() { }
* }</pre>
*/
void pre_at_code() { }
/*
DocComment[DOC_COMMENT, pos:1
firstSentence: 2
StartElement[START_ELEMENT, pos:1
name:pre
attributes: empty
]
Literal[CODE, pos:6, |_____@Override|..._____void_m()_{_}|_]
body: 1
EndElement[END_ELEMENT, pos:48, pre]
block tags: empty
]
*/
/** {@code if (a < b) { } */
@ -122,14 +158,10 @@ DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Erroneous[ERRONEOUS, pos:1
code: compiler.err.dc.unterminated.inline.tag
body: {@code_if_(a_<_b)_{_}
body: {@code_if_(a_<_b...)_{_}|_@author_jjg
]
body: empty
block tags: 1
Author[AUTHOR, pos:24
name: 1
Text[TEXT, pos:32, jjg]
]
block tags: empty
]
*/

View File

@ -873,22 +873,57 @@ public class DocCommentTester {
System.err.println(normRaw.replace(" ", "_"));
System.err.println("*** found:");
System.err.println(pretty.replace(" ", "_"));
// throw new Error();
}
}
/**
* Normalize white space in places where the tree does not preserve it.
* Maintain contents of at-code and at-literal inline tags.
*/
String normalize(String s) {
s = s.trim()
.replaceFirst("\\.\\s*\\n *@", ".\n@")
.replaceAll("\\{@docRoot\\s+\\}", "{@docRoot}")
String s2 = s.trim().replaceFirst("\\.\\s*\\n *@", ".\n@");
StringBuilder sb = new StringBuilder();
Pattern p = Pattern.compile("\\{@(code|literal)( )?");
Matcher m = p.matcher(s2);
int start = 0;
while (m.find(start)) {
sb.append(normalizeFragment(s2.substring(start, m.start())));
sb.append(m.group().trim());
start = copyLiteral(s2, m.end(), sb);
}
sb.append(normalizeFragment(s2.substring(start)));
return sb.toString();
}
String normalizeFragment(String s) {
return s.replaceAll("\\{@docRoot\\s+\\}", "{@docRoot}")
.replaceAll("\\{@inheritDoc\\s+\\}", "{@inheritDoc}")
.replaceAll("(\\{@value\\s+[^}]+)\\s+(\\})", "$1$2")
.replaceAll("\n[ \t]+@", "\n@")
.replaceAll("(\\{@code)(\\x20)(\\s+.*)", "$1$3");
return s;
.replaceAll("\n[ \t]+@", "\n@");
}
int copyLiteral(String s, int start, StringBuilder sb) {
int depth = 0;
for (int i = start; i < s.length(); i++) {
char ch = s.charAt(i);
if (i == start && !Character.isWhitespace(ch)) {
sb.append(' ');
}
switch (ch) {
case '{':
depth++;
break;
case '}':
depth--;
if (depth < 0) {
sb.append(ch);
return i + 1;
}
break;
}
sb.append(ch);
}
return s.length();
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 7021614
* @bug 7021614 8241780
* @summary extend com.sun.source API to support parsing javadoc comments
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.file
@ -99,6 +99,21 @@ DocComment[DOC_COMMENT, pos:1
]
*/
/**
* {@literal
* @tag
* }
*/
void embedded_at() { }
/*
DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Literal[LITERAL, pos:1, |_@tag|_]
body: empty
block tags: empty
]
*/
/** {@literal if (a < b) { } */
void unterminated_1() { }
@ -123,14 +138,10 @@ DocComment[DOC_COMMENT, pos:1
firstSentence: 1
Erroneous[ERRONEOUS, pos:1
code: compiler.err.dc.unterminated.inline.tag
body: {@literal_if_(a_<_b)_{_}
body: {@literal_if_(a_...<_b)_{_}|_@author_jjg
]
body: empty
block tags: 1
Author[AUTHOR, pos:27
name: 1
Text[TEXT, pos:35, jjg]
]
block tags: empty
]
*/

View File

@ -122,9 +122,9 @@ TEXT:some text
erroneous2:
DOC_COMMENT:First sentence.
*
* <p>Description with {@unknownInlineTag }, {@unknownInlineTag text}, {@unknownInlineTag
* <p>Description with {@unknownInlineTag }, {@unknownInlineTag text}
*
* @param p1 p {@unknownInlineTag text
* @param p1 p {@unknownInlineTag text}
* @param p2 p <
* @param p3 p <em
* @param p4 p <!--
@ -142,12 +142,11 @@ TEXT:
TEXT:,!trailing-whitespace!
UNKNOWN_INLINE_TAG:{@unknownInlineTag text}
TEXT:text
TEXT:,!trailing-whitespace!
ERRONEOUS:{@unknownInlineTag
PARAM:@param p1 p {@unknownInlineTag text
PARAM:@param p1 p {@unknownInlineTag text}
IDENTIFIER:p1
TEXT:p!trailing-whitespace!
ERRONEOUS:{@unknownInlineTag text
UNKNOWN_INLINE_TAG:{@unknownInlineTag text}
TEXT:text
PARAM:@param p2 p <
IDENTIFIER:p2
TEXT:p!trailing-whitespace!

View File

@ -73,9 +73,9 @@ public class TestPositionSource {
/**First sentence.
*
* <p>Description with {@unknownInlineTag }, {@unknownInlineTag text}, {@unknownInlineTag
* <p>Description with {@unknownInlineTag }, {@unknownInlineTag text}
*
* @param p1 p {@unknownInlineTag text
* @param p1 p {@unknownInlineTag text}
* @param p2 p <
* @param p3 p <em
* @param p4 p <!--