@@ -533,11 +533,11 @@ object Parsers:
533
533
def inBrackets [T ](body : => T ): T = enclosed(LBRACKET , body)
534
534
535
535
def inBracesOrIndented [T ](body : => T , inStatSeq : Boolean = false , rewriteWithColon : Boolean = false ): T =
536
- val followsArrow = in.last.token == ARROW
537
536
if in.token == INDENT then
538
537
// braces are always optional after `=>` so none should be inserted
539
- val rewriteToBraces = in.rewriteNoIndent && ! followsArrow
540
- val rewriteToIndent = in.rewriteToIndent && ! followsArrow
538
+ val afterArrow = testChars(in.lastOffset - 3 , " =>" )
539
+ val rewriteToBraces = in.rewriteNoIndent && ! afterArrow
540
+ val rewriteToIndent = in.rewriteToIndent && ! afterArrow
541
541
if rewriteToBraces then indentedToBraces(body)
542
542
else if rewriteToIndent then enclosed(INDENT , toIndentedRegion(body))
543
543
else enclosed(INDENT , body)
@@ -614,6 +614,11 @@ object Parsers:
614
614
/* -------- REWRITES ----------------------------------------------------------- */
615
615
616
616
object IndentRewriteState :
617
+ assert(in.rewriteToIndent)
618
+
619
+ /** A copy of the previous token */
620
+ var prev : TokenData = Scanners .newTokenData
621
+
617
622
/** The last offset where a colon at the end of line would be required if a subsequent { ... }
618
623
* block would be converted to an indentation region. */
619
624
var possibleColonOffset : Int = - 1
@@ -705,8 +710,8 @@ object Parsers:
705
710
val (start, end) = blankLinesAround(offset, offset + 1 )
706
711
if testChar(end, Chars .LF ) then
707
712
if testChar(start - 1 , Chars .LF ) then (start, end + 1 ) // skip the whole line
708
- else (start, end) // skip the end of line
709
- else (offset, end) // skip from last to end of token
713
+ else (start, end) // skip from previous char to end of line
714
+ else (offset, end) // skip from token to next char
710
715
711
716
/** Expand the current span to its surrounding blank space */
712
717
def blankLinesAround (start : Offset , end : Offset ): (Offset , Offset ) =
@@ -720,18 +725,18 @@ object Parsers:
720
725
* 4. there is at least one token between the braces
721
726
* 5. the closing brace is also at the end of the line, or it is followed by one of
722
727
* `then`, `else`, `do`, `catch`, `finally`, `yield`, or `match`.
723
- * 6. the opening brace does not follow a closing `}`
728
+ * 6. the opening brace does not follow a closing brace
724
729
* 7. last token is not a leading operator
725
730
* 8. not a block in a sequence of statements
726
- * 9. cannot rewrite to colon after a NEWLINE, e.g.
731
+ * 9. cannot rewrite if colon required after a NEWLINE, e.g.
727
732
* true ||
728
- * { // NEWLINE inserted between || and {
733
+ * {
729
734
* false
730
735
* }
731
736
*/
732
737
def bracesToIndented [T ](body : => T , inStatSeq : Boolean , rewriteWithColon : Boolean ): T =
733
738
import IndentRewriteState .*
734
- val lastSaved = in.last .saveCopy
739
+ val prevSaved = prev .saveCopy
735
740
val lastOffsetSaved = in.lastOffset
736
741
val underColonSyntax = possibleColonOffset == in.lastOffset
737
742
val colonRequired = rewriteWithColon || underColonSyntax
@@ -741,9 +746,10 @@ object Parsers:
741
746
case r : InBraces => true
742
747
case _ => false
743
748
var canRewrite = isBracesOrIndented(in.currentRegion) && // test (1)
744
- lastSaved.token != RBRACE && // test (6)
745
- ! (lastSaved.isOperator && lastSaved.isAfterLineEnd) && // test (7)
746
- ! inStatSeq // test (8)
749
+ prevSaved.token != RBRACE && // test (6)
750
+ ! (prevSaved.isOperator && prevSaved.isAfterLineEnd) && // test (7)
751
+ ! inStatSeq && // test (8)
752
+ (! colonRequired || ! in.isAfterLineEnd) // test (9)
747
753
val t = enclosed(LBRACE , {
748
754
if in.isAfterLineEnd && in.token != RBRACE then // test (2)(4)
749
755
toIndentedRegion :
@@ -753,17 +759,16 @@ object Parsers:
753
759
canRewrite = false
754
760
body
755
761
})
756
- canRewrite &= (in.isAfterLineEnd || in.token == EOF || statCtdTokens.contains(in.token)) && // test (5)
757
- (! colonRequired || ! lastSaved.isNewLine) // test (9)
762
+ canRewrite &= (in.isAfterLineEnd || in.token == EOF || statCtdTokens.contains(in.token)) // test (5)
758
763
if canRewrite && (! underColonSyntax || Feature .fewerBracesEnabled) then
759
- val (startClosing, endClosing) = elimRegion(in.last.offset )
764
+ val (startClosing, endClosing) = elimRegion(in.lastOffset - 1 )
760
765
// patch over the added indentation to remove braces
761
766
patchOver(source, Span (startOpening, endOpening), " " )
762
767
patchOver(source, Span (startClosing, endClosing), " " )
763
768
if colonRequired then
764
- if lastSaved .token == IDENTIFIER && lastSaved .isOperator then
765
- patch(Span (lastSaved .offset, lastSaved.offset + lastSaved.name.length ), s " ` ${lastSaved .name}`: " )
766
- else if lastSaved .token == IDENTIFIER && lastSaved .name.last == '_' then
769
+ if prevSaved .token == IDENTIFIER && prevSaved .isOperator then
770
+ patch(Span (prevSaved .offset, lastOffsetSaved ), s " ` ${prevSaved .name}`: " )
771
+ else if prevSaved .token == IDENTIFIER && prevSaved .name.last == '_' then
767
772
patch(Span (lastOffsetSaved), " :" )
768
773
else patch(Span (lastOffsetSaved), " :" )
769
774
else
@@ -816,7 +821,9 @@ object Parsers:
816
821
maximumIndent = None
817
822
818
823
def nextToken (): Unit =
819
- if in.rewriteToIndent then patchIndent()
824
+ if in.rewriteToIndent then
825
+ IndentRewriteState .prev = in.saveCopy
826
+ patchIndent()
820
827
in.nextToken()
821
828
822
829
def skipToken (): Offset =
@@ -838,7 +845,7 @@ object Parsers:
838
845
val preFill = if (closingStartsLine || endStr.isEmpty) " " else " "
839
846
val postFill = if (in.lastOffset == in.offset) " " else " "
840
847
val (startClosing, endClosing) =
841
- if (closingStartsLine && endStr.isEmpty) elimRegion(in.last.offset )
848
+ if (closingStartsLine && endStr.isEmpty) elimRegion(in.lastOffset - 1 )
842
849
else (in.lastOffset - 1 , in.lastOffset)
843
850
patch(source, Span (startClosing, endClosing), s " $preFill$endStr$postFill" )
844
851
@@ -1336,7 +1343,8 @@ object Parsers:
1336
1343
syntaxErrorOrIncomplete(em " indented definitions expected, ${in} found " )
1337
1344
1338
1345
def colonAtEOLOpt (): Unit =
1339
- IndentRewriteState .possibleColonOffset = in.lastOffset
1346
+ if in.rewriteToIndent then
1347
+ IndentRewriteState .possibleColonOffset = in.lastOffset
1340
1348
in.observeColonEOL(inTemplate = false )
1341
1349
if in.token == COLONeol then
1342
1350
nextToken()
@@ -2062,7 +2070,7 @@ object Parsers:
2062
2070
2063
2071
def subExpr () = subPart(expr)
2064
2072
2065
- def expr (location : Location , inStatSeq : Boolean = false ): Tree =
2073
+ def expr (location : Location , inStatSeq : Boolean = false ): Tree = {
2066
2074
val start = in.offset
2067
2075
in.token match
2068
2076
case IMPLICIT =>
@@ -2385,7 +2393,7 @@ object Parsers:
2385
2393
* Quoted ::= ‘'’ ‘{’ Block ‘}’
2386
2394
* | ‘'’ ‘[’ Type ‘]’
2387
2395
*/
2388
- def simpleExpr (location : Location , inStatSeq : Boolean = false ): Tree =
2396
+ def simpleExpr (location : Location , inStatSeq : Boolean = false ): Tree = {
2389
2397
var canApply = true
2390
2398
val t = in.token match
2391
2399
case XMLSTART =>
@@ -2557,12 +2565,13 @@ object Parsers:
2557
2565
2558
2566
/** BlockExpr ::= <<< (CaseClauses | Block) >>>
2559
2567
*/
2560
- def blockExpr (inStatSeq : Boolean = false ): Tree = atSpan(in.offset):
2568
+ def blockExpr (inStatSeq : Boolean = false ): Tree = atSpan(in.offset) {
2561
2569
val simplify = in.token == INDENT
2562
2570
inDefScopeBraces({
2563
2571
if (in.token == CASE ) Match (EmptyTree , caseClauses(() => caseClause()))
2564
2572
else block(simplify)
2565
2573
}, inStatSeq = inStatSeq)
2574
+ }
2566
2575
2567
2576
/** Block ::= BlockStatSeq
2568
2577
* @note Return tree does not have a defined span.
@@ -2731,7 +2740,7 @@ object Parsers:
2731
2740
rejectWildcardType(infixType())
2732
2741
CaseDef (pat, EmptyTree , atSpan(accept(ARROW )) {
2733
2742
val t = indentedRegionAfterArrow(rejectWildcardType(typ()), inCaseDef = true )
2734
- if in.token == SEMI then nextToken()
2743
+ if in.token == SEMI then in. nextToken()
2735
2744
newLinesOptWhenFollowedBy(CASE )
2736
2745
t
2737
2746
})
@@ -4181,7 +4190,7 @@ object Parsers:
4181
4190
def skipBracesHook (): Option [Tree ] =
4182
4191
if (in.token == XMLSTART ) Some (xmlLiteral()) else None
4183
4192
4184
- override def blockExpr (inStatSeq : Boolean ): Tree =
4193
+ override def blockExpr (inStatSeq : Boolean ): Tree = {
4185
4194
skipBraces()
4186
4195
EmptyTree
4187
4196
0 commit comments