Skip to content

Commit a2cd2c5

Browse files
authored
Merge pull request #14757 from dotty-staging/refine-trailing-commas
Alternative trailing comma handling
2 parents 03085e0 + 11f8b99 commit a2cd2c5

File tree

3 files changed

+35
-18
lines changed

3 files changed

+35
-18
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -559,19 +559,24 @@ object Parsers {
559559
def inDefScopeBraces[T](body: => T, rewriteWithColon: Boolean = false): T =
560560
inBracesOrIndented(body, rewriteWithColon)
561561

562-
/**
563-
* @param readFirst If true, assume we have not read the first `part`. Otherwise,
564-
* expect that we have (i.e the next thing to expect is a [[COMMA]]).
565-
*/
566-
def commaSeparated[T](part: () => T, readFirst: Boolean = true): List[T] =
562+
/** <part> {`,` <part>} */
563+
def commaSeparated[T](part: () => T): List[T] =
567564
in.currentRegion.withCommasExpected {
568-
val ts = new ListBuffer[T]
569-
if (readFirst) ts += part()
565+
commaSeparatedRest(part(), part)
566+
}
567+
568+
/** {`,` <part>}
569+
*
570+
* currentRegion.commasExpected has to be set separately.
571+
*/
572+
def commaSeparatedRest[T](leading: T, part: () => T): List[T] =
573+
if in.token == COMMA then
574+
val ts = new ListBuffer[T] += leading
570575
while in.token == COMMA do
571576
in.nextToken()
572577
ts += part()
573578
ts.toList
574-
}
579+
else leading :: Nil
575580

576581
def inSepRegion[T](f: Region => Region)(op: => T): T =
577582
val cur = in.currentRegion
@@ -1402,13 +1407,15 @@ object Parsers {
14021407
else {
14031408
if isErased then imods = addModifier(imods)
14041409
val paramStart = in.offset
1405-
val ts = funArgType() match {
1406-
case Ident(name) if name != tpnme.WILDCARD && in.isColon() =>
1407-
isValParamList = true
1408-
typedFunParam(paramStart, name.toTermName, imods) :: commaSeparated(
1409-
() => typedFunParam(in.offset, ident(), imods), readFirst = false)
1410-
case t =>
1411-
t :: commaSeparated(funArgType, readFirst = false)
1410+
val ts = in.currentRegion.withCommasExpected {
1411+
funArgType() match
1412+
case Ident(name) if name != tpnme.WILDCARD && in.isColon() =>
1413+
isValParamList = true
1414+
commaSeparatedRest(
1415+
typedFunParam(paramStart, name.toTermName, imods),
1416+
() => typedFunParam(in.offset, ident(), imods))
1417+
case t =>
1418+
commaSeparatedRest(t, funArgType)
14121419
}
14131420
accept(RPAREN)
14141421
if isValParamList || in.isArrow then
@@ -3188,8 +3195,7 @@ object Parsers {
31883195
}
31893196
else ImportSelector(from)
31903197

3191-
def importSelector(idOK: Boolean)(): ImportSelector =
3192-
val isWildcard = in.token == USCORE || in.token == GIVEN || isIdent(nme.raw.STAR)
3198+
def importSelector(idOK: Boolean): ImportSelector =
31933199
atSpan(in.offset) {
31943200
in.token match
31953201
case USCORE => wildcardSelector()
@@ -3201,6 +3207,14 @@ object Parsers {
32013207
namedSelector(termIdent())
32023208
}
32033209

3210+
def importSelectors(): List[ImportSelector] =
3211+
var idOK = true
3212+
commaSeparated { () =>
3213+
val isWildcard = in.token == USCORE || in.token == GIVEN || isIdent(nme.raw.STAR)
3214+
try importSelector(idOK)
3215+
finally idOK &= !isWildcard
3216+
}
3217+
32043218
def importSelection(qual: Tree): Tree =
32053219
if in.isIdent(nme.as) && qual.isInstanceOf[RefTree] then
32063220
qual match
@@ -3217,7 +3231,7 @@ object Parsers {
32173231
case GIVEN =>
32183232
mkTree(qual, givenSelector() :: Nil)
32193233
case LBRACE =>
3220-
mkTree(qual, inBraces(commaSeparated(importSelector(idOK = true))))
3234+
mkTree(qual, inBraces(importSelectors()))
32213235
case _ =>
32223236
if isIdent(nme.raw.STAR) then
32233237
mkTree(qual, wildcardSelector() :: Nil)

compiler/src/dotty/tools/dotc/parsing/Scanners.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@ object Scanners {
700700
case _ =>
701701
lookAhead()
702702
if isAfterLineEnd
703+
&& currentRegion.commasExpected
703704
&& (token == RPAREN || token == RBRACKET || token == RBRACE || token == OUTDENT)
704705
then
705706
() /* skip the trailing comma */

tests/neg/imports.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import scala.collection.{*, View} // error
2+
object test

0 commit comments

Comments
 (0)