--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Aug 13 10:27:32 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Aug 13 10:27:33 2019 +0200
@@ -3756,23 +3756,59 @@
List<JCTree> enumBody(Name enumName) {
accept(LBRACE);
ListBuffer<JCTree> defs = new ListBuffer<>();
+ boolean wasSemi = false;
+ boolean hasStructuralErrors = false;
+ boolean wasError = false;
if (token.kind == COMMA) {
nextToken();
- } else if (token.kind != RBRACE && token.kind != SEMI) {
- defs.append(enumeratorDeclaration(enumName));
- while (token.kind == COMMA) {
+ if (token.kind == SEMI) {
+ wasSemi = true;
nextToken();
- if (token.kind == RBRACE || token.kind == SEMI) break;
- defs.append(enumeratorDeclaration(enumName));
- }
- if (token.kind != SEMI && token.kind != RBRACE) {
- defs.append(syntaxError(token.pos, Errors.Expected3(COMMA, RBRACE, SEMI)));
- nextToken();
+ } else if (token.kind != RBRACE) {
+ reportSyntaxError(S.prevToken().endPos,
+ Errors.Expected2(RBRACE, SEMI));
+ wasError = true;
}
}
- if (token.kind == SEMI) {
- nextToken();
- while (token.kind != RBRACE && token.kind != EOF) {
+ while (token.kind != RBRACE && token.kind != EOF) {
+ if (token.kind == SEMI) {
+ accept(SEMI);
+ wasSemi = true;
+ if (token.kind == RBRACE || token.kind == EOF) break;
+ }
+ EnumeratorEstimate memberType = estimateEnumeratorOrMember(enumName);
+ if (memberType == EnumeratorEstimate.UNKNOWN) {
+ memberType = wasSemi ? EnumeratorEstimate.MEMBER
+ : EnumeratorEstimate.ENUMERATOR;
+ }
+ if (memberType == EnumeratorEstimate.ENUMERATOR) {
+ wasError = false;
+ if (wasSemi && !hasStructuralErrors) {
+ reportSyntaxError(token.pos, Errors.EnumConstantNotExpected);
+ hasStructuralErrors = true;
+ }
+ defs.append(enumeratorDeclaration(enumName));
+ if (token.pos <= endPosTable.errorEndPos) {
+ // error recovery
+ skip(false, true, true, false);
+ } else {
+ if (token.kind != RBRACE && token.kind != SEMI && token.kind != EOF) {
+ if (token.kind == COMMA) {
+ nextToken();
+ } else {
+ setErrorEndPos(token.pos);
+ reportSyntaxError(S.prevToken().endPos,
+ Errors.Expected3(COMMA, RBRACE, SEMI));
+ wasError = true;
+ }
+ }
+ }
+ } else {
+ if (!wasSemi && !hasStructuralErrors && !wasError) {
+ reportSyntaxError(token.pos, Errors.EnumConstantExpected);
+ hasStructuralErrors = true;
+ }
+ wasError = false;
defs.appendList(classOrInterfaceBodyDeclaration(enumName,
false));
if (token.pos <= endPosTable.errorEndPos) {
@@ -3785,6 +3821,28 @@
return defs.toList();
}
+ private EnumeratorEstimate estimateEnumeratorOrMember(Name enumName) {
+ if (token.kind == TokenKind.IDENTIFIER && token.name() != enumName) {
+ Token next = S.token(1);
+ switch (next.kind) {
+ case LPAREN: case LBRACE: case COMMA: case SEMI:
+ return EnumeratorEstimate.ENUMERATOR;
+ }
+ }
+ switch (token.kind) {
+ case IDENTIFIER: case MONKEYS_AT: case LT:
+ return EnumeratorEstimate.UNKNOWN;
+ default:
+ return EnumeratorEstimate.MEMBER;
+ }
+ }
+
+ private enum EnumeratorEstimate {
+ ENUMERATOR,
+ MEMBER,
+ UNKNOWN;
+ }
+
/** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
*/
JCTree enumeratorDeclaration(Name enumName) {