summaryrefslogtreecommitdiff
path: root/src/repl
diff options
context:
space:
mode:
authorSom Snytt <som.snytt@gmail.com>2016-05-27 14:43:22 -0700
committerSom Snytt <som.snytt@gmail.com>2016-06-02 17:04:31 -0700
commitfe61bcf99c0c10054066f7ff41e4c7f44cf02e5d (patch)
tree341cc2ee54d3f8e07cc52ca6710e916d7b02baf8 /src/repl
parent461c896581a6e16d1b79e91e9322eb2d14dc53d2 (diff)
downloadscala-fe61bcf99c0c10054066f7ff41e4c7f44cf02e5d.tar.gz
scala-fe61bcf99c0c10054066f7ff41e4c7f44cf02e5d.tar.bz2
scala-fe61bcf99c0c10054066f7ff41e4c7f44cf02e5d.zip
SI-9104 Autodetect raw pastage
If `-raw` is not supplied explicitly to REPL `:paste`, see if the code text starts with `package` keyword or else see if it parses to a named package (to cope with leading commentary). In that case, take it as raw. But parse only on suspect comment slash. It's only worth parsing for a package if there's a chance that package keyword is buried behind comments. Small refactors to the `paste` object.
Diffstat (limited to 'src/repl')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala45
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala16
2 files changed, 40 insertions, 21 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 8f19b4860a..66a5f08e96 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -490,11 +490,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
def editCommand(what: String): Result = editCommand(what, Properties.envOrNone("EDITOR"))
def editCommand(what: String, editor: Option[String]): Result = {
- def diagnose(code: String) = {
- echo("The edited code is incomplete!\n")
- val errless = intp compileSources new BatchSourceFile("<pastie>", s"object pastel {\n$code\n}")
- if (errless) echo("The compiler reports no errors.")
- }
+ def diagnose(code: String): Unit = paste.incomplete("The edited code is incomplete!\n", "<edited>", code)
def edit(text: String): Result = editor match {
case Some(ed) =>
@@ -756,21 +752,13 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
text
}
def interpretCode() = {
- val res = intp.withLabel(label)(intp interpret code)
- // if input is incomplete, let the compiler try to say why
- if (res == IR.Incomplete) {
- echo("The pasted code is incomplete!\n")
- // Remembrance of Things Pasted in an object
- val errless = intp compileSources new BatchSourceFile(label, s"object pastel {\n$code\n}")
- if (errless) echo("...but compilation found no error? Good luck with that.")
- }
- }
- def compileCode() = {
- val errless = intp compileSources new BatchSourceFile(label, code)
- if (!errless) echo("There were compilation errors!")
+ if (intp.withLabel(label)(intp interpret code) == IR.Incomplete)
+ paste.incomplete("The pasted code is incomplete!\n", label, code)
}
+ def compileCode() = paste.compilePaste(label = label, code = code)
+
if (code.nonEmpty) {
- if (raw) compileCode() else interpretCode()
+ if (raw || paste.isPackaged(code)) compileCode() else interpretCode()
}
result
}
@@ -778,6 +766,27 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
private object paste extends Pasted(prompt) {
def interpret(line: String) = intp interpret line
def echo(message: String) = ILoop.this echo message
+
+ val leadingElement = raw"(?s)\s*(package\s|/)".r
+ def isPackaged(code: String): Boolean = {
+ leadingElement.findPrefixMatchOf(code)
+ .map(m => if (m.group(1) == "/") intp.parse.packaged(code) else true)
+ .getOrElse(false)
+ }
+
+ // if input is incomplete, wrap and compile for diagnostics.
+ def incomplete(message: String, label: String, code: String): Boolean = {
+ echo(message)
+ val errless = intp.compileSources(new BatchSourceFile(label, s"object pastel {\n$code\n}"))
+ if (errless) echo("No error found in incomplete source.")
+ errless
+ }
+
+ def compilePaste(label: String, code: String): Boolean = {
+ val errless = intp.compileSources(new BatchSourceFile(label, code))
+ if (!errless) echo("There were compilation errors!")
+ errless
+ }
}
private object invocation {
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 2f20a1cd0a..44784aa953 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -1101,7 +1101,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
case class Incomplete(trees: List[Tree]) extends Result
case class Success(trees: List[Tree]) extends Result
- def apply(line: String): Result = debugging(s"""parse("$line")""") {
+ def apply(line: String): Result = debugging(s"""parse("$line")""") {
var isIncomplete = false
def parse = {
reporter.reset()
@@ -1110,8 +1110,18 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
else if (isIncomplete) Incomplete(trees)
else Success(trees)
}
- currentRun.parsing.withIncompleteHandler((_, _) => isIncomplete = true) {parse}
-
+ currentRun.parsing.withIncompleteHandler((_, _) => isIncomplete = true)(parse)
+ }
+ // code has a named package
+ def packaged(line: String): Boolean = {
+ def parses = {
+ reporter.reset()
+ val tree = newUnitParser(line).parse()
+ !reporter.hasErrors && {
+ tree match { case PackageDef(Ident(id), _) => id != nme.EMPTY_PACKAGE_NAME case _ => false }
+ }
+ }
+ beSilentDuring(parses)
}
}