scala.tools.nsc.interpreter.Pasted.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* NSC -- new Scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Paul Phillips
*/
package scala.tools.nsc
package interpreter
/** If it looks like they're pasting in a scala interpreter
* transcript, remove all the formatting we inserted so we
* can make some sense of it.
*
* Most of the interesting code in here is due to my goal of
* "paste idempotence" i.e. the transcript resulting from pasting
* a transcript should itself be pasteable and should achieve
* the same result.
*/
abstract class Pasted {
def ContinueString: String
def PromptString: String
def interpret(line: String): Unit
def matchesPrompt(line: String) = matchesString(line, PromptString)
def matchesContinue(line: String) = matchesString(line, ContinueString)
def running = isRunning
private def matchesString(line: String, target: String): Boolean = (
(line startsWith target) ||
(line.nonEmpty && " \t".toSet(line.head) && matchesString(line.tail, target))
)
private def stripString(line: String, target: String) = line indexOf target match {
case -1 => line
case idx => line drop (idx + target.length)
}
private var isRunning = false
private val resReference = """(? prompt and
* rewrite the line containing as
* val res15 = { }
* and the rest as they say is rewritten history.
*
* In all other cases, discard the line.
*/
def fixResRefs(code: String, line: String) = line match {
case resCreation(resName) if referenced(resName) =>
code.lastIndexOf(PromptString) match {
case -1 => code
case idx =>
val (str1, str2) = code splitAt (idx + PromptString.length)
str2 match {
case resAssign(`resName`) => code
case _ => "%sval %s = { %s }".format(str1, resName, str2)
}
}
case _ => code
}
def run() {
println("// Replaying %d commands from transcript.\n" format cmds.size)
cmds foreach { cmd =>
print(PromptString)
interpret(cmd)
}
}
}
/** Commands start on lines beginning with "scala>" and each successive
* line which begins with the continuation string is appended to that command.
* Everything else is discarded. When the end of the transcript is spotted,
* all the commands are replayed.
*/
def apply(lines: TraversableOnce[String]) = {
isRunning = true
try new PasteAnalyzer(lines.toList) run()
finally isRunning = false
}
}