@@ -555,10 +555,29 @@ object Parsers {
555
555
accept(tok)
556
556
try body finally accept(tok + 1 )
557
557
558
+ /** Same as enclosed, but if closing token is missing, add `,` to the expected tokens
559
+ * in the error message provided the next token could have followed a `,`.
560
+ */
561
+ def enclosedWithCommas [T ](tok : Token , body : => T ): T =
562
+ accept(tok)
563
+ val closing = tok + 1
564
+ val isEmpty = in.token == closing
565
+ val ts = body
566
+ if in.token != closing then
567
+ val followComma =
568
+ if tok == LPAREN then canStartExprTokens3 else canStartTypeTokens
569
+ val prefix = if ! isEmpty && followComma.contains(in.token) then " ',' or " else " "
570
+ syntaxErrorOrIncomplete(ExpectedTokenButFound (closing, in.token, prefix))
571
+ if in.token == closing then in.nextToken()
572
+ ts
573
+
558
574
def inParens [T ](body : => T ): T = enclosed(LPAREN , body)
559
575
def inBraces [T ](body : => T ): T = enclosed(LBRACE , body)
560
576
def inBrackets [T ](body : => T ): T = enclosed(LBRACKET , body)
561
577
578
+ def inParensWithCommas [T ](body : => T ): T = enclosedWithCommas(LPAREN , body)
579
+ def inBracketsWithCommas [T ](body : => T ): T = enclosedWithCommas(LBRACKET , body)
580
+
562
581
def inBracesOrIndented [T ](body : => T , rewriteWithColon : Boolean = false ): T =
563
582
if in.token == INDENT then
564
583
val rewriteToBraces = in.rewriteNoIndent
@@ -1672,7 +1691,7 @@ object Parsers {
1672
1691
/** FunParamClause ::= ‘(’ TypedFunParam {‘,’ TypedFunParam } ‘)’
1673
1692
*/
1674
1693
def funParamClause (): List [ValDef ] =
1675
- inParens (commaSeparated(() => typedFunParam(in.offset, ident())))
1694
+ inParensWithCommas (commaSeparated(() => typedFunParam(in.offset, ident())))
1676
1695
1677
1696
def funParamClauses (): List [List [ValDef ]] =
1678
1697
if in.token == LPAREN then funParamClause() :: funParamClauses() else Nil
@@ -1853,7 +1872,7 @@ object Parsers {
1853
1872
else
1854
1873
def singletonArgs (t : Tree ): Tree =
1855
1874
if in.token == LPAREN && in.featureEnabled(Feature .dependent)
1856
- then singletonArgs(AppliedTypeTree (t, inParens (commaSeparated(singleton))))
1875
+ then singletonArgs(AppliedTypeTree (t, inParensWithCommas (commaSeparated(singleton))))
1857
1876
else t
1858
1877
singletonArgs(simpleType1())
1859
1878
@@ -1869,7 +1888,7 @@ object Parsers {
1869
1888
def simpleType1 () = simpleTypeRest {
1870
1889
if in.token == LPAREN then
1871
1890
atSpan(in.offset) {
1872
- makeTupleOrParens(inParens (argTypes(namedOK = false , wildOK = true )))
1891
+ makeTupleOrParens(inParensWithCommas (argTypes(namedOK = false , wildOK = true )))
1873
1892
}
1874
1893
else if in.token == LBRACE then
1875
1894
atSpan(in.offset) { RefinedTypeTree (EmptyTree , refinement(indentOK = false )) }
@@ -2022,7 +2041,8 @@ object Parsers {
2022
2041
/** TypeArgs ::= `[' Type {`,' Type} `]'
2023
2042
* NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]'
2024
2043
*/
2025
- def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = inBrackets(argTypes(namedOK, wildOK))
2044
+ def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] =
2045
+ inBracketsWithCommas(argTypes(namedOK, wildOK))
2026
2046
2027
2047
/** Refinement ::= `{' RefineStatSeq `}'
2028
2048
*/
@@ -2518,7 +2538,7 @@ object Parsers {
2518
2538
placeholderParams = param :: placeholderParams
2519
2539
atSpan(start) { Ident (pname) }
2520
2540
case LPAREN =>
2521
- atSpan(in.offset) { makeTupleOrParens(inParens (exprsInParensOrBindings())) }
2541
+ atSpan(in.offset) { makeTupleOrParens(inParensWithCommas (exprsInParensOrBindings())) }
2522
2542
case LBRACE | INDENT =>
2523
2543
canApply = false
2524
2544
blockExpr()
@@ -2616,15 +2636,15 @@ object Parsers {
2616
2636
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2617
2637
* | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
2618
2638
*/
2619
- def parArgumentExprs (): (List [Tree ], Boolean ) = inParens {
2620
- if in.token == RPAREN then
2621
- ( Nil , false )
2622
- else if isIdent(nme.using) then
2623
- in.nextToken()
2624
- (commaSeparated(argumentExpr), true )
2625
- else
2626
- (commaSeparated(argumentExpr), false )
2627
- }
2639
+ def parArgumentExprs (): (List [Tree ], Boolean ) =
2640
+ inParensWithCommas :
2641
+ if in.token == RPAREN then
2642
+ ( Nil , false )
2643
+ else if isIdent(nme.using) then
2644
+ in.nextToken( )
2645
+ (commaSeparated(argumentExpr), true )
2646
+ else
2647
+ (commaSeparated(argumentExpr), false )
2628
2648
2629
2649
/** ArgumentExprs ::= ParArgumentExprs
2630
2650
* | [nl] BlockExpr
@@ -2985,7 +3005,7 @@ object Parsers {
2985
3005
case USCORE =>
2986
3006
wildcardIdent()
2987
3007
case LPAREN =>
2988
- atSpan(in.offset) { makeTupleOrParens(inParens (patternsOpt())) }
3008
+ atSpan(in.offset) { makeTupleOrParens(inParensWithCommas (patternsOpt())) }
2989
3009
case QUOTE =>
2990
3010
simpleExpr(Location .InPattern )
2991
3011
case XMLSTART =>
@@ -3031,7 +3051,7 @@ object Parsers {
3031
3051
* | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’
3032
3052
*/
3033
3053
def argumentPatterns (): List [Tree ] =
3034
- inParens (patternsOpt(Location .InPatternArgs ))
3054
+ inParensWithCommas (patternsOpt(Location .InPatternArgs ))
3035
3055
3036
3056
/* -------- MODIFIERS and ANNOTATIONS ------------------------------------------- */
3037
3057
@@ -3220,7 +3240,7 @@ object Parsers {
3220
3240
* HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
3221
3241
* HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypePamClause] | ‘_’) TypeBounds
3222
3242
*/
3223
- def typeParamClause (ownerKind : ParamOwner ): List [TypeDef ] = inBrackets {
3243
+ def typeParamClause (ownerKind : ParamOwner ): List [TypeDef ] = inBracketsWithCommas {
3224
3244
3225
3245
def checkVarianceOK (): Boolean =
3226
3246
val ok = ownerKind != ParamOwner .Def && ownerKind != ParamOwner .TypeParam
@@ -3360,7 +3380,7 @@ object Parsers {
3360
3380
}
3361
3381
3362
3382
// begin termParamClause
3363
- inParens {
3383
+ inParensWithCommas {
3364
3384
if in.token == RPAREN && ! prefix && ! impliedMods.is(Given ) then Nil
3365
3385
else
3366
3386
val clause =
0 commit comments