summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-03-28 07:34:04 +0000
committerPaul Phillips <paulp@improving.org>2011-03-28 07:34:04 +0000
commit1b4fc3f26ea5efbf4784e1eb6d1de38ab1d8b013 (patch)
tree86f385fa9babfce3528a580306b079032af6edee /src
parent54f560fe37e9b95517822cec0a78e96cdb256abc (diff)
downloadscala-1b4fc3f26ea5efbf4784e1eb6d1de38ab1d8b013.tar.gz
scala-1b4fc3f26ea5efbf4784e1eb6d1de38ab1d8b013.tar.bz2
scala-1b4fc3f26ea5efbf4784e1eb6d1de38ab1d8b013.zip
Learned an interesting lesson about having an i...
Learned an interesting lesson about having an implicit object with a "def apply(x: Any): List[String]" method imported into power mode. Let's just say this is not advised. This and other rough edges eliminated from power mode, no review.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala157
2 files changed, 112 insertions, 50 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 4541dc165b..d018a5420d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -44,7 +44,10 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
var settings: Settings = _
var intp: IMain = _
- lazy val power = new Power(this)
+ lazy val power = {
+ val g = intp.global
+ Power[g.type](this, g)
+ }
// TODO
// object opt extends AestheticSettings
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 0933365d9e..01b2d2328f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -6,20 +6,56 @@
package scala.tools.nsc
package interpreter
+import scala.reflect.NameTransformer
import scala.collection.{ mutable, immutable }
import scala.util.matching.Regex
import scala.tools.nsc.util.{ BatchSourceFile }
import session.{ History }
+trait SharesGlobal[G <: Global] {
+ val global: G
+
+ // This business gets really old:
+ //
+ // found : power.intp.global.Symbol
+ // required: global.Symbol
+ //
+ // Have tried many ways to cast it aside, this is the current winner.
+ // Todo: figure out a way to abstract over all the type members.
+ type AnySymbol = Global#Symbol
+ type AnyType = Global#Type
+ type AnyName = Global#Name
+ type AnyTree = Global#Tree
+
+ type Symbol = global.Symbol
+ type Type = global.Type
+ type Name = global.Name
+ type Tree = global.Tree
+
+ implicit def upDependentSymbol(x: AnySymbol): Symbol = x.asInstanceOf[Symbol]
+ implicit def upDependentType(x: AnyType): Type = x.asInstanceOf[Type]
+ implicit def upDependentName(x: AnyName): Name = x.asInstanceOf[Name]
+ implicit def upDependentTree(x: AnyTree): Tree = x.asInstanceOf[Tree]
+}
+
+object Power {
+ def apply[G <: Global](repl: ILoop, g: G) =
+ new { final val global: G = g }
+ with Power[G](repl, repl.intp) // .asInstanceOf[IMain { val global: G }])
+
+ def apply(intp: IMain) =
+ new { final val global = intp.global }
+ with Power[Global](null, intp)
+}
+
/** A class for methods to be injected into the intp in power mode.
*/
-class Power(repl: ILoop, intp: IMain) {
- def this(repl: ILoop) = this(repl, repl.intp)
- def this(intp: IMain) = this(null, intp)
-
- val global: intp.global.type = intp.global
- import global._
+abstract class Power[G <: Global](
+ val repl: ILoop,
+ val intp: IMain // { val global: G }
+) extends SharesGlobal[G] {
import intp.{ beQuietDuring, interpret, parse }
+ import global.{ opt, definitions, stringToTermName, NoSymbol, NoType, analyzer, CompilationUnit }
abstract class SymSlurper {
def isKeep(sym: Symbol): Boolean
@@ -93,24 +129,22 @@ class Power(repl: ILoop, intp: IMain) {
def init = """
|import scala.tools.nsc._
- |val global: intp.global.type = intp.global
+ |import interpreter.Power
+ |final val global = repl.power.global
+ |final val power = repl.power.asInstanceOf[Power[global.type]]
+ |final val intp = repl.intp
|import global._
|import definitions._
|import power.phased
- |import power.Implicits._
+ |import power.Implicits.{ global => _, _ }
""".stripMargin
/** Starts up power mode and runs whatever is in init.
*/
def unleash(): Unit = beQuietDuring {
- if (repl != null) {
- intp.bind[ILoop]("repl", repl)
- intp.bind[History]("history", repl.in.history)
- intp.bind("completion", repl.in.completion)
- }
-
- intp.bind[IMain]("intp", intp)
- intp.bind[Power]("power", this)
+ intp.bind[ILoop]("repl", repl)
+ intp.bind[History]("history", repl.in.history)
+ intp.bind("completion", repl.in.completion)
intp.bind[ISettings]("isettings", intp.isettings)
init split '\n' foreach interpret
}
@@ -122,9 +156,11 @@ class Power(repl: ILoop, intp: IMain) {
private def getCompilerClass(name: String) = missingWrap(definitions.getClass(name))
private def getCompilerModule(name: String) = missingWrap(definitions.getModule(name))
- object InternalInfo {
+ trait LowPriorityInternalInfo {
implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None)
}
+ object InternalInfo extends LowPriorityInternalInfo { }
+
/** Todos...
* translate manifest type arguments into applied types
* customizable symbol filter (had to hardcode no-spec to reduce noise)
@@ -152,11 +188,13 @@ class Power(repl: ILoop, intp: IMain) {
def allMembers = tpe.members
def bts = info.baseTypeSeq.toList
def btsmap = bts map (x => (x, x.decls.toList)) toMap
- def pkgName = erasure.getPackage.getName
- def pkg = getCompilerModule(pkgName)
+ def pkgName = Option(erasure.getPackage) map (_.getName)
+ def pkg = pkgName map getCompilerModule getOrElse NoSymbol
def pkgmates = pkg.tpe.members
- def pkgslurp = new PackageSlurper(pkgName) slurp()
-
+ def pkgslurp = pkgName match {
+ case Some(name) => new PackageSlurper(name) slurp()
+ case _ => Set()
+ }
def ? = this
def whoHas(name: String) = bts filter (_.decls.toList exists (_.name.toString == name))
@@ -171,8 +209,24 @@ class Power(repl: ILoop, intp: IMain) {
}
}
- trait PCFormatter extends (Any => List[String]) {
- def apply(x: Any): List[String]
+ trait LowPriorityPrettifier {
+ implicit object AnyPrettifier extends Prettifier[Any] {
+ def prettify(x: Any): List[String] = x match {
+ case x: Name => List(x.decode)
+ case Tuple2(k, v) => List(prettify(k) ++ Seq("->") ++ prettify(v) mkString " ")
+ case xs: Traversable[_] => (xs.toList flatMap prettify).sorted.distinct
+ case x => List("" + x)
+ }
+ }
+ }
+ object Prettifier extends LowPriorityPrettifier {
+ def prettify[T](value: T): List[String] = default[T] prettify value
+ def default[T] = new Prettifier[T] {
+ def prettify(x: T): List[String] = AnyPrettifier prettify x
+ }
+ }
+ trait Prettifier[T] {
+ def prettify(x: T): List[String]
private var indentLevel = 0
private def spaces = " " * indentLevel
@@ -182,12 +236,13 @@ class Power(repl: ILoop, intp: IMain) {
finally indentLevel -= 1
}
- def show(x: Any): Unit = grep(x, _ => true)
- def grep(x: Any, p: String => Boolean): Unit =
- apply(x) filter p foreach (x => println(spaces + x))
+ def show(x: T): Unit = grep(x, _ => true)
+ def grep(x: T, p: String => Boolean): Unit =
+ prettify(x) filter p foreach (x => println(spaces + x))
}
- class MultiPrintingConvenience[T](coll: Traversable[T])(implicit fmt: PCFormatter) {
- import fmt._
+ class MultiPrintingConvenience[T: Prettifier](coll: Traversable[T]) {
+ val pretty = implicitly[Prettifier[T]]
+ import pretty._
def freqBy[U](p: T => U) = {
val map = coll.toList groupBy p
@@ -197,8 +252,8 @@ class Power(repl: ILoop, intp: IMain) {
val buf = new mutable.ListBuffer[String]
freqBy(p) foreach { case (k, vs) =>
- buf += "%d: %s".format(vs.size, k)
- vs flatMap fmt foreach (buf += " " + _)
+ buf += "%d: %s".format(vs.size, Prettifier.prettify(k))
+ vs flatMap prettify foreach (buf += " " + _)
}
buf.toList
}
@@ -215,16 +270,22 @@ class Power(repl: ILoop, intp: IMain) {
def #?[U](p: T => U) = this freqByFormatted p
}
- class PrintingConvenience[T](value: T)(implicit fmt: PCFormatter) {
- def > : Unit = >(_ => true)
+ class PrintingConvenience[T: Prettifier](value: T) {
+ val pretty = implicitly[Prettifier[T]]
+
+ def > { >(_ => true) }
def >(s: String): Unit = >(_ contains s)
def >(r: Regex): Unit = >(_ matches r.pattern.toString)
- def >(p: String => Boolean): Unit = fmt.grep(value, p)
+ def >(p: String => Boolean): Unit = pretty.grep(value, p)
}
protected trait Implicits1 {
- implicit def replPrinting[T](x: T)(implicit fmt: PCFormatter) = new PrintingConvenience[T](x)
+ // fallback
+ implicit def replPrinting[T](x: T)(implicit pretty: Prettifier[T] = Prettifier.default[T]) = new PrintingConvenience[T](x)
}
- object Implicits extends Implicits1 {
+ object Implicits extends Implicits1 with SharesGlobal[G] {
+ val global = Power.this.global
+ import global._
+
implicit lazy val powerNameOrdering: Ordering[Name] = Ordering[String] on (_.toString)
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
@@ -235,25 +296,23 @@ class Power(repl: ILoop, intp: IMain) {
else if (s1 isLess s2) -1
else 1
}
- implicit def replCollPrinting[T](xs: Traversable[T])(implicit fmt: PCFormatter) = new MultiPrintingConvenience[T](xs)
+ implicit def replCollPrinting[T: Prettifier](xs: Traversable[T]): MultiPrintingConvenience[T] = new MultiPrintingConvenience[T](xs)
implicit def replInternalInfo[T: Manifest](x: T): InternalInfo[T] = new InternalInfo[T](Some(x))
- implicit object ReplDefaultFormatter extends PCFormatter {
- def apply(x: Any): List[String] = x match {
- case Tuple2(k, v) => List(apply(k) ++ Seq("->") ++ apply(v) mkString " ")
- case xs: Traversable[_] => (xs.toList flatMap apply).sorted.distinct
- case x => List("" + x)
- }
+ implicit def replPrettifier[T] : Prettifier[T] = Prettifier.default[T]
+ implicit def vararsTypeApplication(sym: Symbol) = new {
+ def apply(targs: Type*) = typeRef(NoPrefix, sym, targs.toList)
}
+ def ?[T: Manifest] = InternalInfo[T]
}
- object phased extends Phased {
- val global: Power.this.global.type = Power.this.global
+ object phased extends Phased with SharesGlobal[G] {
+ val global: G = Power.this.global
}
- def context(code: String) = analyzer.rootContext(unit(code))
- def source(code: String) = new BatchSourceFile("<console>", code)
- def unit(code: String) = new CompilationUnit(source(code))
- def trees(code: String): List[Tree] = parse(code) getOrElse Nil
- def typeOf(id: String): Type = intp.typeOfExpression(id) getOrElse NoType
+ def context(code: String) = analyzer.rootContext(unit(code))
+ def source(code: String) = new BatchSourceFile("<console>", code)
+ def unit(code: String) = new CompilationUnit(source(code))
+ def trees(code: String) = parse(code) getOrElse Nil
+ def typeOf(id: String): Type = intp.typeOfExpression(id) getOrElse NoType
override def toString = """
|** Power mode status **