@@ -75,13 +75,13 @@ object Scanners {
7575 def isNestedStart = token == LBRACE || token == INDENT
7676 def isNestedEnd = token == RBRACE || token == OUTDENT
7777
78- /** Is token a COLON, after having converted COLONEOL to COLON?
78+ /** Is token a COLON, after having converted COLONeol to COLON?
7979 * The conversion means that indentation is not significant after `:`
8080 * anymore. So, warning: this is a side-effecting operation.
8181 */
8282 def isColon () =
83- if token == COLONEOL then token = COLON
84- token == COLON
83+ if token == COLONeol then token = COLONop
84+ token == COLONop || token == COLONfollow
8585
8686 /** Is current token first one after a newline? */
8787 def isAfterLineEnd : Boolean = lineOffset >= 0
@@ -394,10 +394,11 @@ object Scanners {
394394 */
395395 def nextToken (): Unit =
396396 val lastToken = token
397+ val lastName = name
397398 adjustSepRegions(lastToken)
398399 getNextToken(lastToken)
399400 if isAfterLineEnd then handleNewLine(lastToken)
400- postProcessToken(lastToken)
401+ postProcessToken(lastToken, lastName )
401402 printState()
402403
403404 final def printState () =
@@ -428,7 +429,7 @@ object Scanners {
428429 && {
429430 // Is current lexeme assumed to start an expression?
430431 // This is the case if the lexime is one of the tokens that
431- // starts an expression or it is a COLONEOL . Furthermore, if
432+ // starts an expression or it is a COLONeol . Furthermore, if
432433 // the previous token is in backticks, the lexeme may not be a binary operator.
433434 // I.e. in
434435 //
@@ -439,7 +440,7 @@ object Scanners {
439440 // in backticks and is a binary operator. Hence, `x` is not classified as a
440441 // leading infix operator.
441442 def assumeStartsExpr (lexeme : TokenData ) =
442- (canStartExprTokens.contains(lexeme.token) || lexeme.token == COLONEOL )
443+ (canStartExprTokens.contains(lexeme.token) || lexeme.token == COLONeol )
443444 && (! lexeme.isOperator || nme.raw.isUnary(lexeme.name))
444445 val lookahead = LookaheadScanner ()
445446 lookahead.allowLeadingInfixOperators = false
@@ -615,12 +616,11 @@ object Scanners {
615616 currentRegion match
616617 case r : Indented =>
617618 insert(OUTDENT , offset)
618- if next.token != COLON then
619- handleNewIndentWidth(r.enclosing, ir =>
620- errorButContinue(
621- i """ The start of this line does not match any of the previous indentation widths.
622- |Indentation width of current line : $nextWidth
623- |This falls between previous widths: ${ir.width} and $lastWidth""" ))
619+ handleNewIndentWidth(r.enclosing, ir =>
620+ errorButContinue(
621+ i """ The start of this line does not match any of the previous indentation widths.
622+ |Indentation width of current line : $nextWidth
623+ |This falls between previous widths: ${ir.width} and $lastWidth""" ))
624624 case r =>
625625 if skipping then
626626 if r.enclosing.isClosedByUndentAt(nextWidth) then
@@ -637,7 +637,7 @@ object Scanners {
637637 currentRegion.knownWidth = nextWidth
638638 else if (lastWidth != nextWidth)
639639 errorButContinue(spaceTabMismatchMsg(lastWidth, nextWidth))
640- if token != OUTDENT || next.token == COLON then
640+ if token != OUTDENT then
641641 handleNewIndentWidth(currentRegion, _.otherIndentWidths += nextWidth)
642642 end handleNewLine
643643
@@ -646,19 +646,22 @@ object Scanners {
646646 |Previous indent : $lastWidth
647647 |Latest indent : $nextWidth"""
648648
649- def observeColonEOL (): Unit =
650- if token == COLON then
649+ def observeColonEOL (inTemplate : Boolean ): Unit =
650+ val enabled =
651+ if inTemplate then token == COLONop || token == COLONfollow
652+ else token == COLONfollow && fewerBracesEnabled
653+ if enabled then
651654 lookAhead()
652655 val atEOL = isAfterLineEnd || token == EOF
653656 reset()
654- if atEOL then token = COLONEOL
657+ if atEOL then token = COLONeol
655658
656659 def observeIndented (): Unit =
657660 if indentSyntax && isNewLine then
658661 val nextWidth = indentWidth(next.offset)
659662 val lastWidth = currentRegion.indentWidth
660663 if lastWidth < nextWidth then
661- currentRegion = Indented (nextWidth, COLONEOL , currentRegion)
664+ currentRegion = Indented (nextWidth, COLONeol , currentRegion)
662665 offset = next.offset
663666 token = INDENT
664667 end observeIndented
@@ -691,10 +694,10 @@ object Scanners {
691694 case _ =>
692695
693696 /** - Join CASE + CLASS => CASECLASS, CASE + OBJECT => CASEOBJECT
694- * SEMI + ELSE => ELSE, COLON + <EOL> => COLONEOL
697+ * SEMI + ELSE => ELSE, COLON following id/)/] => COLONfollow
695698 * - Insert missing OUTDENTs at EOF
696699 */
697- def postProcessToken (lastToken : Token ): Unit = {
700+ def postProcessToken (lastToken : Token , lastName : SimpleName ): Unit = {
698701 def fuse (tok : Int ) = {
699702 token = tok
700703 offset = prev.offset
@@ -729,9 +732,10 @@ object Scanners {
729732 reset()
730733 case END =>
731734 if ! isEndMarker then token = IDENTIFIER
732- case COLON =>
733- if fewerBracesEnabled && colonEOLPredecessors.contains(lastToken) && lastOffset == offset then
734- observeColonEOL()
735+ case COLONop =>
736+ if lastToken == IDENTIFIER && lastName != null && isIdentifierStart(lastName.head)
737+ || colonEOLPredecessors.contains(lastToken)
738+ then token = COLONfollow
735739 case RBRACE | RPAREN | RBRACKET =>
736740 closeIndented()
737741 case EOF =>
@@ -1188,7 +1192,7 @@ object Scanners {
11881192 isSoftModifier && inModifierPosition()
11891193
11901194 def isSoftModifierInParamModifierPosition : Boolean =
1191- isSoftModifier && lookahead.token != COLON
1195+ isSoftModifier && lookahead.token != COLONop && lookahead.token != COLONfollow
11921196
11931197 def isErased : Boolean = isIdent(nme.erased) && erasedEnabled
11941198
@@ -1527,6 +1531,7 @@ object Scanners {
15271531 case NEWLINE => " ;"
15281532 case NEWLINES => " ;;"
15291533 case COMMA => " ,"
1534+ case COLONfollow | COLONeol => " ':'"
15301535 case _ =>
15311536 if debugTokenStream then showTokenDetailed(token) else showToken(token)
15321537 }
0 commit comments