diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-24 22:06:58 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-24 22:06:58 +0000 |
commit | d521895e622acde2ceb11221c256de7413e90e5a (patch) | |
tree | b2353811c7bfb829490fdbdaeff49b197a8033a5 | |
parent | 2402240b4bb781bbd5b3e8bd8a3ac79bb68d1940 (diff) | |
download | scala-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.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 129 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/LoopCommands.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/Power.scala | 130 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/ReplVals.scala | 22 | ||||
-rw-r--r-- | test/files/run/repl-parens.check | 11 | ||||
-rw-r--r-- | test/files/run/repl-parens.scala | 1 | ||||
-rw-r--r-- | test/files/run/repl-paste.check | 22 | ||||
-rw-r--r-- | test/files/run/repl-paste.scala | 20 | ||||
-rw-r--r-- | test/files/run/repl-power.check | 9 |
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> |