summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-07-25 14:00:18 +0200
committerMartin Odersky <odersky@gmail.com>2012-07-27 17:04:12 +0200
commit923d5e02298d67f84c13210cd2a20c038b8f3e46 (patch)
tree4758c827665fa4599fd06930c4391cad6aaa21f7 /src
parent7b62eeea86c62f5e068c366065f8f4c2e6624eb7 (diff)
downloadscala-923d5e02298d67f84c13210cd2a20c038b8f3e46.tar.gz
scala-923d5e02298d67f84c13210cd2a20c038b8f3e46.tar.bz2
scala-923d5e02298d67f84c13210cd2a20c038b8f3e46.zip
New Executor.
To try it out: run "instrument worksheet" as usual in the REPL. Worksheet needs to have enclosing object definition. Say it is named "Obj". This will generate a file Obj$instrumented. You can compile that file separately and run it using Java. It should reproduce itself.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala20
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Executor.scala31
3 files changed, 49 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index 1dcc979255..a19463bee7 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -190,10 +190,12 @@ object REPL {
val source = toSourceFile(arguments.head)
// strip right hand side comment column and any trailing spaces from all lines
val strippedSource = new BatchSourceFile(source.file, SourceInserter.stripRight(source.content))
+ println("stripped source = "+strippedSource)
comp.askReload(List(strippedSource), reloadResult)
comp.askInstrumented(strippedSource, line, instrumentedResult)
using(instrumentedResult) {
case (iFullName, iContents) =>
+ println(s"instrumented source $iFullName = ${iContents.mkString}")
val iSourceName = writeInstrumented(iFullName, iContents)
val vdirOpt = compileInstrumented(iSourceName, arguments.tail)
runInstrumented(vdirOpt, iFullName, strippedSource.content)
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index c79248e1c1..45f7c20ba0 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -29,9 +29,21 @@ trait ScratchPadMaker { self: Global =>
private def nameType(sym: Symbol): String = nameType(sym.name.toString, sym.tpe)
private def literal(str: String) = "\"\"\""+str+"\"\"\""
+
+ private val prologue = "import scala.tools.nsc.scratchpad.Executor._; def main(args: Array[String])=$execute{"
+
+ def stringifiedContents = {
+ contents flatMap {
+ case '$' => """$$"""
+ case '"' => """${'"'}"""
+ case c => c.toString
+ }
+ }.mkString
+
+ private def epilogue = "}(s\"\"\"" + stringifiedContents + "\"\"\")"
private def applyPendingPatches(offset: Int) = {
- if (skipped == 0) patches += Patch(offset, "import scala.tools.nsc.scratchpad.Executor._; ")
+ if (skipped == 0) patches += Patch(offset, prologue)
for (msg <- toPrint) patches += Patch(offset, ";System.out.println("+msg+")")
toPrint.clear()
}
@@ -92,10 +104,12 @@ trait ScratchPadMaker { self: Global =>
case PackageDef(_, _) =>
super.traverse(tree)
case ModuleDef(_, name, Template(_, _, body)) =>
- if (objectName.length == 0)
- objectName = tree.symbol.fullName
+ val topLevel = objectName.isEmpty
+ if (topLevel) objectName = tree.symbol.fullName
body foreach traverseStat
applyPendingPatches(skipped)
+ if (topLevel)
+ patches += Patch(skipped, epilogue)
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
index 89523df71e..d7b93b0031 100644
--- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
+++ b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
@@ -15,6 +15,7 @@ object Executor {
/** Execute module with given name, redirecting all output to given
* source inserter. Catch all exceptions and print stacktrace of underlying causes.
*/
+ @deprecated("use $execute instead")
def execute(name: String, si: SourceInserter, classLoader: ClassLoader = getClass.getClassLoader) {
val oldSysOut = System.out
val oldSysErr = System.err
@@ -29,7 +30,7 @@ object Executor {
Console.setErr(newOut)
try {
singletonInstance(classLoader, name)
- } catch {
+ } catch {
case ex: Throwable =>
unwrapThrowable(ex) match {
case _: StopException => ;
@@ -44,6 +45,34 @@ object Executor {
currentWriter = oldCwr
}
}
+
+ def $execute(op: => Unit)(source: String) = {
+ val oldSysOut = System.out
+ val oldSysErr = System.err
+ val oldConsOut = Console.out
+ val oldConsErr = Console.err
+ val si = new SourceInserter(source.toCharArray)
+ currentWriter = new CommentWriter(si)
+ val newOut = new PrintStream(new CommentOutputStream(currentWriter))
+ System.setOut(newOut)
+ System.setErr(newOut)
+ Console.setOut(newOut)
+ Console.setErr(newOut)
+ try {
+ op
+ } catch {
+ case ex: StopException =>
+ case ex: Throwable => ex.printStackTrace()
+ } finally {
+ currentWriter.close()
+ System.setOut(oldSysOut)
+ System.setErr(oldSysErr)
+ Console.setOut(oldConsOut)
+ Console.setErr(oldConsErr)
+ println("done")
+ println(si.currentContents.mkString)
+ }
+ }
def $skip(n: Int) = currentWriter.skip(n)