@@ -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
@@ -1821,7 +1840,7 @@ object Parsers {
1821
1840
else
1822
1841
def singletonArgs (t : Tree ): Tree =
1823
1842
if in.token == LPAREN && in.featureEnabled(Feature .dependent)
1824
- then singletonArgs(AppliedTypeTree (t, inParens (commaSeparated(singleton))))
1843
+ then singletonArgs(AppliedTypeTree (t, inParensWithCommas (commaSeparated(singleton))))
1825
1844
else t
1826
1845
singletonArgs(simpleType1())
1827
1846
@@ -1837,7 +1856,7 @@ object Parsers {
1837
1856
def simpleType1 () = simpleTypeRest {
1838
1857
if in.token == LPAREN then
1839
1858
atSpan(in.offset) {
1840
- makeTupleOrParens(inParens (argTypes(namedOK = false , wildOK = true )))
1859
+ makeTupleOrParens(inParensWithCommas (argTypes(namedOK = false , wildOK = true )))
1841
1860
}
1842
1861
else if in.token == LBRACE then
1843
1862
atSpan(in.offset) { RefinedTypeTree (EmptyTree , refinement(indentOK = false )) }
@@ -1990,7 +2009,8 @@ object Parsers {
1990
2009
/** TypeArgs ::= `[' Type {`,' Type} `]'
1991
2010
* NamedTypeArgs ::= `[' NamedTypeArg {`,' NamedTypeArg} `]'
1992
2011
*/
1993
- def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] = inBrackets(argTypes(namedOK, wildOK))
2012
+ def typeArgs (namedOK : Boolean , wildOK : Boolean ): List [Tree ] =
2013
+ inBracketsWithCommas(argTypes(namedOK, wildOK))
1994
2014
1995
2015
/** Refinement ::= `{' RefineStatSeq `}'
1996
2016
*/
@@ -2487,7 +2507,7 @@ object Parsers {
2487
2507
placeholderParams = param :: placeholderParams
2488
2508
atSpan(start) { Ident (pname) }
2489
2509
case LPAREN =>
2490
- atSpan(in.offset) { makeTupleOrParens(inParens (exprsInParensOrBindings())) }
2510
+ atSpan(in.offset) { makeTupleOrParens(inParensWithCommas (exprsInParensOrBindings())) }
2491
2511
case LBRACE | INDENT =>
2492
2512
canApply = false
2493
2513
blockExpr()
@@ -2592,15 +2612,15 @@ object Parsers {
2592
2612
/** ParArgumentExprs ::= `(' [‘using’] [ExprsInParens] `)'
2593
2613
* | `(' [ExprsInParens `,'] PostfixExpr `*' ')'
2594
2614
*/
2595
- def parArgumentExprs (): (List [Tree ], Boolean ) = inParens {
2596
- if in.token == RPAREN then
2597
- ( Nil , false )
2598
- else if isIdent(nme.using) then
2599
- in.nextToken()
2600
- (commaSeparated(argumentExpr), true )
2601
- else
2602
- (commaSeparated(argumentExpr), false )
2603
- }
2615
+ def parArgumentExprs (): (List [Tree ], Boolean ) =
2616
+ inParensWithCommas :
2617
+ if in.token == RPAREN then
2618
+ ( Nil , false )
2619
+ else if isIdent(nme.using) then
2620
+ in.nextToken( )
2621
+ (commaSeparated(argumentExpr), true )
2622
+ else
2623
+ (commaSeparated(argumentExpr), false )
2604
2624
2605
2625
/** ArgumentExprs ::= ParArgumentExprs
2606
2626
* | [nl] BlockExpr
@@ -2957,7 +2977,7 @@ object Parsers {
2957
2977
case USCORE =>
2958
2978
wildcardIdent()
2959
2979
case LPAREN =>
2960
- atSpan(in.offset) { makeTupleOrParens(inParens (patternsOpt())) }
2980
+ atSpan(in.offset) { makeTupleOrParens(inParensWithCommas (patternsOpt())) }
2961
2981
case QUOTE =>
2962
2982
simpleExpr(Location .InPattern )
2963
2983
case XMLSTART =>
@@ -3003,7 +3023,7 @@ object Parsers {
3003
3023
* | ‘(’ [Patterns ‘,’] PatVar ‘*’ ‘)’
3004
3024
*/
3005
3025
def argumentPatterns (): List [Tree ] =
3006
- inParens (patternsOpt(Location .InPatternArgs ))
3026
+ inParensWithCommas (patternsOpt(Location .InPatternArgs ))
3007
3027
3008
3028
/* -------- MODIFIERS and ANNOTATIONS ------------------------------------------- */
3009
3029
@@ -3192,7 +3212,7 @@ object Parsers {
3192
3212
* HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
3193
3213
* HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypePamClause] | ‘_’) TypeBounds
3194
3214
*/
3195
- def typeParamClause (ownerKind : ParamOwner ): List [TypeDef ] = inBrackets {
3215
+ def typeParamClause (ownerKind : ParamOwner ): List [TypeDef ] = inBracketsWithCommas {
3196
3216
3197
3217
def checkVarianceOK (): Boolean =
3198
3218
val ok = ownerKind != ParamOwner .Def && ownerKind != ParamOwner .TypeParam
@@ -3331,7 +3351,7 @@ object Parsers {
3331
3351
}
3332
3352
3333
3353
// begin termParamClause
3334
- inParens {
3354
+ inParensWithCommas {
3335
3355
if in.token == RPAREN && ! prefix && ! impliedMods.is(Given ) then Nil
3336
3356
else
3337
3357
val clause =
0 commit comments