summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-04-11 03:04:47 +0000
committerPaul Phillips <paulp@improving.org>2011-04-11 03:04:47 +0000
commit6b7ff287fcd56109d1db51ff82fce0ed0cdbcca6 (patch)
tree4b9bae5d44cf3f26f8d7063570d6c3d86c0a8a74 /src
parent35f82e66d1fd3aa0d3d9171a1ab92b8a00e4f7bb (diff)
downloadscala-6b7ff287fcd56109d1db51ff82fce0ed0cdbcca6.tar.gz
scala-6b7ff287fcd56109d1db51ff82fce0ed0cdbcca6.tar.bz2
scala-6b7ff287fcd56109d1db51ff82fce0ed0cdbcca6.zip
Improving the repl help infrastructure, and mad...
Improving the repl help infrastructure, and made the :wrap command more robust. No review.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala214
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala19
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala3
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplStrings.scala45
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/package.scala21
6 files changed, 180 insertions, 131 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index b6a6da369f..d6e447ca0a 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -43,8 +43,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
var settings: Settings = _
var intp: IMain = _
- def codeQuoted(s: String) = intp.memberHandlers.string2codeQuoted(s)
-
lazy val power = {
val g = intp.global
Power[g.type](this, g)
@@ -129,7 +127,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
|// Calling Thread.stop on runaway %s with offending code:
|// scala> %s""".stripMargin
- println(template.format(line.thread, line.code))
+ echo(template.format(line.thread, line.code))
// XXX no way to suppress the deprecation warning
line.thread.stop()
in.redrawLine()
@@ -150,14 +148,40 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
}
/** print a friendly help message */
- def helpCommand() = {
- val usageWidth = commands map (_.usageMsg.length) max
- val cmds = commands map (x => (x.usageMsg, x.help))
- val formatStr = "%-" + usageWidth + "s %s"
+ def helpCommand(line: String): Result = {
+ if (line == "") helpSummary()
+ else uniqueCommand(line) match {
+ case Some(lc) => echo("\n" + lc.longHelp)
+ case _ => ambiguousError(line)
+ }
+ }
+ private def helpSummary() = {
+ val usageWidth = commands map (_.usageMsg.length) max
+ val formatStr = "%-" + usageWidth + "s %s %s"
+
+ echo("All commands can be abbreviated, e.g. :he instead of :help.")
+ echo("Those marked with a * have more detailed help, e.g. :help imports.\n")
- out println "All commands can be abbreviated - for example :he instead of :help.\n"
- for ((use, help) <- cmds)
- out println formatStr.format(use, help)
+ commands foreach { cmd =>
+ val star = if (cmd.hasLongHelp) "*" else " "
+ echo(formatStr.format(cmd.usageMsg, star, cmd.help))
+ }
+ }
+ private def ambiguousError(cmd: String): Result = {
+ matchingCommands(cmd) match {
+ case Nil => echo(cmd + ": no such command. Type :help for help.")
+ case xs => echo(cmd + " is ambiguous: did you mean " + xs.map(":" + _.name).mkString(" or ") + "?")
+ }
+ Result(true, None)
+ }
+ private def matchingCommands(cmd: String) = commands filter (_.name startsWith cmd)
+ private def uniqueCommand(cmd: String): Option[LoopCommand] = {
+ // this lets us add commands willy-nilly and only requires enough command to disambiguate
+ matchingCommands(cmd) match {
+ case List(x) => Some(x)
+ // exact match OK even if otherwise appears ambiguous
+ case xs => xs find (_.name == cmd)
+ }
}
/** Print a welcome message */
@@ -170,7 +194,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
stripMargin.format(versionString, javaVmName, javaVersion)
val addendum = if (isReplDebug) "\n" + new java.util.Date else ""
- plushln(welcomeMsg + addendum)
+ echo(welcomeMsg + addendum)
}
/** Show the history */
@@ -189,15 +213,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val offset = current - lines.size + 1
for ((line, index) <- lines.zipWithIndex)
- println("%3d %s".format(index + offset, line))
+ echo("%3d %s".format(index + offset, line))
}
}
- /** Some print conveniences */
- def println(x: Any) = out println x
- def plush(x: Any) = { out print x ; out.flush() }
- def plushln(x: Any) = { out println x ; out.flush() }
-
private def echo(msg: String) = {
out println msg
out.flush()
@@ -213,7 +232,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val offset = history.index - history.size + 1
for ((line, index) <- history.asStrings.zipWithIndex ; if line.toLowerCase contains cmdline)
- println("%d %s".format(index + offset, line))
+ echo("%d %s".format(index + offset, line))
}
private var currentPrompt = Properties.shellPromptString
@@ -224,9 +243,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
import LoopCommand.{ cmd, nullary }
/** Standard commands **/
- val standardCommands = List(
- cmd("cp", "<path>", "add an entry (jar or directory) to the classpath", addClasspath),
- nullary("help", "print this help message", helpCommand),
+ lazy val standardCommands = List(
+ cmd("cp", "<path>", "add a jar or directory to the classpath", addClasspath),
+ cmd("help", "[command]", "print this summary or command-specific help", helpCommand),
historyCommand,
cmd("h?", "<string>", "search the history", searchHistory),
cmd("imports", "[name name ...]", "show import history, identifying sources of names", importsCommand),
@@ -244,15 +263,34 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
)
/** Power user commands */
- val powerCommands: List[LoopCommand] = List(
+ lazy val powerCommands: List[LoopCommand] = List(
nullary("dump", "displays a view of the interpreter's internal state", dumpCommand),
cmd("phase", "<phase>", "set the implicit phase for power commands", phaseCommand),
- cmd("wrap", "<code>", "code to wrap around all executions", wrapCommand)
+ cmd("wrap", "<method>", "name of method to wrap around each repl line", wrapCommand) withLongHelp ("""
+ |:wrap
+ |:wrap <method>
+ |
+ |Installs a wrapper around each line entered into the repl.
+ |Currently it must be the simple name of an existing method
+ |with the specific signature shown in the following example.
+ |
+ |def timed[T](body: => T): T = {
+ | val start = System.nanoTime
+ | try body
+ | finally println((System.nanoTime - start) + " nanos elapsed.")
+ |}
+ |:wrap timed
+ |
+ |If given no argument, :wrap removes any wrapper present.
+ |Note that wrappers do not compose (a new one replaces the old
+ |one) and also that the :phase command uses the same machinery,
+ |so setting :wrap will clear any :phase setting.
+ """.stripMargin.trim)
)
private def dumpCommand(): Result = {
- println(power)
- history.asStrings takeRight 30 foreach println
+ echo("" + power)
+ history.asStrings takeRight 30 foreach echo
in.redrawLine()
}
@@ -385,16 +423,35 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
private def keybindingsCommand(): Result = {
if (in.keyBindings.isEmpty) "Key bindings unavailable."
else {
- println("Reading jline properties for default key bindings.")
- println("Accuracy not guaranteed: treat this as a guideline only.\n")
- in.keyBindings foreach println
+ echo("Reading jline properties for default key bindings.")
+ echo("Accuracy not guaranteed: treat this as a guideline only.\n")
+ in.keyBindings foreach (x => echo ("" + x))
}
}
private def wrapCommand(line: String): Result = {
- intp setExecutionWrapper line
- if (line == "") "Cleared wrapper."
- else "Set wrapper to '" + line + "'"
+ def failMsg = "Argument to :wrap must be the name of a method with signature [T](=> T): T"
+ val intp = ILoop.this.intp
+ val g: intp.global.type = intp.global
+ import g._
+
+ words(line) match {
+ case Nil =>
+ intp setExecutionWrapper ""
+ "Cleared wrapper."
+ case wrapper :: Nil =>
+ intp.typeOfExpression(wrapper) match {
+ case Some(PolyType(List(targ), MethodType(List(arg), restpe))) =>
+ intp setExecutionWrapper intp.pathToTerm(wrapper)
+ "Set wrapper to '" + wrapper + "'"
+ case Some(x) =>
+ failMsg + "\nFound: " + x
+ case _ =>
+ failMsg + "\nFound: <unknown>"
+ }
+ case _ => failMsg
+ }
}
+
private def pathToPhaseWrapper = intp.pathToTerm("$r") + ".phased.atCurrent"
private def phaseCommand(name: String): Result = {
// This line crashes us in TreeGen:
@@ -451,15 +508,15 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
case ex: Throwable =>
if (settings.YrichExes.value) {
val sources = implicitly[Sources]
- out.println("\n" + ex.getMessage)
- out.println(
+ echo("\n" + ex.getMessage)
+ echo(
if (isReplDebug) "[searching " + sources.path + " for exception contexts...]"
else "[searching for exception contexts...]"
)
- out.println(Exceptional(ex).force().context())
+ echo(Exceptional(ex).force().context())
}
else {
- out.println(util.stackTraceString(ex))
+ echo(util.stackTraceString(ex))
}
ex match {
case _: NoSuchMethodError | _: NoClassDefFoundError =>
@@ -467,7 +524,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
throw ex
case _ =>
def fn(): Boolean = in.readYesOrNo(replayQuestionMessage, { echo("\nYou must enter y or n.") ; fn() })
-
if (fn()) replay()
else echo("\nAbandoning crashed session.")
}
@@ -504,7 +560,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
try file applyReader { reader =>
in = SimpleReader(reader, out, false)
- plushln("Loading " + file + "...")
+ echo("Loading " + file + "...")
loop()
}
finally {
@@ -518,9 +574,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
closeInterpreter()
createInterpreter()
for (cmd <- replayCommands) {
- plushln("Replaying: " + cmd) // flush because maybe cmd will have its own output
+ echo("Replaying: " + cmd) // flush because maybe cmd will have its own output
command(cmd)
- out.println
+ echo("")
}
}
@@ -530,7 +586,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
def apply(line: String): Result = line match {
case "" => showUsage()
case _ =>
- val toRun = classOf[ProcessResult].getName + "(" + codeQuoted(line) + ")"
+ val toRun = classOf[ProcessResult].getName + "(" + string2codeQuoted(line) + ")"
intp interpret toRun
()
}
@@ -540,7 +596,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val f = File(filename)
if (f.exists) action(f)
- else out.println("That file does not exist")
+ else echo("That file does not exist")
}
def loadCommand(arg: String) = {
@@ -557,10 +613,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
if (f.exists) {
addedClasspath = ClassPath.join(addedClasspath, f.path)
val totalClasspath = ClassPath.join(settings.classpath.value, addedClasspath)
- println("Added '%s'. Your new classpath is:\n\"%s\"".format(f.path, totalClasspath))
+ echo("Added '%s'. Your new classpath is:\n\"%s\"".format(f.path, totalClasspath))
replay()
}
- else out.println("The path '" + f + "' doesn't seem to exist.")
+ else echo("The path '" + f + "' doesn't seem to exist.")
}
def powerCmd(): Result = {
@@ -570,48 +626,28 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
def enablePowerMode() = {
replProps.power setValue true
power.unleash()
- out.println(power.banner)
+ echo(power.banner)
}
def verbosity() = {
val old = intp.printResults
intp.printResults = !old
- out.println("Switched " + (if (old) "off" else "on") + " result printing.")
+ echo("Switched " + (if (old) "off" else "on") + " result printing.")
}
/** Run one command submitted by the user. Two values are returned:
* (1) whether to keep running, (2) the line to record for replay,
* if any. */
def command(line: String): Result = {
- def withError(msg: String) = {
- out println msg
- Result(true, None)
- }
- def ambiguous(cmds: List[LoopCommand]) = "Ambiguous: did you mean " + cmds.map(":" + _.name).mkString(" or ") + "?"
-
- // not a command
- if (!line.startsWith(":")) {
- // Notice failure to create compiler
- if (intp.global == null) return Result(false, None)
- else return Result(true, interpretStartingWith(line))
- }
-
- val line2 = line.tail
- val (cmd, rest) = line2 indexWhere (_.isWhitespace) match {
- case -1 => (line2, "")
- case idx => (line2 take idx, line2 drop idx dropWhile (_.isWhitespace))
- }
-
- // this lets us add commands willy-nilly and only requires enough command to disambiguate
- commands.filter(_.name startsWith cmd) match {
- case List(f) => f(rest)
- case Nil => withError("Unknown command. Type :help for help.")
- case fs =>
- fs find (_.name == cmd) match {
- case Some(exact) => exact(rest)
- case _ => withError(ambiguous(fs))
- }
+ if (line startsWith ":") {
+ val cmd = line.tail takeWhile (x => !x.isWhitespace)
+ uniqueCommand(cmd) match {
+ case Some(lc) => lc(line.tail stripPrefix cmd dropWhile (_.isWhitespace))
+ case _ => ambiguousError(cmd)
+ }
}
+ else if (intp.global == null) Result(false, None) // Notice failure to create compiler
+ else Result(true, interpretStartingWith(line))
}
private def readWhile(cond: String => Boolean) = {
@@ -619,10 +655,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
}
def pasteCommand(): Result = {
- out.println("// Entering paste mode (ctrl-D to finish)\n")
- out.flush()
+ echo("// Entering paste mode (ctrl-D to finish)\n")
val code = readWhile(_ => true) mkString "\n"
- out.println("\n// Exiting paste mode, now interpreting.\n")
+ echo("\n// Exiting paste mode, now interpreting.\n")
intp interpret code
()
}
@@ -632,9 +667,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val PromptString = "scala> "
def interpret(line: String): Unit = {
- out.println(line.trim)
+ echo(line.trim)
intp interpret line
- out.println("")
+ echo("")
}
def transcript(start: String) = {
@@ -642,7 +677,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
// transcript they just pasted. Todo: a short timer goes off when
// lines stop coming which tells them to hit ctrl-D.
//
- // out.println("// Detected repl transcript paste: ctrl-D to finish.")
+ // echo("// Detected repl transcript paste: ctrl-D to finish.")
apply(Iterator(start) ++ readWhile(_.trim != PromptString.trim))
}
}
@@ -665,7 +700,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
case IR.Success => Some(code)
case IR.Incomplete =>
if (in.interactive && code.endsWith("\n\n")) {
- out.println("You typed two blank lines. Starting a new command.")
+ echo("You typed two blank lines. Starting a new command.")
None
}
else in.readLine(ContinueString) match {
@@ -730,7 +765,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val cmd = ":load " + filename
command(cmd)
addReplay(cmd)
- out.println()
+ echo("")
}
case _ =>
}
@@ -748,8 +783,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
)
catch {
case ex @ (_: Exception | _: NoClassDefFoundError) =>
- out.println("Failed to created JLineReader: " + ex)
- out.println("Falling back to SimpleReader.")
+ echo("Failed to created JLineReader: " + ex + "\nFalling back to SimpleReader.")
SimpleReader()
}
}
@@ -778,7 +812,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
// they type a command the compiler is ready to roll.
intp.initialize()
if (isReplPower) {
- plushln("Starting in power mode, one moment...\n")
+ echo("Starting in power mode, one moment...\n")
enablePowerMode()
}
loop()
@@ -789,8 +823,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
/** process command-line arguments and do as they request */
def process(args: Array[String]): Boolean = {
- def error1(msg: String) = out println ("scala: " + msg)
- val command = new CommandLine(args.toList, error1)
+ val command = new CommandLine(args.toList, msg => echo("scala: " + msg))
def neededHelp(): String =
(if (command.settings.help.value) command.usageMsg + "\n" else "") +
(if (command.settings.Xhelp.value) command.xusageMsg + "\n" else "")
@@ -798,7 +831,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
// if they asked for no help and command is valid, we call the real main
neededHelp() match {
case "" => command.ok && process(command.settings)
- case help => plush(help) ; true
+ case help => echoNoNL(help) ; true
}
}
@@ -815,6 +848,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
object ILoop {
implicit def loopToInterpreter(repl: ILoop): IMain = repl.intp
+ private def echo(msg: String) = Console println msg
// Designed primarily for use by test code: take a String with a
// bunch of code, and prints out a transcript of what it would look
@@ -882,11 +916,11 @@ object ILoop {
val msg = if (args.isEmpty) "" else " Binding " + args.size + " value%s.".format(
if (args.size == 1) "" else "s"
)
- Console.println("Debug repl starting." + msg)
+ echo("Debug repl starting." + msg)
val repl = new ILoop {
override def prompt = "\ndebug> "
}
- repl.settings = new Settings(Console println _)
+ repl.settings = new Settings(echo)
repl.settings.embeddedDefaults[T]
repl.createInterpreter()
repl.in = JLineReader(repl)
@@ -896,7 +930,7 @@ object ILoop {
args foreach (p => repl.bind(p.name, p.tpe, p.value))
repl.loop()
- Console.println("\nDebug repl exiting.")
+ echo("\nDebug repl exiting.")
repl.closeInterpreter()
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
index 2fa7f1501b..196d8b882f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
@@ -31,12 +31,19 @@ trait LoopCommands {
// a single interpreter command
abstract class LoopCommand(val name: String, val help: String) extends (String => Result) {
+ private var _longHelp: String = null
+ final def defaultHelp = usageMsg + " (no extended help available.)"
+ def hasLongHelp = _longHelp != null || longHelp != defaultHelp
+ def withLongHelp(text: String): this.type = { _longHelp = text ; this }
+ def longHelp = _longHelp match {
+ case null => defaultHelp
+ case text => text
+ }
def usage: String = ""
def usageMsg: String = ":" + name + (
if (usage == "") "" else " " + usage
)
def apply(line: String): Result
- protected def words(line: String): List[String] = line split "\\s+" toList
// called if no args are given
def showUsage(): Result = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index 208b033afb..330294f823 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -18,25 +18,6 @@ trait MemberHandlers {
import global._
import naming._
- def string2codeQuoted(str: String) =
- "\"" + string2code(str) + "\""
-
- def any2stringOf(x: Any, maxlen: Int) =
- "scala.runtime.ScalaRunTime.replStringOf(%s, %s)".format(x, maxlen)
-
- /** Convert a string into code that can recreate the string.
- * This requires replacing all special characters by escape
- * codes. It does not add the surrounding " marks. */
- def string2code(str: String): String = {
- val res = new StringBuilder
- for (c <- str) c match {
- case '"' | '\'' | '\\' => res += '\\' ; res += c
- case _ if c.isControl => res ++= Chars.char2uescape(c)
- case _ => res += c
- }
- res.toString
- }
-
private def codegenln(leadingPlus: Boolean, xs: String*): String = codegen(leadingPlus, (xs ++ Array("\n")): _*)
private def codegenln(xs: String*): String = codegenln(true, xs: _*)
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 1d68c14d4a..c2f72e9f37 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -135,6 +135,7 @@ abstract class Power[G <: Global](
|import scala.tools.nsc._
|import scala.collection.JavaConverters._
|import global._
+ |import power.Implicits._
""".stripMargin
/** Starts up power mode and runs whatever is in init.
@@ -318,7 +319,7 @@ abstract class Power[G <: Global](
implicit def replInputStreamURL(url: URL)(implicit codec: Codec) = replInputStream(url.openStream())
}
object Implicits extends Implicits2 {
- val global = Power.this.global
+ val global: G = Power.this.global
}
trait ReplUtilities {
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplStrings.scala b/src/compiler/scala/tools/nsc/interpreter/ReplStrings.scala
new file mode 100644
index 0000000000..cef46c963a
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplStrings.scala
@@ -0,0 +1,45 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import scala.collection.{ mutable, immutable }
+import scala.PartialFunction.cond
+import scala.reflect.NameTransformer
+import util.Chars
+
+trait ReplStrings {
+ // Longest common prefix
+ def longestCommonPrefix(xs: List[String]): String = {
+ if (xs.isEmpty || xs.contains("")) ""
+ else xs.head.head match {
+ case ch =>
+ if (xs.tail forall (_.head == ch)) "" + ch + longestCommonPrefix(xs map (_.tail))
+ else ""
+ }
+ }
+ /** Convert a string into code that can recreate the string.
+ * This requires replacing all special characters by escape
+ * codes. It does not add the surrounding " marks. */
+ def string2code(str: String): String = {
+ val res = new StringBuilder
+ for (c <- str) c match {
+ case '"' | '\'' | '\\' => res += '\\' ; res += c
+ case _ if c.isControl => res ++= Chars.char2uescape(c)
+ case _ => res += c
+ }
+ res.toString
+ }
+
+ def string2codeQuoted(str: String) =
+ "\"" + string2code(str) + "\""
+
+ def any2stringOf(x: Any, maxlen: Int) =
+ "scala.runtime.ScalaRunTime.replStringOf(%s, %s)".format(x, maxlen)
+
+ def words(s: String) = s.trim split "\\s+" filterNot (_ == "") toList
+ def isQuoted(s: String) = (s.length >= 2) && (s.head == s.last) && ("\"'" contains s.head)
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala
index aaf07343cb..1865e90e92 100644
--- a/src/compiler/scala/tools/nsc/interpreter/package.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/package.scala
@@ -22,7 +22,7 @@ package scala.tools.nsc
* InteractiveReader contains { history: History, completion: Completion }
* IMain contains { global: Global }
*/
-package object interpreter extends ReplConfig {
+package object interpreter extends ReplConfig with ReplStrings {
type JFile = java.io.File
type JClass = java.lang.Class[_]
type JList[T] = java.util.List[T]
@@ -35,23 +35,4 @@ package object interpreter extends ReplConfig {
import collection.JavaConverters._
xs.asScala.toList map ("" + _)
}
-
- // Longest common prefix
- def longestCommonPrefix(xs: List[String]): String = {
- if (xs.isEmpty || xs.contains("")) ""
- else xs.head.head match {
- case ch =>
- if (xs.tail forall (_.head == ch)) "" + ch + longestCommonPrefix(xs map (_.tail))
- else ""
- }
- }
-
- private[nsc] def words(s: String) = s.trim split "\\s+" toList
- private[nsc] def isQuoted(s: String) =
- (s.length >= 2) && (s.head == s.last) && ("\"'" contains s.head)
-
- /** Class objects */
- private[nsc] def classForName(name: String): Option[JClass] =
- try Some(Class forName name)
- catch { case _: ClassNotFoundException | _: SecurityException => None }
}