changeset 55905:d85abf19424b amber-demo-II

Automatic merge with records-and-sealed
author mcimadamore
date Tue, 30 Apr 2019 00:43:17 +0200
parents eddf8682e1ee fbf54d7428f1
children 66dd561b3653
files src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
diffstat 3 files changed, 119 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Mon Apr 29 20:15:52 2019 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Apr 30 00:43:17 2019 +0200
@@ -2543,7 +2543,9 @@
             dc = token.comment(CommentStyle.JAVADOC);
             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
         }
-        if (isRecordDeclaration()) {
+        if (isRecordToken() &&
+            (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
+             peekToken(TokenKind.IDENTIFIER, TokenKind.LT))) {
             JCModifiers mods = modifiersOpt();
             dc = token.comment(CommentStyle.JAVADOC);
             return List.of(recordDeclaration(mods, dc));
@@ -3584,7 +3586,7 @@
     protected JCStatement classOrRecordOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
         if (token.kind == CLASS) {
             return classDeclaration(mods, dc);
-        } if (isRecordDeclaration()) {
+        } if (isRecordToken()) {
             return recordDeclaration(mods, dc);
         } else if (token.kind == INTERFACE) {
             return interfaceDeclaration(mods, dc);
@@ -3657,7 +3659,8 @@
 
         List<JCTypeParameter> typarams = typeParametersOpt();
 
-        Map<Name, JCVariableDecl> optHeaderFields = headerFields(mods);
+        List<JCVariableDecl> headerFields =
+                headerFields((mods.flags & Flags.ABSTRACT) != 0);
 
         List<JCExpression> implementing = List.nil();
         if (token.kind == IMPLEMENTS) {
@@ -3671,8 +3674,13 @@
             accept(SEMI);
         }
         java.util.List<JCVariableDecl> fields = new ArrayList<>();
-        for (JCVariableDecl field : optHeaderFields.values()) {
-            fields.add(field);
+        Set<Name> seenNames = new HashSet<>();
+        for (JCVariableDecl field : headerFields) {
+            if (seenNames.add(field.name)) {
+                fields.add(field);
+            } else {
+                log.error(field.pos(), Errors.RecordCantDeclareDuplicateFields);
+            }
         }
         for (JCTree def : defs) {
             if (def.hasTag(METHODDEF)) {
@@ -3710,31 +3718,34 @@
         return name;
     }
 
-    Map<Name, JCVariableDecl> headerFields(JCModifiers recordClassMods) {
-        accept(LPAREN);
-        Map<Name, JCVariableDecl> fields = new LinkedHashMap<>();
-        while (token.kind != RPAREN) {
-            JCModifiers mods = modifiersOpt();
-            if (mods.flags != 0) {
-                log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
+    List<JCVariableDecl> headerFields(boolean abstractRecord) {
+        ListBuffer<JCVariableDecl> fields = new ListBuffer<>();
+        if (token.kind == LPAREN) {
+            nextToken();
+            fields.add(headerField(abstractRecord));
+            while (token.kind == COMMA) {
+                nextToken();
+                fields.add(headerField(abstractRecord));
             }
-            mods.flags |= Flags.RECORD | Flags.FINAL | Flags.PRIVATE;
-            mods.flags |= (recordClassMods.flags & Flags.ABSTRACT) != 0 ? Flags.PROTECTED : 0;
-            JCExpression type = parseType();
-            int pos = token.pos;
-            Name id = ident();
-            if (!fields.containsKey(id)) {
-                List<Pair<Accessors.Kind, Name>> accessors = List.of(new Pair<>(Accessors.Kind.GET, id));
-                fields.put(id, toP(F.at(pos).VarDef(mods, id, type, null, accessors)));
-            } else {
-                log.error(pos, Errors.RecordCantDeclareDuplicateFields);
-            }
-            if (token.kind == COMMA) {
-                nextToken();
-            }
+            accept(RPAREN);
+        } else {
+            accept(LPAREN);
         }
-        accept(RPAREN);
-        return fields;
+        return fields.toList();
+    }
+
+    JCVariableDecl headerField(boolean abstractRecord) {
+        JCModifiers mods = modifiersOpt();
+        if (mods.flags != 0) {
+            log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
+        }
+        mods.flags |= Flags.RECORD | Flags.FINAL;
+        mods.flags |= abstractRecord ? Flags.PROTECTED : 0;
+        JCExpression type = parseType();
+        int pos = token.pos;
+        Name id = ident();
+        List<Pair<Accessors.Kind, Name>> accessors = List.of(new Pair<>(Accessors.Kind.GET, id));
+        return toP(F.at(pos).VarDef(mods, id, type, null, accessors));
     }
 
     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
@@ -3944,7 +3955,7 @@
             int pos = token.pos;
             JCModifiers mods = modifiersOpt();
             if (token.kind == CLASS ||
-                isRecordDeclaration() ||
+                isRecordToken() ||
                 token.kind == INTERFACE ||
                 token.kind == ENUM) {
                 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
@@ -4031,10 +4042,8 @@
         }
     }
 
-    boolean isRecordDeclaration() {
-        return token.kind == IDENTIFIER && token.name() == names.record &&
-                (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
-                peekToken(TokenKind.IDENTIFIER, TokenKind.LT));
+    boolean isRecordToken() {
+        return token.kind == IDENTIFIER && token.name() == names.record;
     }
 
     boolean isSealedClassDeclaration() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/datum/BadRecord.java	Tue Apr 30 00:43:17 2019 +0200
@@ -0,0 +1,52 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Verifying error recovery for broken record classes
+ * @compile/fail/ref=BadRecord.out -XDrawDiagnostics BadRecord.java
+ */
+record BadRecordb1 {}
+
+record BadRecordb2( {}
+
+record BadRecordb3(int {}
+
+record BadRecordb4(int) {}
+
+record BadRecordb5(int i {}
+
+record BadRecordb6(int i, {}
+
+record BadRecordb7(int i,) {}
+
+record BadRecordb8(int i, int {}
+
+record BadRecordb9(int i, int) {}
+
+record BadRecordba(int i, int j {}
+
+record BadRecordbb(int i, int j, {}
+
+record BadRecordbc(int i, int j,) {}
+
+record BadRecords1;
+
+record BadRecords2(;
+
+record BadRecords3(int;
+
+record BadRecords4(int);
+
+record BadRecords5(int i;
+
+record BadRecords6(int i,;
+
+record BadRecords7(int i,);
+
+record BadRecords8(int i, int;
+
+record BadRecords9(int i, int);
+
+record BadRecordsa(int i, int j;
+
+record BadRecordsb(int i, int j,;
+
+record BadRecordsc(int i, int j,);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/datum/BadRecord.out	Tue Apr 30 00:43:17 2019 +0200
@@ -0,0 +1,25 @@
+BadRecord.java:6:19: compiler.err.expected: '('
+BadRecord.java:8:21: compiler.err.illegal.start.of.type
+BadRecord.java:10:23: compiler.err.expected: token.identifier
+BadRecord.java:12:23: compiler.err.expected: token.identifier
+BadRecord.java:14:25: compiler.err.expected: ')'
+BadRecord.java:16:27: compiler.err.illegal.start.of.type
+BadRecord.java:18:26: compiler.err.illegal.start.of.type
+BadRecord.java:20:30: compiler.err.expected: token.identifier
+BadRecord.java:22:30: compiler.err.expected: token.identifier
+BadRecord.java:24:32: compiler.err.expected: ')'
+BadRecord.java:26:34: compiler.err.illegal.start.of.type
+BadRecord.java:28:33: compiler.err.illegal.start.of.type
+BadRecord.java:30:19: compiler.err.expected: '('
+BadRecord.java:32:20: compiler.err.illegal.start.of.type
+BadRecord.java:34:23: compiler.err.expected: token.identifier
+BadRecord.java:36:23: compiler.err.expected: token.identifier
+BadRecord.java:38:25: compiler.err.expected: ')'
+BadRecord.java:40:26: compiler.err.illegal.start.of.type
+BadRecord.java:42:26: compiler.err.illegal.start.of.type
+BadRecord.java:44:30: compiler.err.expected: token.identifier
+BadRecord.java:46:30: compiler.err.expected: token.identifier
+BadRecord.java:48:32: compiler.err.expected: ')'
+BadRecord.java:50:33: compiler.err.illegal.start.of.type
+BadRecord.java:52:33: compiler.err.illegal.start.of.type
+24 errors