@@ -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
0 commit comments