diff options
author | Som Snytt <som.snytt@gmail.com> | 2016-05-27 14:43:22 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2016-06-02 17:04:31 -0700 |
commit | fe61bcf99c0c10054066f7ff41e4c7f44cf02e5d (patch) | |
tree | 341cc2ee54d3f8e07cc52ca6710e916d7b02baf8 /src/repl | |
parent | 461c896581a6e16d1b79e91e9322eb2d14dc53d2 (diff) | |
download | scala-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.scala | 45 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/IMain.scala | 16 |
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) } } |