summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2016-06-02 18:58:44 -0700
committerAdriaan Moors <adriaan@lightbend.com>2016-06-02 18:58:44 -0700
commit5fffe799329713f90d9188497504fe130e5b5000 (patch)
tree341cc2ee54d3f8e07cc52ca6710e916d7b02baf8
parent461c896581a6e16d1b79e91e9322eb2d14dc53d2 (diff)
parentfe61bcf99c0c10054066f7ff41e4c7f44cf02e5d (diff)
downloadscala-5fffe799329713f90d9188497504fe130e5b5000.tar.gz
scala-5fffe799329713f90d9188497504fe130e5b5000.tar.bz2
scala-5fffe799329713f90d9188497504fe130e5b5000.zip
Merge pull request #5197 from som-snytt/issue/9104-raw
SI-9104 Autodetect raw pastage
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala45
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala16
-rw-r--r--test/files/run/repl-paste-b.check14
-rw-r--r--test/files/run/repl-paste-b.scala13
-rw-r--r--test/files/run/repl-paste-raw-b.pastie8
-rw-r--r--test/files/run/repl-paste-raw-b.scala18
-rw-r--r--test/files/run/repl-paste-raw-c.pastie5
-rw-r--r--test/files/run/repl-paste-raw-c.scala16
-rw-r--r--test/files/run/repl-paste-raw.pastie4
-rw-r--r--test/files/run/repl-paste-raw.scala2
10 files changed, 117 insertions, 24 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)
}
}
diff --git a/test/files/run/repl-paste-b.check b/test/files/run/repl-paste-b.check
new file mode 100644
index 0000000000..2e205d48d6
--- /dev/null
+++ b/test/files/run/repl-paste-b.check
@@ -0,0 +1,14 @@
+
+scala> :paste < EOF
+// Entering paste mode (EOF to finish)
+
+object X
+EOF
+
+// Exiting paste mode, now interpreting.
+
+defined object X
+
+scala> assert(X.getClass.getName.contains("line"))
+
+scala> :quit
diff --git a/test/files/run/repl-paste-b.scala b/test/files/run/repl-paste-b.scala
new file mode 100644
index 0000000000..718f7d9e17
--- /dev/null
+++ b/test/files/run/repl-paste-b.scala
@@ -0,0 +1,13 @@
+import scala.tools.partest.ReplTest
+
+// confirm X not in empty package
+object Test extends ReplTest {
+ def code =
+ """
+:paste < EOF
+object X
+EOF
+assert(X.getClass.getName.contains("line"))
+"""
+
+}
diff --git a/test/files/run/repl-paste-raw-b.pastie b/test/files/run/repl-paste-raw-b.pastie
new file mode 100644
index 0000000000..f13b4bcf8b
--- /dev/null
+++ b/test/files/run/repl-paste-raw-b.pastie
@@ -0,0 +1,8 @@
+
+// a raw paste is not a script
+// hence it can be packaged
+
+package brown_paper
+
+// these are a few of my favorite things
+case class Gift (hasString: Boolean)
diff --git a/test/files/run/repl-paste-raw-b.scala b/test/files/run/repl-paste-raw-b.scala
new file mode 100644
index 0000000000..d1c7692f2f
--- /dev/null
+++ b/test/files/run/repl-paste-raw-b.scala
@@ -0,0 +1,18 @@
+
+import scala.tools.partest.SessionTest
+
+object Test extends SessionTest {
+ def session =
+s"""|
+ |scala> :paste $pastie
+ |Pasting file $pastie...
+ |
+ |scala> val favoriteThing = brown_paper.Gift(true)
+ |favoriteThing: brown_paper.Gift = Gift(true)
+ |
+ |scala> favoriteThing.hasString
+ |res0: Boolean = true
+ |
+ |scala> :quit"""
+ def pastie = testPath changeExtension "pastie"
+}
diff --git a/test/files/run/repl-paste-raw-c.pastie b/test/files/run/repl-paste-raw-c.pastie
new file mode 100644
index 0000000000..364d8cef4b
--- /dev/null
+++ b/test/files/run/repl-paste-raw-c.pastie
@@ -0,0 +1,5 @@
+
+// not actually a candidate for raw paste
+
+val nope = 42
+
diff --git a/test/files/run/repl-paste-raw-c.scala b/test/files/run/repl-paste-raw-c.scala
new file mode 100644
index 0000000000..600ac4d2f0
--- /dev/null
+++ b/test/files/run/repl-paste-raw-c.scala
@@ -0,0 +1,16 @@
+
+import scala.tools.partest.SessionTest
+
+object Test extends SessionTest {
+ def session =
+s"""|
+ |scala> :paste -raw $pastie
+ |Pasting file $pastie...
+ |$pastie:3: error: expected class or object definition
+ |val nope = 42
+ |^
+ |There were compilation errors!
+ |
+ |scala> :quit"""
+ def pastie = testPath changeExtension "pastie"
+}
diff --git a/test/files/run/repl-paste-raw.pastie b/test/files/run/repl-paste-raw.pastie
index f13b4bcf8b..a4a570aaa2 100644
--- a/test/files/run/repl-paste-raw.pastie
+++ b/test/files/run/repl-paste-raw.pastie
@@ -1,8 +1,8 @@
+package brown_paper
+
// a raw paste is not a script
// hence it can be packaged
-package brown_paper
-
// these are a few of my favorite things
case class Gift (hasString: Boolean)
diff --git a/test/files/run/repl-paste-raw.scala b/test/files/run/repl-paste-raw.scala
index 9bd5e8e63e..d1c7692f2f 100644
--- a/test/files/run/repl-paste-raw.scala
+++ b/test/files/run/repl-paste-raw.scala
@@ -4,7 +4,7 @@ import scala.tools.partest.SessionTest
object Test extends SessionTest {
def session =
s"""|
- |scala> :paste -raw $pastie
+ |scala> :paste $pastie
|Pasting file $pastie...
|
|scala> val favoriteThing = brown_paper.Gift(true)