summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-07-24 22:06:58 +0000
committerPaul Phillips <paulp@improving.org>2011-07-24 22:06:58 +0000
commitd521895e622acde2ceb11221c256de7413e90e5a (patch)
treeb2353811c7bfb829490fdbdaeff49b197a8033a5
parent2402240b4bb781bbd5b3e8bd8a3ac79bb68d1940 (diff)
downloadscala-d521895e622acde2ceb11221c256de7413e90e5a.tar.gz
scala-d521895e622acde2ceb11221c256de7413e90e5a.tar.bz2
scala-d521895e622acde2ceb11221c256de7413e90e5a.zip
Pulled some more repl code from trunk.
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala129
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala5
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala130
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ReplVals.scala22
-rw-r--r--test/files/run/repl-parens.check11
-rw-r--r--test/files/run/repl-parens.scala1
-rw-r--r--test/files/run/repl-paste.check22
-rw-r--r--test/files/run/repl-paste.scala20
-rw-r--r--test/files/run/repl-power.check9
10 files changed, 228 insertions, 130 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index b249d37006..8e7f73296f 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -43,11 +43,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
var settings: Settings = _
var intp: IMain = _
+ override def echoCommandMessage(msg: String): Unit =
+ intp.reporter.printMessage(msg)
+
def isAsync = !settings.Yreplsync.value
- lazy val power = {
- val g = intp.global
- Power[g.type](this, g)
- }
+ lazy val power = Power(this)
// TODO
// object opt extends AestheticSettings
@@ -622,6 +622,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
def enablePowerMode(isDuringInit: Boolean) = {
replProps.power setValue true
power.unleash()
+ intp.beSilentDuring(phaseCommand("typer"))
if (isDuringInit) asyncMessage(power.banner)
else echo(power.banner)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index ebc3146cc7..68911d65f0 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -154,10 +154,10 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
@deprecated("Use `global` for access to the compiler instance.", "2.9.0")
lazy val compiler: global.type = global
- import global._
+ import global.{ treeWrapper => _, _ }
import definitions.{ ScalaPackage, JavaLangPackage, PredefModule, RootClass }
- private def privateTreeOps(t: Tree): List[Tree] = {
+ private implicit def privateTreeOps(t: Tree): List[Tree] = {
(new Traversable[Tree] {
def foreach[U](f: Tree => U): Unit = t foreach { x => f(x) ; () }
}).toList
@@ -267,7 +267,10 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
definitions.
*/
private var _classLoader: AbstractFileClassLoader = null
- def resetClassLoader() = _classLoader = makeClassLoader()
+ def resetClassLoader() = {
+ repldbg("Setting new classloader: was " + _classLoader)
+ _classLoader = makeClassLoader()
+ }
def classLoader: AbstractFileClassLoader = {
if (_classLoader == null)
resetClassLoader()
@@ -287,8 +290,10 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
override protected def findAbstractFile(name: String): AbstractFile = {
super.findAbstractFile(name) match {
// deadlocks on startup if we try to translate names too early
- case null if isInitializeComplete => generatedName(name) map (x => super.findAbstractFile(x)) orNull
- case file => file
+ case null if isInitializeComplete =>
+ generatedName(name) map (x => super.findAbstractFile(x)) orNull
+ case file =>
+ file
}
}
}
@@ -301,8 +306,9 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
/** Given a simple repl-defined name, returns the real name of
* the class representing it, e.g. for "Bippy" it may return
- *
+ * {{{
* $line19.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$Bippy
+ * }}}
*/
def generatedName(simpleName: String): Option[String] = {
if (simpleName endsWith "$") optFlatName(simpleName.init) map (_ + "$")
@@ -324,7 +330,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
private def mostRecentlyHandledTree: Option[Tree] = {
prevRequests.reverse foreach { req =>
req.handlers.reverse foreach {
- case x: MemberDefHandler if x.definesValue && !isInternalVarName(x.name) => return Some(x.member)
+ case x: MemberDefHandler if x.definesValue && !isInternalVarName(x.name) => return Some(x.member)
case _ => ()
}
}
@@ -347,6 +353,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
repldbg("Redefining term '%s'\n %s -> %s".format(name, t1, t2))
}
}
+
def recordRequest(req: Request) {
if (req == null || referencedNameMap == null)
return
@@ -378,9 +385,10 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
}
}
- private[nsc] def replwarn(msg: => String): Unit =
+ private[nsc] def replwarn(msg: => String) {
if (!settings.nowarnings.value)
printMessage(msg)
+ }
def isParseable(line: String): Boolean = {
beSilentDuring {
@@ -425,6 +433,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
case idx => s take idx
}) mkString "\n"
}
+
private def safePos(t: Tree, alt: Int): Int =
try t.pos.startOrPoint
catch { case _: UnsupportedOperationException => alt }
@@ -448,7 +457,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
}
repltrace(
trees map { t =>
- privateTreeOps(t) map { t0 => t0.getClass + " at " + safePos(t0, -1) + "\n" }
+ t map { t0 => t0.getClass + " at " + safePos(t0, -1) + "\n" }
} mkString
)
// If the last tree is a bare expression, pinpoint where it begins using the
@@ -467,15 +476,20 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
else {
// The position of the last tree
val lastpos0 = earliestPosition(trees.last)
- // Oh boy, the parser throws away parens so "(2+2)" is mispositioned.
- // So until we can fix the parser we'll have to go trawling.
- val adjustment = ((content take lastpos0).reverse takeWhile { ch =>
- ch.isWhitespace || ch == '(' || ch == ')'
- }).length
+ // Oh boy, the parser throws away parens so "(2+2)" is mispositioned,
+ // with increasingly hard to decipher positions as we move on to "() => 5",
+ // (x: Int) => x + 1, and more. So I abandon attempts to finesse and just
+ // look for semicolons and newlines, which I'm sure is also buggy.
+ val (raw1, raw2) = content splitAt lastpos0
+ repldbg("[raw] " + raw1 + " <---> " + raw2)
+
+ val adjustment = (raw1.reverse takeWhile (ch => (ch != ';') && (ch != '\n'))).size
val lastpos = lastpos0 - adjustment
// the source code split at the laboriously determined position.
val (l1, l2) = content splitAt lastpos
+ repldbg("[adj] " + l1 + " <---> " + l2)
+
val prefix = if (l1.trim == "") "" else l1 + ";\n"
// Note to self: val source needs to have this precise structure so that
// error messages print the user-submitted part without the "val res0 = " part.
@@ -528,18 +542,14 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
def interpret(line: String, synthetic: Boolean): IR.Result = {
def loadAndRunReq(req: Request) = {
val (result, succeeded) = req.loadAndRun
+
/** To our displeasure, ConsoleReporter offers only printMessage,
* which tacks a newline on the end. Since that breaks all the
* output checking, we have to take one off to balance.
*/
- def show() = {
- if (result == "") ()
- else printMessage(result stripSuffix "\n")
- }
-
if (succeeded) {
- if (printResults)
- show()
+ if (printResults && result != "")
+ printMessage(result stripSuffix "\n")
else if (isReplDebug) // show quiet-mode activity
printMessage(result.trim.lines map ("[quiet] " + _) mkString "\n")
@@ -550,7 +560,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
}
else {
// don't truncate stack traces
- withoutTruncating(show())
+ withoutTruncating(printMessage(result))
IR.Error
}
}
@@ -583,11 +593,19 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
|}
""".stripMargin.format(bindRep.evalName, boundType, boundType)
)
- bindRep.callOpt("set", value) match {
- case Some(_) => interpret("val %s = %s.value".format(name, bindRep.evalPath))
- case _ => repldbg("Set failed in bind(%s, %s, %s)".format(name, boundType, value)) ; IR.Error
+ bindRep.callEither("set", value) match {
+ case Left(ex) =>
+ repldbg("Set failed in bind(%s, %s, %s)".format(name, boundType, value))
+ repldbg(util.stackTraceString(ex))
+ IR.Error
+
+ case Right(_) =>
+ val line = "val %s = %s.value".format(name, bindRep.evalPath)
+ repldbg("Interpreting: " + line)
+ interpret(line)
}
}
+
def rebind(p: NamedParam): IR.Result = {
val name = p.name
val oldType = typeOfTerm(name) getOrElse { return IR.Error }
@@ -683,15 +701,30 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
def call(name: String, args: Any*): AnyRef =
evalMethod(name).invoke(evalClass, args.map(_.asInstanceOf[AnyRef]): _*)
+ def callEither(name: String, args: Any*): Either[Throwable, AnyRef] =
+ try Right(call(name, args: _*))
+ catch { case ex: Throwable => Left(ex) }
+
def callOpt(name: String, args: Any*): Option[AnyRef] =
try Some(call(name, args: _*))
- catch { case ex: Exception => bindError(ex) ; None }
+ catch { case ex: Throwable => bindError(ex) ; None }
+
+ class EvalException(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { }
- private def load(s: String): Class[_] =
- (classLoader tryToInitializeClass s) getOrElse sys.error("Failed to load expected class: '" + s + "'")
+ private def evalError(path: String, ex: Throwable) =
+ throw new EvalException("Failed to load '" + path + "': " + ex.getMessage, ex)
+
+ private def load(path: String): Class[_] = {
+ try Class.forName(path, true, classLoader)
+ catch { case ex => evalError(path, unwrap(ex)) }
+ }
+ var evalCaught: Option[Throwable] = None
lazy val evalClass = load(evalPath)
- lazy val evalValue = callOpt(evalName)
+ lazy val evalValue = callEither(evalName) match {
+ case Left(ex) => evalCaught = Some(ex) ; None
+ case Right(result) => Some(result)
+ }
def compile(source: String): Boolean = compileAndSaveRun("<console>", source)
def lineAfterTyper[T](op: => T): T = {
@@ -726,7 +759,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
/** One line of code submitted by the user for interpretation */
// private
class Request(val line: String, val trees: List[Tree]) {
- val lineRep = new ReadEvalPrint()
+ val lineRep = new ReadEvalPrint()
import lineRep.lineAfterTyper
private var _originalLine: String = null
@@ -922,6 +955,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
try Some(definitions.getClass(newTypeName(name)))
catch { case _: MissingRequirementError => None }
}
+
def safeModule(name: String): Option[Symbol] = {
try Some(definitions.getModule(newTermName(name)))
catch { case _: MissingRequirementError => None }
@@ -942,6 +976,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
case nme.ROOTPKG => Some(definitions.RootClass.tpe)
case name => requestForName(name) flatMap (_.compilerTypeOf get name)
}
+
def symbolOfTerm(id: String): Symbol =
requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol
@@ -981,6 +1016,39 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
def definedTypes = onlyTypes(allDefinedNames)
def definedSymbols = prevRequests.toSet flatMap ((x: Request) => x.definedSymbols.values)
+ private def findName(name: Name) = definedSymbols find (_.name == name)
+
+ private def missingOpt(op: => Symbol): Option[Symbol] =
+ try Some(op)
+ catch { case _: MissingRequirementError => None }
+ private def missingWrap(op: => Symbol): Symbol =
+ try op
+ catch { case _: MissingRequirementError => NoSymbol }
+
+ def optCompilerClass(name: String) = missingOpt(definitions.getClass(name))
+ def optCompilerModule(name: String) = missingOpt(definitions.getModule(name))
+ def getCompilerClass(name: String) = missingWrap(definitions.getClass(name))
+ def getCompilerModule(name: String) = missingWrap(definitions.getModule(name))
+
+ /** Translate a repl-defined identifier into a Symbol.
+ */
+ def apply(name: String): Symbol = {
+ val tpname = newTypeName(name)
+ (
+ findName(tpname)
+ orElse findName(tpname.companionName)
+ orElse optCompilerClass(name)
+ orElse optCompilerModule(name)
+ getOrElse NoSymbol
+ )
+ }
+ def types(name: String): Symbol = {
+ findName(newTypeName(name)) getOrElse getCompilerClass(name)
+ }
+ def terms(name: String): Symbol = {
+ findName(newTermName(name)) getOrElse getCompilerModule(name)
+ }
+
/** the previous requests this interpreter has processed */
private lazy val prevRequests = mutable.ListBuffer[Request]()
private lazy val referencedNameMap = mutable.Map[Name, Request]()
@@ -1023,6 +1091,7 @@ class IMain(val settings: Settings, protected val out: JPrintWriter) extends Imp
parse(code) foreach (ts => ts foreach (t => withoutUnwrapping(repldbg(asCompactString(t)))))
}
}
+
// debugging
def debugging[T](msg: String)(res: T) = {
repldbg(msg + " " + res)
diff --git a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
index 188f891054..9469baa4e2 100644
--- a/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala
@@ -29,6 +29,9 @@ object ProcessResult {
trait LoopCommands {
protected def out: JPrintWriter
+ // So outputs can be suppressed.
+ def echoCommandMessage(msg: String): Unit = out println msg
+
// a single interpreter command
abstract class LoopCommand(val name: String, val help: String) extends (String => Result) {
private var _longHelp: String = null
@@ -95,7 +98,7 @@ trait LoopCommands {
// to print something to the console, so we accomodate Unit and String returns.
implicit def resultFromUnit(x: Unit): Result = default
implicit def resultFromString(msg: String): Result = {
- out println msg
+ echoCommandMessage(msg)
default
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index d907d5024f..95b42ebf69 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -6,7 +6,7 @@
package scala.tools.nsc
package interpreter
-import scala.reflect.NameTransformer
+import scala.reflect.{ NameTransformer, AnyValManifest }
import scala.collection.{ mutable, immutable }
import scala.util.matching.Regex
import scala.tools.nsc.util.{ BatchSourceFile }
@@ -15,8 +15,9 @@ import scala.io.Codec
import java.net.{ URL, MalformedURLException }
import io.{ Path }
-trait SharesGlobal[G <: Global] {
- val global: G
+trait SharesGlobal {
+ type GlobalType <: Global
+ val global: GlobalType
// This business gets really old:
//
@@ -42,26 +43,26 @@ trait SharesGlobal[G <: Global] {
}
object Power {
- def apply[G <: Global](repl: ILoop, g: G) =
- new { final val global: G = g } with Power[G](repl, repl.intp)
-
- def apply(intp: IMain) =
- new { final val global = intp.global } with Power[Global](null, intp)
+ def apply(intp: IMain): Power = apply(null, intp)
+ def apply(repl: ILoop): Power = apply(repl, repl.intp)
+ def apply(repl: ILoop, intp: IMain): Power =
+ new Power(repl, intp) {
+ type GlobalType = intp.global.type
+ final val global: intp.global.type = intp.global
+ }
}
/** A class for methods to be injected into the intp in power mode.
*/
-abstract class Power[G <: Global](
+abstract class Power(
val repl: ILoop,
val intp: IMain
-) extends SharesGlobal[G] {
- import intp.{ beQuietDuring, interpret, parse }
- import global.{
- opt, definitions, analyzer,
- stringToTermName, typeRef,
- CompilationUnit,
- NoSymbol, NoPrefix, NoType
+) extends SharesGlobal {
+ import intp.{
+ beQuietDuring, typeOfExpression, getCompilerClass, getCompilerModule,
+ interpret, parse
}
+ import global._
abstract class SymSlurper {
def isKeep(sym: Symbol): Boolean
@@ -129,48 +130,38 @@ abstract class Power[G <: Global](
private def customInit = replProps.powerInitCode.option flatMap (f => io.File(f).safeSlurp())
def banner = customBanner getOrElse """
- |** Power User mode enabled - BEEP BOOP WHIR **
+ |** Power User mode enabled - BEEP BOOP SPIZ **
+ |** :phase has been set to 'typer'. **
|** scala.tools.nsc._ has been imported **
|** global._ and definitions._ also imported **
- |** New vals! Try repl, intp, global, power **
- |** New cmds! :help to discover them **
- |** New defs! Type power.<tab> to reveal **
+ |** Try :help, vals.<tab>, power.<tab> **
""".stripMargin.trim
private def initImports = List(
"scala.tools.nsc._",
"scala.collection.JavaConverters._",
"global.{ error => _, _ }",
+ "definitions.{ getClass => _, _ }",
"power.Implicits._",
"power.rutil._"
)
- def init = customInit getOrElse "import " + initImports.mkString(", ")
+
+ def init = customInit match {
+ case Some(x) => x
+ case _ => initImports.mkString("import ", ", ", "")
+ }
/** Starts up power mode and runs whatever is in init.
*/
def unleash(): Unit = beQuietDuring {
- val r = new ReplVals(repl)
- intp.bind[ILoop]("repl", repl)
- intp.bind[ReplVals]("$r", r)
-
- intp.bind("intp", r.intp)
- intp.bind("global", r.global)
- intp.bind("power", r.power)
- intp.bind("phased", r.phased)
- intp.bind("isettings", r.isettings)
- intp.bind("completion", r.completion)
- intp.bind("history", r.history)
-
- init split '\n' foreach interpret
+ // First we create the ReplVals instance and bind it to $r
+ intp.bind("$r", new ReplVals(repl))
+ // Then we import everything from $r.
+ intp interpret ("import " + intp.pathToTerm("$r") + "._")
+ // And whatever else there is to do.
+ init.lines foreach (intp interpret _)
}
- private def missingWrap(op: => Symbol): Symbol =
- try op
- catch { case _: MissingRequirementError => NoSymbol }
-
- private def getCompilerClass(name: String) = missingWrap(definitions.getClass(name))
- private def getCompilerModule(name: String) = missingWrap(definitions.getModule(name))
-
trait LowPriorityInternalInfo {
implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None)
}
@@ -181,14 +172,41 @@ abstract class Power[G <: Global](
* customizable symbol filter (had to hardcode no-spec to reduce noise)
*/
class InternalInfo[T: Manifest](value: Option[T] = None) {
- def companion = symbol.companionSymbol
- def info = symbol.info
- def module = symbol.moduleClass
- def owner = symbol.owner
- def owners = symbol.ownerChain drop 1
- def symDef = symbol.defString
- def symName = symbol.name
- def tpe = symbol.tpe
+ // Decided it was unwise to have implicit conversions via commonly
+ // used type/symbol methods, because it's too easy to e.g. call
+ // "x.tpe" where x is a Type, and rather than failing you get the
+ // Type representing Types#Type (or Manifest, or whatever.)
+ private def tpe = tpe_
+ private def symbol = symbol_
+ private def name = name_
+
+ // Would love to have stuff like existential types working,
+ // but very unfortunately those manifests just stuff the relevant
+ // information into the toString method. Boo.
+ private def manifestToType(m: Manifest[_]): Type = m match {
+ case x: AnyValManifest[_] =>
+ getCompilerClass("scala." + x).tpe
+ case _ =>
+ val name = m.erasure.getName
+ if (name endsWith "$") getCompilerModule(name dropRight 1).tpe
+ else {
+ val sym = getCompilerClass(name)
+ val args = m.typeArguments
+
+ if (args.isEmpty) sym.tpe
+ else typeRef(NoPrefix, sym, args map manifestToType)
+ }
+ }
+
+ def symbol_ : Symbol = getCompilerClass(erasure.getName)
+ def tpe_ : Type = manifestToType(man)
+ def name_ : Name = symbol.name
+ def companion = symbol.companionSymbol
+ def info = symbol.info
+ def module = symbol.moduleClass
+ def owner = symbol.owner
+ def owners = symbol.ownerChain drop 1
+ def defn = symbol.defString
def declares = members filter (_.owner == symbol)
def inherits = members filterNot (_.owner == symbol)
@@ -197,8 +215,8 @@ abstract class Power[G <: Global](
def overrides = declares filter (_.isOverride)
def inPackage = owners find (x => x.isPackageClass || x.isPackage) getOrElse definitions.RootPackage
- def erasure = manifest[T].erasure
- def symbol = getCompilerClass(erasure.getName)
+ def man = manifest[T]
+ def erasure = man.erasure
def members = tpe.members filterNot (_.name.toString contains "$mc")
def allMembers = tpe.members
def bts = info.baseTypeSeq.toList
@@ -331,10 +349,10 @@ abstract class Power[G <: Global](
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
+ implicit def replInternalInfo[T: Manifest](x: T): InternalInfo[T] = new InternalInfo[T](Some(x))
implicit def replEnhancedStrings(s: String): RichReplString = new RichReplString(s)
implicit def replMultiPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrettifierClass[T] =
new MultiPrettifierClass[T](xs.toSeq)
- implicit def replInternalInfo[T: Manifest](x: T): InternalInfo[T] = new InternalInfo[T](Some(x))
implicit def replPrettifier[T] : Prettifier[T] = Prettifier.default[T]
implicit def replTypeApplication(sym: Symbol): RichSymbol = new RichSymbol(sym)
implicit def replInputStream(in: InputStream)(implicit codec: Codec) = new RichInputStream(in)
@@ -343,6 +361,8 @@ abstract class Power[G <: Global](
object Implicits extends Implicits2 { }
trait ReplUtilities {
+ def module[T: Manifest] = getCompilerModule(manifest[T].erasure.getName stripSuffix "$")
+ def clazz[T: Manifest] = getCompilerClass(manifest[T].erasure.getName)
def info[T: Manifest] = InternalInfo[T]
def ?[T: Manifest] = InternalInfo[T]
def url(s: String) = {
@@ -367,8 +387,10 @@ abstract class Power[G <: Global](
}
lazy val rutil: ReplUtilities = new ReplUtilities { }
- lazy val phased: Phased = new Phased with SharesGlobal[G] {
- val global: G = Power.this.global
+
+ lazy val phased: Phased = new Phased with SharesGlobal {
+ type GlobalType = Power.this.global.type
+ final val global: Power.this.global.type = Power.this.global
}
def context(code: String) = analyzer.rootContext(unit(code))
diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
index 2c5f5474af..2f2489b242 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ReplVals.scala
@@ -6,15 +6,15 @@
package scala.tools.nsc
package interpreter
-import java.lang.reflect.{ Method => JMethod }
-
-class ReplVals(final val r: ILoop) {
- final val intp = r.intp
- final val global = r.power.global
- final val power = r.power
- final val phased = r.power.phased
- final val isettings = r.intp.isettings
- final val completion = r.in.completion
- final val history = r.in.history
- final val rutil = r.power.rutil
+final class ReplVals(r: ILoop) {
+ lazy val repl = r
+ lazy val intp = r.intp
+ lazy val power = r.power
+ lazy val reader = r.in
+ lazy val vals = this
+ lazy val global = intp.global
+ lazy val isettings = intp.isettings
+ lazy val completion = reader.completion
+ lazy val history = reader.history
+ lazy val phased = power.phased
}
diff --git a/test/files/run/repl-parens.check b/test/files/run/repl-parens.check
index f41c2e74bd..2f56e5ddd4 100644
--- a/test/files/run/repl-parens.check
+++ b/test/files/run/repl-parens.check
@@ -36,16 +36,19 @@ scala>
scala> 55 ; ((2 + 2)) ; (1, 2, 3)
res10: (Int, Int, Int) = (1,2,3)
+scala> 55 ; (x: Int) => x + 1 ; () => ((5))
+res11: () => Int = <function0>
+
scala>
scala> () => 5
-res11: () => Int = <function0>
+res12: () => Int = <function0>
scala> 55 ; () => 5
-res12: () => Int = <function0>
+res13: () => Int = <function0>
scala> () => { class X ; new X }
-res13: () => java.lang.Object with ScalaObject = <function0>
+res14: () => java.lang.Object with ScalaObject = <function0>
scala>
@@ -53,6 +56,6 @@ scala> def foo(x: Int)(y: Int)(z: Int) = x+y+z
foo: (x: Int)(y: Int)(z: Int)Int
scala> foo(5)(10)(15)+foo(5)(10)(15)
-res14: Int = 60
+res15: Int = 60
scala>
diff --git a/test/files/run/repl-parens.scala b/test/files/run/repl-parens.scala
index 081db3606a..1baa9c37a5 100644
--- a/test/files/run/repl-parens.scala
+++ b/test/files/run/repl-parens.scala
@@ -14,6 +14,7 @@ object Test extends ReplTest {
((((2 + 2)), ((2 + 2)), 2).productIterator ++ Iterator(3) mkString)
55 ; ((2 + 2)) ; (1, 2, 3)
+55 ; (x: Int) => x + 1 ; () => ((5))
() => 5
55 ; () => 5
diff --git a/test/files/run/repl-paste.check b/test/files/run/repl-paste.check
index 50589433cd..d3e171fbfb 100644
--- a/test/files/run/repl-paste.check
+++ b/test/files/run/repl-paste.check
@@ -5,17 +5,17 @@ scala> :paste
// Entering paste mode (ctrl-D to finish)
- class Dingus
- {
- private val x = 5
- def y = Dingus.x * 2
- }
- object Dingus
- {
- private val x = 55
- }
-
- val x = (new Dingus).y
+class Dingus
+{
+ private val x = 5
+ def y = Dingus.x * 2
+}
+object Dingus
+{
+ private val x = 55
+}
+
+val x = (new Dingus).y
// Exiting paste mode, now interpreting.
diff --git a/test/files/run/repl-paste.scala b/test/files/run/repl-paste.scala
index e2ebab1e45..5495505353 100644
--- a/test/files/run/repl-paste.scala
+++ b/test/files/run/repl-paste.scala
@@ -3,17 +3,17 @@ import scala.tools.partest.ReplTest
object Test extends ReplTest {
def code = ":paste\n" + (
"""
- class Dingus
- {
- private val x = 5
- def y = Dingus.x * 2
- }
- object Dingus
- {
- private val x = 55
- }
+class Dingus
+{
+ private val x = 5
+ def y = Dingus.x * 2
+}
+object Dingus
+{
+ private val x = 55
+}
- val x = (new Dingus).y
+val x = (new Dingus).y
"""
)
} \ No newline at end of file
diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check
index 9561c04eca..38e7532133 100644
--- a/test/files/run/repl-power.check
+++ b/test/files/run/repl-power.check
@@ -2,16 +2,15 @@ Type in expressions to have them evaluated.
Type :help for more information.
scala> :power
-** Power User mode enabled - BEEP BOOP WHIR **
+** Power User mode enabled - BEEP BOOP SPIZ **
+** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._ and definitions._ also imported **
-** New vals! Try repl, intp, global, power **
-** New cmds! :help to discover them **
-** New defs! Type power.<tab> to reveal **
+** Try :help, vals.<tab>, power.<tab> **
scala> // guarding against "error: reference to global is ambiguous"
scala> global.emptyValDef // "it is imported twice in the same scope by ..."
-res0: global.emptyValDef.type = private val _ = _
+res0: $r.global.emptyValDef.type = private val _ = _
scala>