< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java

Print this page

        

*** 36,46 **** import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Source.Feature; import com.sun.tools.javac.parser.Tokens.*; import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; import com.sun.tools.javac.resources.CompilerProperties.Errors; - import com.sun.tools.javac.resources.CompilerProperties.Fragments; import com.sun.tools.javac.resources.CompilerProperties.Warnings; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; --- 36,45 ----
*** 99,113 **** /** The Preview language setting. */ private Preview preview; /** The name table. */ ! private Names names; /** End position mappings container */ protected final AbstractEndPosTable endPosTable; // Because of javac's limited lookahead, some contexts are ambiguous in // the presence of type annotations even though they are not ambiguous // in the absence of type annotations. Consider this code: // void m(String [] m) { } // void m(String ... m) { } --- 98,114 ---- /** The Preview language setting. */ private Preview preview; /** The name table. */ ! protected Names names; /** End position mappings container */ protected final AbstractEndPosTable endPosTable; + private final boolean debug; + // Because of javac's limited lookahead, some contexts are ambiguous in // the presence of type annotations even though they are not ambiguous // in the absence of type annotations. Consider this code: // void m(String [] m) { } // void m(String ... m) { }
*** 182,191 **** --- 183,193 ---- this.keepLineMap = keepLineMap; this.errorTree = F.Erroneous(); endPosTable = newEndPosTable(keepEndPositions); this.allowYieldStatement = (!preview.isPreview(Feature.SWITCH_EXPRESSION) || preview.isEnabled()) && Feature.SWITCH_EXPRESSION.allowedInSource(source); + debug = fac.options.isSet("debug"); } protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { return keepEndPositions ? new SimpleEndPosTable(this)
*** 891,900 **** --- 893,903 ---- } } /* Expression2Rest = {infixop Expression3} * | Expression3 instanceof Type + * | Expression3 instanceof Pattern * infixop = "||" * | "&&" * | "|" * | "^" * | "&"
*** 913,929 **** odStack[0] = t; int startPos = token.pos; Token topOp = Tokens.DUMMY; while (prec(token.kind) >= minprec) { opStack[top] = topOp; ! top++; ! topOp = token; ! nextToken(); ! odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { ! odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], ! odStack[top]); top--; topOp = opStack[top]; } } Assert.check(top == 0); --- 916,942 ---- odStack[0] = t; int startPos = token.pos; Token topOp = Tokens.DUMMY; while (prec(token.kind) >= minprec) { opStack[top] = topOp; ! ! if (token.kind == INSTANCEOF) { ! int pos = token.pos; ! nextToken(); ! JCTree pattern = parseType(); ! if (token.kind == IDENTIFIER) { ! pattern = toP(F.at(token.pos).BindingPattern(ident(), pattern)); ! } ! odStack[top] = F.at(pos).TypeTest(odStack[top], pattern); ! } else { ! topOp = token; ! nextToken(); ! top++; ! odStack[top] = term3(); ! } while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { ! odStack[top - 1] = F.at(topOp.pos).Binary(optag(topOp.kind), odStack[top - 1], odStack[top]); top--; topOp = opStack[top]; } } Assert.check(top == 0);
*** 936,958 **** odStackSupply.add(odStack); opStackSupply.add(opStack); return t; } //where - /** Construct a binary or type test node. - */ - private JCExpression makeOp(int pos, - TokenKind topOp, - JCExpression od1, - JCExpression od2) - { - if (topOp == INSTANCEOF) { - return F.at(pos).TypeTest(od1, od2); - } else { - return F.at(pos).Binary(optag(topOp), od1, od2); - } - } /** If tree is a concatenation of string literals, replace it * by a single literal representing the concatenated string. */ protected JCExpression foldStrings(JCExpression tree) { if (!allowStringFolding) --- 949,958 ----
*** 2398,2408 **** { List<JCExpression> args = arguments(); JCClassDecl body = null; if (token.kind == LBRACE) { int pos = token.pos; ! List<JCTree> defs = classOrInterfaceBody(names.empty, false); JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); body = toP(F.at(pos).AnonymousClassDef(mods, defs)); } return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); } --- 2398,2408 ---- { List<JCExpression> args = arguments(); JCClassDecl body = null; if (token.kind == LBRACE) { int pos = token.pos; ! List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false); JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); body = toP(F.at(pos).AnonymousClassDef(mods, defs)); } return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); }
*** 2533,2542 **** --- 2533,2543 ---- /**This method parses a statement appearing inside a block. */ @SuppressWarnings("fallthrough") List<JCStatement> blockStatement() { //todo: skip to anchor on error(?) + Comment dc; int pos = token.pos; switch (token.kind) { case RBRACE: case CASE: case DEFAULT: case EOF: return List.nil(); case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
*** 2544,2577 **** case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: case ASSERT: return List.of(parseSimpleStatement()); case MONKEYS_AT: case FINAL: { ! Comment dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); if (token.kind == INTERFACE || token.kind == CLASS || token.kind == ENUM) { ! return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); } else { JCExpression t = parseType(true); return localVariableDeclarations(mods, t); } } case ABSTRACT: case STRICTFP: { ! Comment dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); ! return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); } case INTERFACE: case CLASS: ! Comment dc = token.comment(CommentStyle.JAVADOC); ! return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); case ENUM: log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum); dc = token.comment(CommentStyle.JAVADOC); ! return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); case IDENTIFIER: if (token.name() == names.yield && allowYieldStatement) { Token next = S.token(1); boolean isYieldStatement; switch (next.kind) { --- 2545,2578 ---- case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: case ASSERT: return List.of(parseSimpleStatement()); case MONKEYS_AT: case FINAL: { ! dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); if (token.kind == INTERFACE || token.kind == CLASS || token.kind == ENUM) { ! return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc)); } else { JCExpression t = parseType(true); return localVariableDeclarations(mods, t); } } case ABSTRACT: case STRICTFP: { ! dc = token.comment(CommentStyle.JAVADOC); JCModifiers mods = modifiersOpt(); ! return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc)); } case INTERFACE: case CLASS: ! dc = token.comment(CommentStyle.JAVADOC); ! return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); case ENUM: log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum); dc = token.comment(CommentStyle.JAVADOC); ! return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); case IDENTIFIER: if (token.name() == names.yield && allowYieldStatement) { Token next = S.token(1); boolean isYieldStatement; switch (next.kind) {
*** 2614,2624 **** return List.of(toP(F.at(pos).Yield(t))); } //else intentional fall-through } ! default: Token prevToken = token; JCExpression t = term(EXPR | TYPE); if (token.kind == COLON && t.hasTag(IDENT)) { nextToken(); JCStatement stat = parseStatementAsBlock(); --- 2615,2632 ---- return List.of(toP(F.at(pos).Yield(t))); } //else intentional fall-through } ! } ! 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)); ! } else { Token prevToken = token; JCExpression t = term(EXPR | TYPE); if (token.kind == COLON && t.hasTag(IDENT)) { nextToken(); JCStatement stat = parseStatementAsBlock();
*** 3060,3069 **** --- 3068,3094 ---- case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; case STRICTFP : flag = Flags.STRICTFP; break; case MONKEYS_AT : flag = Flags.ANNOTATION; break; case DEFAULT : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break; case ERROR : flag = 0; nextToken(); break; + case IDENTIFIER : { + if (token.name() == names.non && peekToken(0, TokenKind.SUB, TokenKind.IDENTIFIER)) { + Token tokenSub = S.token(1); + Token tokenSealed = S.token(2); + if (token.endPos == tokenSub.pos && tokenSub.endPos == tokenSealed.pos && tokenSealed.name() == names.sealed) { + flag = Flags.NON_SEALED; + nextToken(); + nextToken(); + break; + } + } + if (token.name() == names.sealed) { + flag = Flags.SEALED; + break; + } + break loop; + } default: break loop; } if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier); lastPos = token.pos; nextToken();
*** 3304,3313 **** --- 3329,3342 ---- } } return false; } + boolean isRestrictedRecordTypeName(Name name) { + return Feature.RECORDS.allowedInSource(source) && name == names.record; + } + /** VariableDeclaratorId = Ident BracketsOpt */ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { return variableDeclaratorId(mods, type, false); }
*** 3625,3646 **** int pos = token.pos; if (mods == null && token.kind == SEMI) { nextToken(); return toP(F.at(pos).Skip()); } else { ! return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment); } } /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) * @param mods Any modifiers starting the class or interface declaration * @param dc The documentation comment for the class, or null. */ ! protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) { if (token.kind == CLASS) { return classDeclaration(mods, dc); } else if (token.kind == INTERFACE) { return interfaceDeclaration(mods, dc); } else if (token.kind == ENUM) { return enumDeclaration(mods, dc); } else { --- 3654,3677 ---- int pos = token.pos; if (mods == null && token.kind == SEMI) { nextToken(); return toP(F.at(pos).Skip()); } else { ! return classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment); } } /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) * @param mods Any modifiers starting the class or interface declaration * @param dc The documentation comment for the class, or null. */ ! protected JCStatement classOrRecordOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) { if (token.kind == CLASS) { return classDeclaration(mods, dc); + } if (isRecordToken()) { + return recordDeclaration(mods, dc); } else if (token.kind == INTERFACE) { return interfaceDeclaration(mods, dc); } else if (token.kind == ENUM) { return enumDeclaration(mods, dc); } else {
*** 3654,3664 **** } final JCErroneous erroneousTree; if (parseModuleInfo) { erroneousTree = syntaxError(pos, errs, Errors.ExpectedModuleOrOpen); } else { ! erroneousTree = syntaxError(pos, errs, Errors.Expected3(CLASS, INTERFACE, ENUM)); } return toP(F.Exec(erroneousTree)); } } --- 3685,3695 ---- } final JCErroneous erroneousTree; if (parseModuleInfo) { erroneousTree = syntaxError(pos, errs, Errors.ExpectedModuleOrOpen); } else { ! erroneousTree = syntaxError(pos, errs, Errors.Expected4(CLASS, INTERFACE, ENUM, RECORD)); } return toP(F.Exec(erroneousTree)); } }
*** 3682,3707 **** List<JCExpression> implementing = List.nil(); if (token.kind == IMPLEMENTS) { nextToken(); implementing = typeList(); } ! List<JCTree> defs = classOrInterfaceBody(name, false); JCClassDecl result = toP(F.at(pos).ClassDef( ! mods, name, typarams, extending, implementing, defs)); attach(result, dc); return result; } Name typeName() { int pos = token.pos; Name name = ident(); if (isRestrictedTypeName(name, pos, true)) { reportSyntaxError(pos, Errors.RestrictedTypeNotAllowed(name, name == names.var ? Source.JDK10 : Source.JDK13)); } return name; } /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt * [EXTENDS TypeList] InterfaceBody * @param mods The modifiers starting the interface declaration * @param dc The documentation comment for the interface, or null. */ --- 3713,3837 ---- List<JCExpression> implementing = List.nil(); if (token.kind == IMPLEMENTS) { nextToken(); implementing = typeList(); } ! List<JCExpression> permitting = List.nil(); ! if (token.kind == IDENTIFIER && token.name() == names.permits) { ! if ((mods.flags & Flags.SEALED) == 0) { ! log.error(token.pos, Errors.PermitsInNoSealedClass); ! } ! nextToken(); ! permitting = typeList(); ! } ! List<JCTree> defs = classInterfaceOrRecordBody(name, false, false); JCClassDecl result = toP(F.at(pos).ClassDef( ! mods, name, typarams, extending, implementing, permitting, defs)); ! attach(result, dc); ! return result; ! } ! ! protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) { ! int pos = token.pos; ! if ((mods.flags & Flags.ABSTRACT) != 0) { ! log.error(mods.pos, Errors.RecordCantBeAbstract); ! } ! nextToken(); ! mods.flags |= Flags.RECORD | Flags.STATIC | Flags.FINAL; ! Name name = typeName(); ! ! List<JCTypeParameter> typarams = typeParametersOpt(); ! ! List<JCVariableDecl> headerFields = ! headerFields(); ! ! List<JCExpression> implementing = List.nil(); ! if (token.kind == IMPLEMENTS) { ! nextToken(); ! implementing = typeList(); ! } ! List<JCTree> defs = List.nil(); ! defs = classInterfaceOrRecordBody(name, false, true); ! java.util.List<JCVariableDecl> fields = new ArrayList<>(); ! 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)) { ! JCMethodDecl methDef = (JCMethodDecl) def; ! if (methDef.name == names.init && methDef.params.isEmpty()) { ! if ((methDef.mods.flags & Flags.PUBLIC) == 0) { ! log.error(methDef, Errors.MethodMustBePublic(names.init)); ! } ! ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>(); ! for (JCVariableDecl param : fields) { ! tmpParams.add(F.at(param).VarDef(F.Modifiers(Flags.PARAMETER), param.name, param.vartype, null)); ! } ! methDef.params = tmpParams.toList(); ! } ! } ! } ! for (int i = fields.size() - 1; i >= 0; i--) { ! defs = defs.prepend(fields.get(i)); ! } ! JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs)); attach(result, dc); return result; } Name typeName() { int pos = token.pos; Name name = ident(); if (isRestrictedTypeName(name, pos, true)) { reportSyntaxError(pos, Errors.RestrictedTypeNotAllowed(name, name == names.var ? Source.JDK10 : Source.JDK13)); } + + if (isRestrictedRecordTypeName(name)) { + reportSyntaxError(pos, Errors.RecordNotAllowed(name)); + } return name; } + List<JCVariableDecl> headerFields() { + ListBuffer<JCVariableDecl> fields = new ListBuffer<>(); + if (token.kind == LPAREN) { + nextToken(); + // check for empty record + if (token.kind == RPAREN) { + nextToken(); + return List.nil(); + } + fields.add(headerField()); + while (token.kind == COMMA) { + nextToken(); + fields.add(headerField()); + } + accept(RPAREN); + } else { + accept(LPAREN); + } + return fields.toList(); + } + + JCVariableDecl headerField() { + JCModifiers mods = modifiersOpt(); + if (mods.flags != 0) { + log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers); + } + mods.flags |= Flags.RECORD | Flags.FINAL | Flags.PRIVATE | Flags.MANDATED; + 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 * [EXTENDS TypeList] InterfaceBody * @param mods The modifiers starting the interface declaration * @param dc The documentation comment for the interface, or null. */
*** 3716,3728 **** List<JCExpression> extending = List.nil(); if (token.kind == EXTENDS) { nextToken(); extending = typeList(); } ! List<JCTree> defs = classOrInterfaceBody(name, true); JCClassDecl result = toP(F.at(pos).ClassDef( ! mods, name, typarams, null, extending, defs)); attach(result, dc); return result; } /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody --- 3846,3867 ---- List<JCExpression> extending = List.nil(); if (token.kind == EXTENDS) { nextToken(); extending = typeList(); } ! List<JCExpression> permitting = List.nil(); ! if (token.kind == IDENTIFIER && token.name() == names.permits) { ! if ((mods.flags & Flags.SEALED) == 0) { ! log.error(token.pos, Errors.PermitsInNoSealedClass); ! } ! nextToken(); ! permitting = typeList(); ! } ! List<JCTree> defs; ! defs = classInterfaceOrRecordBody(name, true, false); JCClassDecl result = toP(F.at(pos).ClassDef( ! mods, name, typarams, null, extending, permitting, defs)); attach(result, dc); return result; } /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
*** 3771,3782 **** } } if (token.kind == SEMI) { nextToken(); while (token.kind != RBRACE && token.kind != EOF) { ! defs.appendList(classOrInterfaceBodyDeclaration(enumName, ! false)); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, true, false); } } --- 3910,3921 ---- } } if (token.kind == SEMI) { nextToken(); while (token.kind != RBRACE && token.kind != EOF) { ! defs.appendList(classOrInterfaceOrRecordBodyDeclaration(enumName, ! false, false)); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, true, false); } }
*** 3803,3813 **** List<JCExpression> args = (token.kind == LPAREN) ? arguments() : List.nil(); JCClassDecl body = null; if (token.kind == LBRACE) { JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM); ! List<JCTree> defs = classOrInterfaceBody(names.empty, false); body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); } if (args.isEmpty() && body == null) createPos = identPos; JCIdent ident = F.at(identPos).Ident(enumName); --- 3942,3952 ---- List<JCExpression> args = (token.kind == LPAREN) ? arguments() : List.nil(); JCClassDecl body = null; if (token.kind == LBRACE) { JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM); ! List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false); body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); } if (args.isEmpty() && body == null) createPos = identPos; JCIdent ident = F.at(identPos).Ident(enumName);
*** 3833,3853 **** } /** ClassBody = "{" {ClassBodyDeclaration} "}" * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" */ ! List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { accept(LBRACE); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, false, false); if (token.kind == LBRACE) nextToken(); } ListBuffer<JCTree> defs = new ListBuffer<>(); while (token.kind != RBRACE && token.kind != EOF) { ! defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, true, false); } } --- 3972,3992 ---- } /** ClassBody = "{" {ClassBodyDeclaration} "}" * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" */ ! List<JCTree> classInterfaceOrRecordBody(Name className, boolean isInterface, boolean isRecord) { accept(LBRACE); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, false, false); if (token.kind == LBRACE) nextToken(); } ListBuffer<JCTree> defs = new ListBuffer<>(); while (token.kind != RBRACE && token.kind != EOF) { ! defs.appendList(classOrInterfaceOrRecordBodyDeclaration(className, isInterface, isRecord)); if (token.pos <= endPosTable.errorEndPos) { // error recovery skip(false, true, true, false); } }
*** 3882,3903 **** * ) * | ClassOrInterfaceOrEnumDeclaration * ) * */ ! protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { if (token.kind == SEMI) { nextToken(); return List.nil(); } else { Comment dc = token.comment(CommentStyle.JAVADOC); int pos = token.pos; JCModifiers mods = modifiersOpt(); if (token.kind == CLASS || token.kind == INTERFACE || token.kind == ENUM) { ! return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); } else if (token.kind == LBRACE && (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && mods.annotations.isEmpty()) { if (isInterface) { log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.InitializerNotAllowed); --- 4021,4046 ---- * ) * | ClassOrInterfaceOrEnumDeclaration * ) * */ ! protected List<JCTree> classOrInterfaceOrRecordBodyDeclaration(Name className, boolean isInterface, boolean isRecord) { if (token.kind == SEMI) { nextToken(); return List.nil(); } else { Comment dc = token.comment(CommentStyle.JAVADOC); int pos = token.pos; JCModifiers mods = modifiersOpt(); + if (debug) { + System.out.println("read flags " + Flags.toString(mods.flags)); + } if (token.kind == CLASS || + isRecordToken() || token.kind == INTERFACE || token.kind == ENUM) { ! return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc)); } else if (token.kind == LBRACE && (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && mods.annotations.isEmpty()) { if (isInterface) { log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.InitializerNotAllowed);
*** 3930,3961 **** nextToken(); } else { // method returns types are un-annotated types type = unannotatedType(false); } ! if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidMethDeclRetTypeReq); else if (annosAfterParams.nonEmpty()) illegal(annosAfterParams.head.pos); return List.of(methodDeclaratorRest( pos, mods, null, names.init, typarams, ! isInterface, true, dc)); } else { pos = token.pos; Name name = ident(); if (token.kind == LPAREN) { return List.of(methodDeclaratorRest( pos, mods, type, name, typarams, ! isInterface, isVoid, dc)); } else if (!isVoid && typarams.isEmpty()) { ! List<JCTree> defs = ! variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, ! new ListBuffer<JCTree>(), false).toList(); ! accept(SEMI); ! storeEnd(defs.last(), S.prevToken().endPos); ! return defs; } else { pos = token.pos; List<JCTree> err; if (isVoid || typarams.nonEmpty()) { JCMethodDecl m = --- 4073,4110 ---- nextToken(); } else { // method returns types are un-annotated types type = unannotatedType(false); } ! if ((token.kind == LPAREN && !isInterface || ! isRecord && token.kind == LBRACE) && type.hasTag(IDENT)) { if (isInterface || tk.name() != className) log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidMethDeclRetTypeReq); else if (annosAfterParams.nonEmpty()) illegal(annosAfterParams.head.pos); return List.of(methodDeclaratorRest( pos, mods, null, names.init, typarams, ! isInterface, true, isRecord, dc)); } else { pos = token.pos; Name name = ident(); if (token.kind == LPAREN) { return List.of(methodDeclaratorRest( pos, mods, type, name, typarams, ! isInterface, isVoid, false, dc)); } else if (!isVoid && typarams.isEmpty()) { ! if (!isRecord || (isRecord && (mods.flags & Flags.STATIC) != 0)) { ! List<JCTree> defs = ! variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, ! new ListBuffer<JCTree>(), false).toList(); ! accept(SEMI); ! storeEnd(defs.last(), S.prevToken().endPos); ! return defs; ! } else { ! nextToken(); ! return List.of(syntaxError(pos, null, Errors.RecordFieldsMustBeInHeader)); ! } } else { pos = token.pos; List<JCTree> err; if (isVoid || typarams.nonEmpty()) { JCMethodDecl m =
*** 3971,3980 **** --- 4120,4133 ---- } } } } + boolean isRecordToken() { + return token.kind == IDENTIFIER && token.name() == names.record; + } + /** MethodDeclaratorRest = * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") * VoidMethodDeclaratorRest = * FormalParameters [THROWS TypeList] ( MethodBody | ";") * ConstructorDeclaratorRest =
*** 3984,3993 **** --- 4137,4147 ---- JCModifiers mods, JCExpression type, Name name, List<JCTypeParameter> typarams, boolean isInterface, boolean isVoid, + boolean isRecord, Comment dc) { if (isInterface) { if ((mods.flags & Flags.STATIC) != 0) { checkSourceLevel(Feature.STATIC_INTERFACE_METHODS); }
*** 3997,4012 **** } JCVariableDecl prevReceiverParam = this.receiverParam; try { this.receiverParam = null; // Parsing formalParameters sets the receiverParam, if present ! List<JCVariableDecl> params = formalParameters(); ! if (!isVoid) type = bracketsOpt(type); List<JCExpression> thrown = List.nil(); ! if (token.kind == THROWS) { ! nextToken(); ! thrown = qualidentList(true); } JCBlock body = null; JCExpression defaultValue; if (token.kind == LBRACE) { body = block(); --- 4151,4169 ---- } JCVariableDecl prevReceiverParam = this.receiverParam; try { this.receiverParam = null; // Parsing formalParameters sets the receiverParam, if present ! List<JCVariableDecl> params = List.nil(); List<JCExpression> thrown = List.nil(); ! if (!isRecord || name != names.init || token.kind == LPAREN) { ! params = formalParameters(); ! if (!isVoid) type = bracketsOpt(type); ! if (token.kind == THROWS) { ! nextToken(); ! thrown = qualidentList(true); ! } } JCBlock body = null; JCExpression defaultValue; if (token.kind == LBRACE) { body = block();
*** 4025,4035 **** if (token.kind == LBRACE) { body = block(); } } } - JCMethodDecl result = toP(F.at(pos).MethodDef(mods, name, type, typarams, receiverParam, params, thrown, body, defaultValue)); attach(result, dc); --- 4182,4191 ----
< prev index next >