langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
changeset 22163 3651128c74eb
parent 22155 2f0a83a98593
child 22165 ec53c8946fc2
equal deleted inserted replaced
22162:3b3e23e67329 22163:3651128c74eb
  1008         }
  1008         }
  1009 
  1009 
  1010         /** optimization: To save allocating a new operand/operator stack
  1010         /** optimization: To save allocating a new operand/operator stack
  1011          *  for every binary operation, we use supplys.
  1011          *  for every binary operation, we use supplys.
  1012          */
  1012          */
  1013         ArrayList<JCExpression[]> odStackSupply = new ArrayList<JCExpression[]>();
  1013         ArrayList<JCExpression[]> odStackSupply = new ArrayList<>();
  1014         ArrayList<Token[]> opStackSupply = new ArrayList<Token[]>();
  1014         ArrayList<Token[]> opStackSupply = new ArrayList<>();
  1015 
  1015 
  1016         private JCExpression[] newOdStack() {
  1016         private JCExpression[] newOdStack() {
  1017             if (odStackSupply.isEmpty())
  1017             if (odStackSupply.isEmpty())
  1018                 return new JCExpression[infixPrecedenceLevels + 1];
  1018                 return new JCExpression[infixPrecedenceLevels + 1];
  1019             return odStackSupply.remove(odStackSupply.size() - 1);
  1019             return odStackSupply.remove(odStackSupply.size() - 1);
  1312                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
  1312                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
  1313                             //this is an unbound method reference whose qualifier
  1313                             //this is an unbound method reference whose qualifier
  1314                             //is a generic type i.e. A<S>::m
  1314                             //is a generic type i.e. A<S>::m
  1315                             int pos1 = token.pos;
  1315                             int pos1 = token.pos;
  1316                             accept(LT);
  1316                             accept(LT);
  1317                             ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
  1317                             ListBuffer<JCExpression> args = new ListBuffer<>();
  1318                             args.append(typeArgument());
  1318                             args.append(typeArgument());
  1319                             while (token.kind == COMMA) {
  1319                             while (token.kind == COMMA) {
  1320                                 nextToken();
  1320                                 nextToken();
  1321                                 args.append(typeArgument());
  1321                                 args.append(typeArgument());
  1322                             }
  1322                             }
  1694 
  1694 
  1695     enum ParensResult {
  1695     enum ParensResult {
  1696         CAST,
  1696         CAST,
  1697         EXPLICIT_LAMBDA,
  1697         EXPLICIT_LAMBDA,
  1698         IMPLICIT_LAMBDA,
  1698         IMPLICIT_LAMBDA,
  1699         PARENS;
  1699         PARENS
  1700     }
  1700     }
  1701 
  1701 
  1702     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
  1702     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
  1703         List<JCVariableDecl> params = explicitParams ?
  1703         List<JCVariableDecl> params = explicitParams ?
  1704                 formalParameters(true) :
  1704                 formalParameters(true) :
  2170             } else {
  2170             } else {
  2171                 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
  2171                 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
  2172                 return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
  2172                 return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
  2173             }
  2173             }
  2174         } else {
  2174         } else {
  2175             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  2175             ListBuffer<JCExpression> dims = new ListBuffer<>();
  2176 
  2176 
  2177             // maintain array dimension type annotations
  2177             // maintain array dimension type annotations
  2178             ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
  2178             ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
  2179             dimAnnotations.append(annos);
  2179             dimAnnotations.append(annos);
  2180 
  2180 
  2224 
  2224 
  2225     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  2225     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  2226      */
  2226      */
  2227     JCExpression arrayInitializer(int newpos, JCExpression t) {
  2227     JCExpression arrayInitializer(int newpos, JCExpression t) {
  2228         accept(LBRACE);
  2228         accept(LBRACE);
  2229         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  2229         ListBuffer<JCExpression> elems = new ListBuffer<>();
  2230         if (token.kind == COMMA) {
  2230         if (token.kind == COMMA) {
  2231             nextToken();
  2231             nextToken();
  2232         } else if (token.kind != RBRACE) {
  2232         } else if (token.kind != RBRACE) {
  2233             elems.append(variableInitializer());
  2233             elems.append(variableInitializer());
  2234             while (token.kind == COMMA) {
  2234             while (token.kind == COMMA) {
  2286      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  2286      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  2287      */
  2287      */
  2288     @SuppressWarnings("fallthrough")
  2288     @SuppressWarnings("fallthrough")
  2289     List<JCStatement> blockStatements() {
  2289     List<JCStatement> blockStatements() {
  2290         //todo: skip to anchor on error(?)
  2290         //todo: skip to anchor on error(?)
  2291         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  2291         ListBuffer<JCStatement> stats = new ListBuffer<>();
  2292         while (true) {
  2292         while (true) {
  2293             List<JCStatement> stat = blockStatement();
  2293             List<JCStatement> stat = blockStatement();
  2294             if (stat.isEmpty()) {
  2294             if (stat.isEmpty()) {
  2295                 return stats.toList();
  2295                 return stats.toList();
  2296             } else {
  2296             } else {
  2354                 allowEnums && token.kind == ENUM) {
  2354                 allowEnums && token.kind == ENUM) {
  2355                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2355                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2356             } else {
  2356             } else {
  2357                 JCExpression t = parseType();
  2357                 JCExpression t = parseType();
  2358                 ListBuffer<JCStatement> stats =
  2358                 ListBuffer<JCStatement> stats =
  2359                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  2359                         variableDeclarators(mods, t, new ListBuffer<>());
  2360                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2360                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2361                 storeEnd(stats.last(), token.endPos);
  2361                 storeEnd(stats.last(), token.endPos);
  2362                 accept(SEMI);
  2362                 accept(SEMI);
  2363                 return stats.toList();
  2363                 return stats.toList();
  2364             }
  2364             }
  2392             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2392             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2393                 pos = token.pos;
  2393                 pos = token.pos;
  2394                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2394                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2395                 F.at(pos);
  2395                 F.at(pos);
  2396                 ListBuffer<JCStatement> stats =
  2396                 ListBuffer<JCStatement> stats =
  2397                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  2397                         variableDeclarators(mods, t, new ListBuffer<>());
  2398                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2398                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2399                 storeEnd(stats.last(), token.endPos);
  2399                 storeEnd(stats.last(), token.endPos);
  2400                 accept(SEMI);
  2400                 accept(SEMI);
  2401                 return stats.toList();
  2401                 return stats.toList();
  2402             } else {
  2402             } else {
  2493                 nextToken();
  2493                 nextToken();
  2494                 resources = resources();
  2494                 resources = resources();
  2495                 accept(RPAREN);
  2495                 accept(RPAREN);
  2496             }
  2496             }
  2497             JCBlock body = block();
  2497             JCBlock body = block();
  2498             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  2498             ListBuffer<JCCatch> catchers = new ListBuffer<>();
  2499             JCBlock finalizer = null;
  2499             JCBlock finalizer = null;
  2500             if (token.kind == CATCH || token.kind == FINALLY) {
  2500             if (token.kind == CATCH || token.kind == FINALLY) {
  2501                 while (token.kind == CATCH) catchers.append(catchClause());
  2501                 while (token.kind == CATCH) catchers.append(catchClause());
  2502                 if (token.kind == FINALLY) {
  2502                 if (token.kind == FINALLY) {
  2503                     nextToken();
  2503                     nextToken();
  2641     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  2641     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  2642      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  2642      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  2643      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  2643      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  2644      */
  2644      */
  2645     List<JCCase> switchBlockStatementGroups() {
  2645     List<JCCase> switchBlockStatementGroups() {
  2646         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  2646         ListBuffer<JCCase> cases = new ListBuffer<>();
  2647         while (true) {
  2647         while (true) {
  2648             int pos = token.pos;
  2648             int pos = token.pos;
  2649             switch (token.kind) {
  2649             switch (token.kind) {
  2650             case CASE:
  2650             case CASE:
  2651             case DEFAULT:
  2651             case DEFAULT:
  2728     /** ForUpdate = StatementExpression MoreStatementExpressions
  2728     /** ForUpdate = StatementExpression MoreStatementExpressions
  2729      */
  2729      */
  2730     List<JCExpressionStatement> forUpdate() {
  2730     List<JCExpressionStatement> forUpdate() {
  2731         return moreStatementExpressions(token.pos,
  2731         return moreStatementExpressions(token.pos,
  2732                                         parseExpression(),
  2732                                         parseExpression(),
  2733                                         new ListBuffer<JCExpressionStatement>()).toList();
  2733                                         new ListBuffer<>()).toList();
  2734     }
  2734     }
  2735 
  2735 
  2736     /** AnnotationsOpt = { '@' Annotation }
  2736     /** AnnotationsOpt = { '@' Annotation }
  2737      *
  2737      *
  2738      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2738      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2739      */
  2739      */
  2740     List<JCAnnotation> annotationsOpt(Tag kind) {
  2740     List<JCAnnotation> annotationsOpt(Tag kind) {
  2741         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  2741         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  2742         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  2742         ListBuffer<JCAnnotation> buf = new ListBuffer<>();
  2743         int prevmode = mode;
  2743         int prevmode = mode;
  2744         while (token.kind == MONKEYS_AT) {
  2744         while (token.kind == MONKEYS_AT) {
  2745             int pos = token.pos;
  2745             int pos = token.pos;
  2746             nextToken();
  2746             nextToken();
  2747             buf.append(annotation(pos, kind));
  2747             buf.append(annotation(pos, kind));
  2766     JCModifiers modifiersOpt() {
  2766     JCModifiers modifiersOpt() {
  2767         return modifiersOpt(null);
  2767         return modifiersOpt(null);
  2768     }
  2768     }
  2769     protected JCModifiers modifiersOpt(JCModifiers partial) {
  2769     protected JCModifiers modifiersOpt(JCModifiers partial) {
  2770         long flags;
  2770         long flags;
  2771         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  2771         ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
  2772         int pos;
  2772         int pos;
  2773         if (partial == null) {
  2773         if (partial == null) {
  2774             flags = 0;
  2774             flags = 0;
  2775             pos = token.pos;
  2775             pos = token.pos;
  2776         } else {
  2776         } else {
  2866     }
  2866     }
  2867 
  2867 
  2868     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  2868     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  2869     List<JCExpression> annotationFieldValues() {
  2869     List<JCExpression> annotationFieldValues() {
  2870         accept(LPAREN);
  2870         accept(LPAREN);
  2871         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2871         ListBuffer<JCExpression> buf = new ListBuffer<>();
  2872         if (token.kind != RPAREN) {
  2872         if (token.kind != RPAREN) {
  2873             buf.append(annotationFieldValue());
  2873             buf.append(annotationFieldValue());
  2874             while (token.kind == COMMA) {
  2874             while (token.kind == COMMA) {
  2875                 nextToken();
  2875                 nextToken();
  2876                 buf.append(annotationFieldValue());
  2876                 buf.append(annotationFieldValue());
  2911             nextToken();
  2911             nextToken();
  2912             return annotation(pos, Tag.ANNOTATION);
  2912             return annotation(pos, Tag.ANNOTATION);
  2913         case LBRACE:
  2913         case LBRACE:
  2914             pos = token.pos;
  2914             pos = token.pos;
  2915             accept(LBRACE);
  2915             accept(LBRACE);
  2916             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2916             ListBuffer<JCExpression> buf = new ListBuffer<>();
  2917             if (token.kind == COMMA) {
  2917             if (token.kind == COMMA) {
  2918                 nextToken();
  2918                 nextToken();
  2919             } else if (token.kind != RBRACE) {
  2919             } else if (token.kind != RBRACE) {
  2920                 buf.append(annotationValue());
  2920                 buf.append(annotationValue());
  2921                 while (token.kind == COMMA) {
  2921                 while (token.kind == COMMA) {
  3033     }
  3033     }
  3034 
  3034 
  3035     /** Resources = Resource { ";" Resources }
  3035     /** Resources = Resource { ";" Resources }
  3036      */
  3036      */
  3037     List<JCTree> resources() {
  3037     List<JCTree> resources() {
  3038         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3038         ListBuffer<JCTree> defs = new ListBuffer<>();
  3039         defs.append(resource());
  3039         defs.append(resource());
  3040         while (token.kind == SEMI) {
  3040         while (token.kind == SEMI) {
  3041             // All but last of multiple declarators must subsume a semicolon
  3041             // All but last of multiple declarators must subsume a semicolon
  3042             storeEnd(defs.last(), token.endPos);
  3042             storeEnd(defs.last(), token.endPos);
  3043             int semiColonPos = token.pos;
  3043             int semiColonPos = token.pos;
  3083             }
  3083             }
  3084             nextToken();
  3084             nextToken();
  3085             pid = qualident(false);
  3085             pid = qualident(false);
  3086             accept(SEMI);
  3086             accept(SEMI);
  3087         }
  3087         }
  3088         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3088         ListBuffer<JCTree> defs = new ListBuffer<>();
  3089         boolean checkForImports = true;
  3089         boolean checkForImports = true;
  3090         boolean firstTypeDecl = true;
  3090         boolean firstTypeDecl = true;
  3091         while (token.kind != EOF) {
  3091         while (token.kind != EOF) {
  3092             if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
  3092             if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
  3093                 // error recovery
  3093                 // error recovery
  3292     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  3292     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  3293      *                  [ ";" {ClassBodyDeclaration} ] "}"
  3293      *                  [ ";" {ClassBodyDeclaration} ] "}"
  3294      */
  3294      */
  3295     List<JCTree> enumBody(Name enumName) {
  3295     List<JCTree> enumBody(Name enumName) {
  3296         accept(LBRACE);
  3296         accept(LBRACE);
  3297         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3297         ListBuffer<JCTree> defs = new ListBuffer<>();
  3298         if (token.kind == COMMA) {
  3298         if (token.kind == COMMA) {
  3299             nextToken();
  3299             nextToken();
  3300         } else if (token.kind != RBRACE && token.kind != SEMI) {
  3300         } else if (token.kind != RBRACE && token.kind != SEMI) {
  3301             defs.append(enumeratorDeclaration(enumName));
  3301             defs.append(enumeratorDeclaration(enumName));
  3302             while (token.kind == COMMA) {
  3302             while (token.kind == COMMA) {
  3361     }
  3361     }
  3362 
  3362 
  3363     /** TypeList = Type {"," Type}
  3363     /** TypeList = Type {"," Type}
  3364      */
  3364      */
  3365     List<JCExpression> typeList() {
  3365     List<JCExpression> typeList() {
  3366         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  3366         ListBuffer<JCExpression> ts = new ListBuffer<>();
  3367         ts.append(parseType());
  3367         ts.append(parseType());
  3368         while (token.kind == COMMA) {
  3368         while (token.kind == COMMA) {
  3369             nextToken();
  3369             nextToken();
  3370             ts.append(parseType());
  3370             ts.append(parseType());
  3371         }
  3371         }
  3381             // error recovery
  3381             // error recovery
  3382             skip(false, true, false, false);
  3382             skip(false, true, false, false);
  3383             if (token.kind == LBRACE)
  3383             if (token.kind == LBRACE)
  3384                 nextToken();
  3384                 nextToken();
  3385         }
  3385         }
  3386         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3386         ListBuffer<JCTree> defs = new ListBuffer<>();
  3387         while (token.kind != RBRACE && token.kind != EOF) {
  3387         while (token.kind != RBRACE && token.kind != EOF) {
  3388             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  3388             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  3389             if (token.pos <= endPosTable.errorEndPos) {
  3389             if (token.pos <= endPosTable.errorEndPos) {
  3390                // error recovery
  3390                // error recovery
  3391                skip(false, true, true, false);
  3391                skip(false, true, true, false);
  3556     }
  3556     }
  3557 
  3557 
  3558     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  3558     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  3559      */
  3559      */
  3560     List<JCExpression> qualidentList() {
  3560     List<JCExpression> qualidentList() {
  3561         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  3561         ListBuffer<JCExpression> ts = new ListBuffer<>();
  3562 
  3562 
  3563         List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  3563         List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  3564         JCExpression qi = qualident(true);
  3564         JCExpression qi = qualident(true);
  3565         if (!typeAnnos.isEmpty()) {
  3565         if (!typeAnnos.isEmpty()) {
  3566             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  3566             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  3589      *  }
  3589      *  }
  3590      */
  3590      */
  3591     List<JCTypeParameter> typeParametersOpt() {
  3591     List<JCTypeParameter> typeParametersOpt() {
  3592         if (token.kind == LT) {
  3592         if (token.kind == LT) {
  3593             checkGenerics();
  3593             checkGenerics();
  3594             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  3594             ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
  3595             nextToken();
  3595             nextToken();
  3596             typarams.append(typeParameter());
  3596             typarams.append(typeParameter());
  3597             while (token.kind == COMMA) {
  3597             while (token.kind == COMMA) {
  3598                 nextToken();
  3598                 nextToken();
  3599                 typarams.append(typeParameter());
  3599                 typarams.append(typeParameter());
  3614      */
  3614      */
  3615     JCTypeParameter typeParameter() {
  3615     JCTypeParameter typeParameter() {
  3616         int pos = token.pos;
  3616         int pos = token.pos;
  3617         List<JCAnnotation> annos = typeAnnotationsOpt();
  3617         List<JCAnnotation> annos = typeAnnotationsOpt();
  3618         Name name = ident();
  3618         Name name = ident();
  3619         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  3619         ListBuffer<JCExpression> bounds = new ListBuffer<>();
  3620         if (token.kind == EXTENDS) {
  3620         if (token.kind == EXTENDS) {
  3621             nextToken();
  3621             nextToken();
  3622             bounds.append(parseType());
  3622             bounds.append(parseType());
  3623             while (token.kind == AMP) {
  3623             while (token.kind == AMP) {
  3624                 nextToken();
  3624                 nextToken();
  3634      */
  3634      */
  3635     List<JCVariableDecl> formalParameters() {
  3635     List<JCVariableDecl> formalParameters() {
  3636         return formalParameters(false);
  3636         return formalParameters(false);
  3637     }
  3637     }
  3638     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
  3638     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
  3639         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  3639         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
  3640         JCVariableDecl lastParam;
  3640         JCVariableDecl lastParam;
  3641         accept(LPAREN);
  3641         accept(LPAREN);
  3642         if (token.kind != RPAREN) {
  3642         if (token.kind != RPAREN) {
  3643             this.allowThisIdent = true;
  3643             this.allowThisIdent = true;
  3644             lastParam = formalParameter(lambdaParameters);
  3644             lastParam = formalParameter(lambdaParameters);
  3659 
  3659 
  3660     List<JCVariableDecl> implicitParameters(boolean hasParens) {
  3660     List<JCVariableDecl> implicitParameters(boolean hasParens) {
  3661         if (hasParens) {
  3661         if (hasParens) {
  3662             accept(LPAREN);
  3662             accept(LPAREN);
  3663         }
  3663         }
  3664         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  3664         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
  3665         if (token.kind != RPAREN && token.kind != ARROW) {
  3665         if (token.kind != RPAREN && token.kind != ARROW) {
  3666             params.append(implicitParameter());
  3666             params.append(implicitParameter());
  3667             while (token.kind == COMMA) {
  3667             while (token.kind == COMMA) {
  3668                 nextToken();
  3668                 nextToken();
  3669                 params.append(implicitParameter());
  3669                 params.append(implicitParameter());
  4049 
  4049 
  4050         private final Map<JCTree, Integer> endPosMap;
  4050         private final Map<JCTree, Integer> endPosMap;
  4051 
  4051 
  4052         SimpleEndPosTable(JavacParser parser) {
  4052         SimpleEndPosTable(JavacParser parser) {
  4053             super(parser);
  4053             super(parser);
  4054             endPosMap = new HashMap<JCTree, Integer>();
  4054             endPosMap = new HashMap<>();
  4055         }
  4055         }
  4056 
  4056 
  4057         public void storeEnd(JCTree tree, int endpos) {
  4057         public void storeEnd(JCTree tree, int endpos) {
  4058             endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
  4058             endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
  4059         }
  4059         }