Skip to content

Commit 3dfcb15

Browse files
committed
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.
1 parent 3880535 commit 3dfcb15

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,14 @@ trait Scanners extends ScannersCommon {
246246
private def inMultiLineInterpolation =
247247
inStringInterpolation && sepRegions.tail.nonEmpty && sepRegions.tail.head == STRINGPART
248248

249+
/** Are we in a `${ }` block? such that RBRACE exits back into multiline string. */
250+
private def inMultiLineInterpolatedExpression = {
251+
sepRegions match {
252+
case RBRACE :: STRINGLIT :: STRINGPART :: rest => true
253+
case _ => false
254+
}
255+
}
256+
249257
/** read next token and return last offset
250258
*/
251259
def skipToken(): Offset = {
@@ -312,7 +320,7 @@ trait Scanners extends ScannersCommon {
312320
lastOffset -= 1
313321
}
314322
if (inStringInterpolation) fetchStringPart() else fetchToken()
315-
if(token == ERROR) {
323+
if (token == ERROR) {
316324
if (inMultiLineInterpolation)
317325
sepRegions = sepRegions.tail.tail
318326
else if (inStringInterpolation)
@@ -547,7 +555,8 @@ trait Scanners extends ScannersCommon {
547555
case ')' =>
548556
nextChar(); token = RPAREN
549557
case '}' =>
550-
nextChar(); token = RBRACE
558+
if (inMultiLineInterpolatedExpression) nextRawChar() else nextChar()
559+
token = RBRACE
551560
case '[' =>
552561
nextChar(); token = LBRACKET
553562
case ']' =>

test/files/run/t9944.check

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[[syntax trees at end of parser]] // newSource1.scala
2+
package <empty> {
3+
class C extends scala.AnyRef {
4+
def <init>() = {
5+
super.<init>();
6+
()
7+
};
8+
def g = 42;
9+
def f = StringContext("123\r\n", "\r\n123\r\n").s(g)
10+
}
11+
}
12+

test/files/run/t9944.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
import scala.tools.partest.ParserTest
3+
4+
object Test extends ParserTest {
5+
6+
def code = s"""class C { def g = 42 ; def f = s""\"123\r\n$${ g }\r\n123\r\n""\"}"""
7+
}

0 commit comments

Comments
 (0)