Skip to content

Commit 0bbfaf6

Browse files
committed
More SepRegions refactorings
Make SepRegions a case class instead of a list of tokens. This is in preparation of merging SepRegions and IndentRegions
1 parent 6672a61 commit 0bbfaf6

File tree

3 files changed

+63
-44
lines changed

3 files changed

+63
-44
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,8 +703,12 @@ object Parsers {
703703
val (startOpening, endOpening) = startingElimRegion(colonRequired)
704704
val isOuterMost = in.sepRegions.isEmpty
705705
val savedPending = pendingPatches
706-
var canRewrite =
707-
in.sepRegions.forall(token => token == RBRACE || token == OUTDENT) && // test (1)
706+
def allBraces(r: Region): Boolean = r match {
707+
case GlobalRegion => true
708+
case InBracesRegion(outer) => allBraces(outer)
709+
case _ => false
710+
}
711+
var canRewrite = allBraces(in.sepRegions) && // test (1)
708712
!testChars(in.lastOffset - 3, " =>") // test(6)
709713
val t = enclosed(LBRACE, {
710714
canRewrite &= in.isAfterLineEnd // test (2)

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

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ object Scanners {
305305
* (the STRINGLIT appears twice in succession on the stack iff the
306306
* expression is a multiline string literal).
307307
*/
308-
var sepRegions: List[Token] = Nil
308+
var sepRegions: Region = GlobalRegion
309309

310310
/** Indentation widths, innermost to outermost */
311311
var indent: IndentRegion = IndentRegion(IndentWidth.Zero, Set(), EMPTY, null)
@@ -333,13 +333,15 @@ object Scanners {
333333
/** Are we directly in a string interpolation expression?
334334
*/
335335
private def inStringInterpolation =
336-
!sepRegions.isEmpty && sepRegions.head == STRINGLIT
336+
sepRegions.isInstanceOf[InStringRegion]
337337

338338
/** Are we directly in a multiline string interpolation expression?
339339
* @pre inStringInterpolation
340340
*/
341-
private def inMultiLineInterpolation =
342-
inStringInterpolation && !sepRegions.tail.isEmpty && sepRegions.tail.head == STRINGPART
341+
private def inMultiLineInterpolation = sepRegions match {
342+
case InStringRegion(_, multiLine) => multiLine
343+
case _ => false
344+
}
343345

344346
/** read next token and return last offset
345347
*/
@@ -350,24 +352,30 @@ object Scanners {
350352
}
351353

352354
def adjustSepRegions(lastToken: Token): Unit = (lastToken: @switch) match {
353-
case LPAREN =>
354-
sepRegions = RPAREN :: sepRegions
355-
case LBRACKET =>
356-
sepRegions = RBRACKET :: sepRegions
355+
case LPAREN | LBRACKET =>
356+
sepRegions = InParensRegion(sepRegions, lastToken + 1)
357357
case LBRACE =>
358-
sepRegions = RBRACE :: sepRegions
358+
sepRegions = InBracesRegion(sepRegions)
359359
case RBRACE =>
360-
while (!sepRegions.isEmpty && sepRegions.head != RBRACE)
361-
sepRegions = sepRegions.tail
362-
if (!sepRegions.isEmpty) sepRegions = sepRegions.tail
363-
case RBRACKET | RPAREN =>
364-
if (!sepRegions.isEmpty && sepRegions.head == lastToken)
365-
sepRegions = sepRegions.tail
360+
def dropBraces(): Unit = sepRegions match {
361+
case GlobalRegion =>
362+
case InBracesRegion(outer) =>
363+
sepRegions = outer
364+
case _ =>
365+
sepRegions = sepRegions.outer
366+
dropBraces()
367+
}
368+
dropBraces()
369+
case RPAREN | RBRACKET =>
370+
sepRegions match {
371+
case InParensRegion(outer, closing) if closing == lastToken => sepRegions = outer
372+
case _ =>
373+
}
366374
case STRINGLIT =>
367-
if (inMultiLineInterpolation)
368-
sepRegions = sepRegions.tail.tail
369-
else if (inStringInterpolation)
370-
sepRegions = sepRegions.tail
375+
sepRegions match {
376+
case InStringRegion(outer, _) => sepRegions = outer
377+
case _ =>
378+
}
371379
case _ =>
372380
}
373381

@@ -555,11 +563,10 @@ object Scanners {
555563
*/
556564
def handleNewLine(lastToken: Token) = {
557565
val indentIsSignificant = indentSyntax && sepRegions.isEmpty
558-
val newlineIsSeparating = (
559-
sepRegions.isEmpty
560-
|| sepRegions.head == RBRACE
561-
|| sepRegions.head == ARROW && token == CASE
562-
)
566+
val newlineIsSeparating = sepRegions match {
567+
case GlobalRegion | InBracesRegion(_) => true
568+
case _ => false
569+
}
563570
val curWidth = indentWidth(offset)
564571
val lastWidth = indent.width
565572
if (newlineIsSeparating &&
@@ -749,43 +756,39 @@ object Scanners {
749756
case '`' =>
750757
getBackquotedIdent()
751758
case '\"' =>
752-
def fetchDoubleQuote() =
759+
def stringPart(multiLine: Boolean) = {
760+
getStringPart(multiLine)
761+
sepRegions = InStringRegion(sepRegions, multiLine)
762+
}
763+
def fetchDoubleQuote() = {
753764
if (token == INTERPOLATIONID) {
754765
nextRawChar()
755766
if (ch == '\"') {
756767
nextRawChar()
757768
if (ch == '\"') {
758769
nextRawChar()
759-
getStringPart(multiLine = true)
760-
sepRegions = STRINGPART :: sepRegions // indicate string part
761-
sepRegions = STRINGLIT :: sepRegions // once more to indicate multi line string part
762-
}
763-
else {
770+
stringPart(multiLine = true)
771+
} else {
764772
token = STRINGLIT
765773
strVal = ""
766774
}
767-
}
768-
else {
769-
getStringPart(multiLine = false)
770-
sepRegions = STRINGLIT :: sepRegions // indicate single line string part
771-
}
772-
}
773-
else {
775+
} else stringPart(multiLine = false)
776+
} else {
774777
nextChar()
775778
if (ch == '\"') {
776779
nextChar()
777780
if (ch == '\"') {
778781
nextRawChar()
779782
getRawStringLit()
780-
}
781-
else {
783+
} else {
782784
token = STRINGLIT
783785
strVal = ""
784786
}
785-
}
786-
else
787+
} else {
787788
getStringLit()
789+
}
788790
}
791+
}
789792
fetchDoubleQuote()
790793
case '\'' =>
791794
def fetchSingleQuote() = {
@@ -1338,6 +1341,18 @@ object Scanners {
13381341
}
13391342
// end Scanner
13401343

1344+
abstract class Region {
1345+
def outer: Region
1346+
def isEmpty = false
1347+
}
1348+
case class InParensRegion(val outer: Region, closing: Token) extends Region
1349+
case class InBracesRegion(val outer: Region) extends Region
1350+
case class InStringRegion(val outer: Region, multiLine: Boolean) extends Region
1351+
case object GlobalRegion extends Region {
1352+
def outer = throw UnsupportedOperationException("GlobalRegion.outer")
1353+
override def isEmpty = true
1354+
}
1355+
13411356
/** A class describing an indentation region.
13421357
* @param width The principal indendation width
13431358
* @param others Other indendation widths > width of lines in the same region

compiler/src/dotty/tools/dotc/parsing/xml/MarkupParsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ object MarkupParsers {
398398

399399
def escapeToScala[A](op: => A, kind: String): A = {
400400
xEmbeddedBlock = false
401-
val res = saving[List[Int], A](parser.in.sepRegions, parser.in.sepRegions = _) {
401+
val res = saving(parser.in.sepRegions, parser.in.sepRegions = _) {
402402
val lbrace = parser.in.newTokenData
403403
lbrace.token = LBRACE
404404
lbrace.offset = parser.in.charOffset - 1

0 commit comments

Comments
 (0)