Skip to content

Commit 0b121d1

Browse files
committed
SI-9450 Fix triple quoted strings in REPL :power mode
Some extra synthetic code generated under this mode failed to escape input before adding it to a literal string. It used to get away with this most of the time by triple quoting the literal. This commit reuses Scala string escaping logic buried in `Constant` to do this properly. Actually, the proper approach would be to build the synthetic code with trees and quasiquotes, and avoid the mess of stringly-genererated code. I threw in some defensive hygiene for the reference to `Nil` while I was in the neighbourhood.
1 parent 79171ce commit 0b121d1

File tree

3 files changed

+11
-3
lines changed

3 files changed

+11
-3
lines changed

src/repl/scala/tools/nsc/interpreter/IMain.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
133133
}
134134
catch AbstractOrMissingHandler()
135135
}
136-
private def tquoted(s: String) = "\"\"\"" + s + "\"\"\""
137136
private val logScope = scala.sys.props contains "scala.repl.scope"
138137
private def scopelog(msg: String) = if (logScope) Console.err.println(msg)
139138

@@ -905,7 +904,10 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
905904
def path = originalPath("$intp")
906905
def envLines = {
907906
if (!isReplPower) Nil // power mode only for now
908-
else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees"))
907+
else {
908+
val escapedLine = Constant(originalLine).escapedStringValue
909+
List(s"""def $$line = $escapedLine """, """def $trees = _root_.scala.Nil""")
910+
}
909911
}
910912
def preamble = s"""
911913
|$headerPreamble

test/files/run/repl-power.check

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,7 @@ m: $r.treedsl.global.Literal = 10
2525
scala> typed(m).tpe // typed is in scope
2626
res2: $r.treedsl.global.Type = Int(10)
2727

28+
scala> """escaping is hard, m'kah"""
29+
res3: String = escaping is hard, m'kah
30+
2831
scala> :quit

test/files/run/repl-power.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import scala.tools.partest.ReplTest
22

33
object Test extends ReplTest {
4-
def code = """
4+
def tripleQuote(s: String) = "\"\"\"" + s + "\"\"\""
5+
6+
def code = s"""
57
:power
68
// guarding against "error: reference to global is ambiguous"
79
global.emptyValDef // "it is imported twice in the same scope by ..."
810
val tp = ArrayClass[scala.util.Random] // magic with tags
911
tp.memberType(Array_apply) // evidence
1012
val m = LIT(10) // treedsl
1113
typed(m).tpe // typed is in scope
14+
${tripleQuote("escaping is hard, m'kah")}
1215
""".trim
1316
}

0 commit comments

Comments
 (0)