From 3dfcb1577d87ed817da0a1445ba414b2ec4c616d Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 1 Oct 2016 16:58:47 -0700 Subject: SI-9944 Scan after interp expr keeps CR In an interpolated expression `s"""${ e }"""`, the scanner advances input past the RBRACE. If a multiline string as shown, get the next raw char, because CR is significant. --- src/compiler/scala/tools/nsc/ast/parser/Scanners.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala index 891858ba7b..755a9d1857 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala @@ -246,6 +246,14 @@ trait Scanners extends ScannersCommon { private def inMultiLineInterpolation = inStringInterpolation && sepRegions.tail.nonEmpty && sepRegions.tail.head == STRINGPART + /** Are we in a `${ }` block? such that RBRACE exits back into multiline string. */ + private def inMultiLineInterpolatedExpression = { + sepRegions match { + case RBRACE :: STRINGLIT :: STRINGPART :: rest => true + case _ => false + } + } + /** read next token and return last offset */ def skipToken(): Offset = { @@ -312,7 +320,7 @@ trait Scanners extends ScannersCommon { lastOffset -= 1 } if (inStringInterpolation) fetchStringPart() else fetchToken() - if(token == ERROR) { + if (token == ERROR) { if (inMultiLineInterpolation) sepRegions = sepRegions.tail.tail else if (inStringInterpolation) @@ -547,7 +555,8 @@ trait Scanners extends ScannersCommon { case ')' => nextChar(); token = RPAREN case '}' => - nextChar(); token = RBRACE + if (inMultiLineInterpolatedExpression) nextRawChar() else nextChar() + token = RBRACE case '[' => nextChar(); token = LBRACKET case ']' => -- cgit v1.2.3