8305673: Convert DocCommentParser to use enhanced switch

Reviewed-by: hannesw
This commit is contained in:
Jonathan Gibbons 2023-04-17 19:04:31 +00:00
parent 6831f9db8b
commit 525a91e3fa

@ -25,6 +25,7 @@
package com.sun.tools.javac.parser;
import java.io.Serial;
import java.util.HashMap;
import java.util.Map;
@ -62,6 +63,7 @@ import static com.sun.tools.javac.util.LayoutCharacters.EOI;
*/
public class DocCommentParser {
static class ParseException extends Exception {
@Serial
private static final long serialVersionUID = 0;
final int pos;
@ -117,10 +119,6 @@ public class DocCommentParser {
this(fac, diagSource, comment, false);
}
public DocCommentParser(ParserFactory fac) {
this(fac, null, null, false);
}
public DCDocComment parse() {
String c = comment.getText();
buf = new char[c.length() + 1];
@ -147,8 +145,7 @@ public class DocCommentParser {
void nextChar() {
ch = buf[bp < buflen ? ++bp : buflen];
switch (ch) {
case '\f': case '\n': case '\r':
newline = true;
case '\f', '\n', '\r' -> newline = true;
}
}
@ -186,7 +183,7 @@ public class DocCommentParser {
newline = false;
if (isFileContent) {
switch (phase) {
case PREAMBLE:
case PREAMBLE -> {
if (isEndPreamble()) {
trees.add(html());
if (textStart == -1) {
@ -197,15 +194,15 @@ public class DocCommentParser {
newline = true;
break loop;
}
break;
case BODY:
}
case BODY -> {
if (isEndBody()) {
addPendingText(trees, lastNonWhite);
break loop;
}
break;
default:
// fallthrough
}
default -> { }
}
}
addPendingText(trees, bp - 1);
@ -389,52 +386,48 @@ public class DocCommentParser {
/**
* Read plain text content of an inline tag.
* Matching pairs of { } are skipped; the text is terminated by the first
* unmatched }. It is an error if the beginning of the next tag is detected.
* Matching pairs of '{' '}' are skipped; the text is terminated by the first
* unmatched '}'. It is an error if the beginning of the next tag is detected.
*/
private DCText inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
switch (whitespacePolicy) {
case REMOVE_ALL:
case REMOVE_ALL -> {
skipWhitespace();
break;
case REMOVE_FIRST_SPACE:
}
case REMOVE_FIRST_SPACE -> {
if (ch == ' ')
nextChar();
break;
case RETAIN_ALL:
default:
// do nothing
break;
}
case RETAIN_ALL -> { }
}
int pos = bp;
int depth = 1;
loop:
while (bp < buflen) {
switch (ch) {
case '\n': case '\r': case '\f':
case ' ': case '\t':
break;
case '\n', '\r', '\f', ' ', '\t' -> {
}
case '{':
case '{' -> {
newline = false;
lastNonWhite = bp;
depth++;
break;
}
case '}':
case '}' -> {
if (--depth == 0) {
return m.at(pos).newTextTree(newString(pos, bp));
}
newline = false;
lastNonWhite = bp;
break;
}
default:
default -> {
newline = false;
lastNonWhite = bp;
break;
}
}
nextChar();
}
@ -444,10 +437,9 @@ public class DocCommentParser {
/**
* Read Java class name, possibly followed by member
* Matching pairs of {@literal < >} are skipped. The text is terminated by the first
* unmatched }. It is an error if the beginning of the next tag is detected.
* unmatched '}'. It is an error if the beginning of the next tag is detected.
*/
// TODO: improve quality of parse to forbid bad constructions.
@SuppressWarnings("fallthrough")
protected DCReference reference(ReferenceParser.Mode mode) throws ParseException {
int pos = bp;
int depth = 0;
@ -457,37 +449,37 @@ public class DocCommentParser {
loop:
while (bp < buflen) {
switch (ch) {
case '\n': case '\r': case '\f':
case ' ': case '\t':
case '\n', '\r', '\f', ' ', '\t' -> {
if (depth == 0)
break loop;
break;
}
case '(':
case '<':
case '(', '<' -> {
newline = false;
depth++;
break;
}
case ')':
case '>':
case ')', '>' -> {
newline = false;
--depth;
break;
}
case '}':
case '}' -> {
if (bp == pos)
return null;
newline = false;
break loop;
}
case '@':
case '@' -> {
if (newline)
break loop;
// fallthrough
}
default:
default -> {
newline = false;
}
}
nextChar();
@ -534,19 +526,18 @@ public class DocCommentParser {
loop:
while (bp < buflen) {
switch (ch) {
case '\n': case '\r': case '\f':
case ' ': case '\t':
break;
case '\n', '\r', '\f', ' ', '\t' -> { }
case '"':
case '"' -> {
nextChar();
// trim trailing white-space?
return m.at(pos).newTextTree(newString(pos, bp));
}
case '@':
case '@' -> {
if (newline)
break loop;
}
}
nextChar();
}
@ -563,24 +554,24 @@ public class DocCommentParser {
loop:
while (bp < buflen) {
switch (ch) {
case '\n':
case '\r': case '\f': case ' ': case '\t':
case '\n', '\r', '\f', ' ', '\t' -> {
return m.at(pos).newTextTree(newString(pos, bp));
}
case '@':
case '@' -> {
if (newline)
break loop;
break;
}
case '{':
case '{' -> {
depth++;
break;
}
case '}':
case '}' -> {
if (depth == 0)
return m.at(pos).newTextTree(newString(pos, bp));
depth--;
break;
}
}
newline = false;
nextChar();
@ -590,8 +581,8 @@ public class DocCommentParser {
/**
* Reads general text content of an inline tag, including HTML entities and elements.
* Matching pairs of { } are skipped; the text is terminated by the first
* unmatched }. It is an error if the beginning of the next tag is detected.
* Matching pairs of '{' '}' are skipped; the text is terminated by the first
* unmatched '}'. It is an error if the beginning of the next tag is detected.
*/
@SuppressWarnings("fallthrough")
private List<DCTree> inlineContent() {
@ -751,7 +742,7 @@ public class DocCommentParser {
if (isIdentifierStart(ch)) {
String name = StringUtils.toLowerCase(readIdentifier().toString());
switch (name) {
case "body":
case "body" -> {
// Check if also followed by <main>
// 1. skip rest of <body>
while (bp < buflen && ch != '>') {
@ -777,10 +768,12 @@ public class DocCommentParser {
// if <body> is _not_ followed by <main> then this is the
// end of the preamble
return true;
}
case "main":
case "main" -> {
// <main> is unconditionally the end of the preamble
return true;
}
}
}
return false;
@ -808,9 +801,9 @@ public class DocCommentParser {
if (isIdentifierStart(ch)) {
String name = StringUtils.toLowerCase(readIdentifier().toString());
switch (name) {
case "body":
case "main":
case "body", "main" -> {
return true;
}
}
}
}
@ -867,8 +860,7 @@ public class DocCommentParser {
}
if (ch == '>') {
nextChar();
DCTree dctree = m.at(p).newStartElementTree(name, attrs, selfClosing).setEndPos(bp);
return dctree;
return m.at(p).newStartElementTree(name, attrs, selfClosing).setEndPos(bp);
}
}
} else if (ch == '/') {
@ -1011,16 +1003,9 @@ public class DocCommentParser {
protected void attrValueChar(ListBuffer<DCTree> list) {
switch (ch) {
case '&':
entity(list);
break;
case '{':
inlineTag(list);
break;
default:
nextChar();
case '&' -> entity(list);
case '{' -> inlineTag(list);
default -> nextChar();
}
}
@ -1064,13 +1049,15 @@ public class DocCommentParser {
loop:
while (i > pos) {
switch (buf[i]) {
case '\f': case '\n': case '\r':
case '\f', '\n', '\r' -> {
newline = true;
break;
case '\t': case ' ':
break;
default:
}
case '\t', ' ' -> { }
default -> {
break loop;
}
}
i--;
}
@ -1146,15 +1133,11 @@ public class DocCommentParser {
}
protected boolean isUnquotedAttrValueTerminator(char ch) {
switch (ch) {
case '\f': case '\n': case '\r': case '\t':
case ' ':
case '"': case '\'': case '`':
case '=': case '<': case '>':
return true;
default:
return false;
}
return switch (ch) {
case '\f', '\n', '\r', '\t', ' ',
'"', '\'', '`', '=', '<', '>' -> true;
default -> false;
};
}
protected boolean isWhitespace(char ch) {
@ -1402,17 +1385,11 @@ public class DocCommentParser {
new TagParser(TagParser.Kind.EITHER, DCTree.Kind.RETURN) {
@Override
public DCTree parse(int pos, Kind kind) {
List<DCTree> description;
switch (kind) {
case BLOCK:
description = blockContent();
break;
case INLINE:
description = inlineContent();
break;
default:
throw new IllegalArgumentException(kind.toString());
}
List<DCTree> description = switch (kind) {
case BLOCK -> blockContent();
case INLINE -> inlineContent();
default -> throw new IllegalArgumentException(kind.toString());
};
return m.at(pos).newReturnTree(kind == Kind.INLINE, description);
}
},
@ -1423,7 +1400,7 @@ public class DocCommentParser {
public DCTree parse(int pos) throws ParseException {
skipWhitespace();
switch (ch) {
case '"':
case '"' -> {
DCText string = quotedString();
if (string != null) {
skipWhitespace();
@ -1432,30 +1409,31 @@ public class DocCommentParser {
return m.at(pos).newSeeTree(List.<DCTree>of(string));
}
}
break;
}
case '<':
case '<' -> {
List<DCTree> html = blockContent();
if (html != null)
return m.at(pos).newSeeTree(html);
break;
}
case '@':
case '@' -> {
if (newline)
throw new ParseException("dc.no.content");
break;
}
case EOI:
case EOI -> {
if (bp == buf.length - 1)
throw new ParseException("dc.no.content");
break;
}
default:
default -> {
if (isJavaIdentifierStart(ch) || ch == '#') {
DCReference ref = reference(ReferenceParser.Mode.MEMBER_OPTIONAL);
List<DCTree> description = blockContent();
return m.at(pos).newSeeTree(description.prepend(ref));
}
}
}
throw new ParseException("dc.unexpected.content");
}
@ -1613,7 +1591,7 @@ public class DocCommentParser {
// {@summary summary-text}
new TagParser(TagParser.Kind.INLINE, DCTree.Kind.SUMMARY) {
@Override
public DCTree parse(int pos) throws ParseException {
public DCTree parse(int pos) {
List<DCTree> summary = inlineContent();
return m.at(pos).newSummaryTree(summary);
}