summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-04-27 07:21:29 +0000
committerPaul Phillips <paulp@improving.org>2010-04-27 07:21:29 +0000
commit4f24cb62ce0932938d5428ec6e4b02b670c4a173 (patch)
tree021e3da016c753fff498055ebf11d866473eb53a
parentcf552d7f27ce5aaf27d890b5f4068914aca76444 (diff)
downloadscala-4f24cb62ce0932938d5428ec6e4b02b670c4a173.tar.gz
scala-4f24cb62ce0932938d5428ec6e4b02b670c4a173.tar.bz2
scala-4f24cb62ce0932938d5428ec6e4b02b670c4a173.zip
Some cleanups in repl completion and power mode.
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala140
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterLoop.scala21
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Completion.scala2
3 files changed, 72 insertions, 91 deletions
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index a494352b9b..547799bd4f 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -74,6 +74,8 @@ import Interpreter._
* @author Lex Spoon
*/
class Interpreter(val settings: Settings, out: PrintWriter) {
+ repl =>
+
/** construct an interpreter that reports to Console */
def this(settings: Settings) = this(settings, new NewLinePrintWriter(new ConsoleWriter, true))
def this() = this(new Settings())
@@ -493,44 +495,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
}
- /** For :power - create trees and type aliases from code snippets. */
- def mkContext(code: String = "") = compiler.analyzer.rootContext(mkUnit(code))
- def mkAlias(name: String, what: String) = interpret("type %s = %s".format(name, what))
- def mkSourceFile(code: String) = new BatchSourceFile("<console>", code)
- def mkUnit(code: String) = new CompilationUnit(mkSourceFile(code))
-
- def mkTree(code: String): Tree = mkTrees(code).headOption getOrElse EmptyTree
- def mkTrees(code: String): List[Tree] = parse(code) getOrElse Nil
- def mkTypedTrees(code: String*): List[compiler.Tree] = {
- class TyperRun extends compiler.Run {
- override def stopPhase(name: String) = name == "superaccessors"
- }
-
- reporter.reset
- val run = new TyperRun
- run compileSources (code.toList.zipWithIndex map {
- case (s, i) => new BatchSourceFile("<console %d>".format(i), s)
- })
- run.units.toList map (_.body)
- }
- def mkTypedTree(code: String) = mkTypedTrees(code).head
-
- def mkType(id: String): compiler.Type = {
- // if it's a recognized identifier, the type of that; otherwise treat the
- // String like a value (e.g. scala.collection.Map) .
- def findType = typeForIdent(id) match {
- case Some(x) => definitions.getClass(newTermName(x)).tpe
- case _ => definitions.getModule(newTermName(id)).tpe
- }
-
- try findType catch { case _: MissingRequirementError => NoType }
- }
-
- private[nsc] val powerMkImports = List(
- "mkContext", "mkTree", "mkTrees", "mkAlias", "mkSourceFile", "mkUnit", "mkType", "mkTypedTree", "mkTypedTrees"
- // , "treeWrapper"
- )
-
/** Compile an nsc SourceFile. Returns true if there are
* no compilation errors, or false otherwise.
*/
@@ -805,7 +769,7 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
private class ImportHandler(imp: Import) extends MemberHandler(imp) {
lazy val Import(expr, selectors) = imp
- def targetType = mkType(expr.toString) match {
+ def targetType = stringToCompilerType(expr.toString) match {
case NoType => None
case x => Some(x)
}
@@ -1023,43 +987,58 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
}
- /** These methods are exposed so REPL commands can access them.
- * The command infrastructure is in InterpreterLoop.
+ /** A container class for methods to be injected into the repl
+ * in power mode.
*/
- def dumpState(xs: List[String]): String = """
- | Names used: %s
- |
- | Identifiers: %s
- |
- | synthvars: %d
- """.stripMargin.format(
- allUsedNames mkString " ",
- unqualifiedIds mkString " ",
- allBoundNames filter isSynthVarName size
- )
-
- // def dumpTrees(xs: List[String]): String = {
- // val treestrs = (xs map requestForIdent).flatten flatMap (_.trees)
- //
- // if (treestrs.isEmpty) "No trees found."
- // else treestrs.map(t => t.toString + " (" + t.getClass.getSimpleName + ")\n").mkString
- // }
+ class Power {
+ def mkContext(code: String = "") = compiler.analyzer.rootContext(mkUnit(code))
+ def mkAlias(name: String, what: String) = interpret("type %s = %s".format(name, what))
+ def mkSourceFile(code: String) = new BatchSourceFile("<console>", code)
+ def mkUnit(code: String) = new CompilationUnit(mkSourceFile(code))
+
+ def mkTree(code: String): Tree = mkTrees(code).headOption getOrElse EmptyTree
+ def mkTrees(code: String): List[Tree] = parse(code) getOrElse Nil
+ def mkTypedTrees(code: String*): List[compiler.Tree] = {
+ class TyperRun extends compiler.Run {
+ override def stopPhase(name: String) = name == "superaccessors"
+ }
- def powerUser(): String = {
- beQuietDuring {
- this.bind("repl", "scala.tools.nsc.Interpreter", this)
- this.bind("global", "scala.tools.nsc.Global", compiler)
- interpret("import repl.{ %s, eval }".format(powerMkImports mkString ", "), false)
+ reporter.reset
+ val run = new TyperRun
+ run compileSources (code.toList.zipWithIndex map {
+ case (s, i) => new BatchSourceFile("<console %d>".format(i), s)
+ })
+ run.units.toList map (_.body)
}
+ def mkTypedTree(code: String) = mkTypedTrees(code).head
+ def mkType(id: String): compiler.Type = stringToCompilerType(id)
+
+ def dump(): String = (
+ ("Names used: " :: allUsedNames) ++
+ ("\nIdentifiers: " :: unqualifiedIds)
+ ) mkString " "
+ }
+
+ lazy val power = new Power
- """** Power User mode enabled - BEEP BOOP **
- |** New vals! Try repl, global **
- |** New cmds! :help to discover them **
- |** New defs! Give these a whirl: **
- |** mkAlias("Fn", "(String, Int) => Int") **
- |** mkTree("def f(x: Int, y: Int) = x+y") **""".stripMargin
+ def unleash(): Unit = beQuietDuring {
+ interpret("import scala.tools.nsc._")
+ repl.bind("repl", "scala.tools.nsc.Interpreter", this)
+ interpret("val global: repl.compiler.type = repl.compiler")
+ interpret("val power: scala.tools.nsc.Interpreter#Power = repl.power")
+ // interpret("val replVars = repl.replVars")
}
+ /** Artificial object demonstrating completion */
+ // lazy val replVars = CompletionAware(
+ // Map[String, CompletionAware](
+ // "ids" -> CompletionAware(() => unqualifiedIds, completionAware _),
+ // "synthVars" -> CompletionAware(() => allBoundNames filter isSynthVarName map (_.toString)),
+ // "types" -> CompletionAware(() => allSeenTypes map (_.toString)),
+ // "implicits" -> CompletionAware(() => allImplicits map (_.toString))
+ // )
+ // )
+
/** Returns the name of the most recent interpreter result.
* Mostly this exists so you can conveniently invoke methods on
* the previous result.
@@ -1078,6 +1057,17 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
private def requestForIdent(line: String): Option[Request] = requestForName(newTermName(line))
+ def stringToCompilerType(id: String): compiler.Type = {
+ // if it's a recognized identifier, the type of that; otherwise treat the
+ // String like a value (e.g. scala.collection.Map) .
+ def findType = typeForIdent(id) match {
+ case Some(x) => definitions.getClass(newTermName(x)).tpe
+ case _ => definitions.getModule(newTermName(id)).tpe
+ }
+
+ try findType catch { case _: MissingRequirementError => NoType }
+ }
+
def typeForIdent(id: String): Option[String] =
requestForIdent(id) flatMap (x => x.typeOf get newTermName(id))
@@ -1208,16 +1198,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
/** Parse the ScalaSig to find type aliases */
def aliasForType(path: String) = ByteCode.aliasForType(path)
- /** Artificial object demonstrating completion */
- def replVarsObject() = CompletionAware(
- Map[String, CompletionAware](
- "ids" -> CompletionAware(() => unqualifiedIds, completionAware _),
- "synthVars" -> CompletionAware(() => allBoundNames filter isSynthVarName map (_.toString)),
- "types" -> CompletionAware(() => allSeenTypes map (_.toString)),
- "implicits" -> CompletionAware(() => allImplicits map (_.toString))
- )
- )
-
// Coming soon
// implicit def string2liftedcode(s: String): LiftedCode = new LiftedCode(s)
// case class LiftedCode(code: String) {
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
index 4dd6c88eaa..d369ef4fa3 100644
--- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
@@ -211,15 +211,12 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
}
/** Power user commands */
- // XXX - why does a third argument like "interpreter dumpState(_)" throw an NPE
- // while the version below works?
var powerUserOn = false
val powerCommands: List[Command] = {
import CommandImplicits._
List(
OneArg("completions", "generate list of completions for a given String", completions),
- VarArgs("dump", "displays a view of the interpreter's internal state",
- (xs: List[String]) => interpreter dumpState xs)
+ NoArgs("dump", "displays a view of the interpreter's internal state", () => interpreter.power.dump())
// VarArgs("tree", "displays ASTs for specified identifiers",
// (xs: List[String]) => interpreter dumpTrees xs)
@@ -339,13 +336,17 @@ class InterpreterLoop(in0: Option[BufferedReader], protected val out: PrintWrite
}
def power() {
- powerUserOn = true
- out println interpreter.powerUser()
- if (in.history.isDefined)
- interpreter.quietBind("history", "scala.collection.immutable.List[String]", in.historyList)
+ val powerUserBanner =
+ """** Power User mode enabled - BEEP BOOP **
+ |** scala.tools.nsc._ has been imported **
+ |** New vals! Try repl, global, power **
+ |** New cmds! :help to discover them **
+ |** New defs! Type power.<tab> to reveal **""".stripMargin
- if (in.completion.isDefined)
- interpreter.quietBind("replHelper", "scala.tools.nsc.interpreter.CompletionAware", interpreter.replVarsObject())
+ powerUserOn = true
+ interpreter.unleash()
+ injectOne("history", in.historyList)
+ out println powerUserBanner
}
def verbosity() = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
index ca7bb54ab0..24b5737960 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
@@ -179,7 +179,7 @@ class Completion(val repl: Interpreter) {
class ImportCompletion(tp: Type) extends TypeMemberCompletion(tp) {
override def completions(verbosity: Int) = verbosity match {
- case 0 => filtered(methods filterNot (_.isSetter) map tos)
+ case 0 => filtered(members filterNot (_.isSetter) map tos)
case _ => super.completions(verbosity)
}
}