diff options
author | Paul Phillips <paulp@improving.org> | 2012-10-28 14:27:21 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-11-09 16:48:19 -0700 |
commit | 8da7e37674d771e177445cc0c56eab7b7016c2f2 (patch) | |
tree | 4c66a68fc6ad0ea19a4c4240c3d11f9c8d0be6b1 /src/compiler/scala/tools/nsc/interpreter/IMain.scala | |
parent | 31ed2e8da246da07a3318c34cdfae2ca02740524 (diff) | |
download | scala-8da7e37674d771e177445cc0c56eab7b7016c2f2.tar.gz scala-8da7e37674d771e177445cc0c56eab7b7016c2f2.tar.bz2 scala-8da7e37674d771e177445cc0c56eab7b7016c2f2.zip |
Cleanups to the previous repl commits.
Diffstat (limited to 'src/compiler/scala/tools/nsc/interpreter/IMain.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 120 |
1 files changed, 53 insertions, 67 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index c5f9553634..0ef27ac96a 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -177,6 +177,23 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends import global._ import definitions.{ ObjectClass, termMember, typeMember, dropNullaryMethod} + lazy val runtimeMirror = ru.runtimeMirror(classLoader) + + private def noFatal(body: => Symbol): Symbol = try body catch { case _: FatalError => NoSymbol } + + def getClassIfDefined(path: String) = ( + noFatal(runtimeMirror staticClass path) + orElse noFatal(rootMirror staticClass path) + ) + def getModuleIfDefined(path: String) = ( + noFatal(runtimeMirror staticModule path) + orElse noFatal(rootMirror staticModule path) + ) + def getPathIfDefined(path: String) = ( + if (path endsWith "$") getModuleIfDefined(path.init) + else getClassIfDefined(path) + ) + implicit class ReplTypeOps(tp: Type) { def orElse(other: => Type): Type = if (tp ne NoType) tp else other def andAlso(fn: Type => Type): Type = if (tp eq NoType) tp else fn(tp) @@ -307,9 +324,10 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def shift[T](op: => T): T = exitingFlatten(op) } - def originalPath(name: Name): String = typerOp path name - def originalPath(sym: Symbol): String = typerOp path sym - def flatPath(sym: Symbol): String = flatOp shift sym.javaClassName + def originalPath(name: String): String = originalPath(name: TermName) + def originalPath(name: Name): String = typerOp path name + def originalPath(sym: Symbol): String = typerOp path sym + def flatPath(sym: Symbol): String = flatOp shift sym.javaClassName // def translatePath(path: String) = symbolOfPath(path).fold(Option.empty[String])(flatPath) def translatePath(path: String) = { val sym = if (path endsWith "$") symbolOfTerm(path.init) else symbolOfIdent(path) @@ -341,13 +359,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends // Set the current Java "context" class loader to this interpreter's class loader def setContextClassLoader() = classLoader.setAsContext() - def allDefinedNames = exitingTyper(replScope.toList.map(_.name).sorted) - def pathToType(id: String): String = pathToName(newTypeName(id)) - def pathToTerm(id: String): String = pathToName(newTermName(id)) - def pathToName(name: Name): String = replScope lookup name match { - case NoSymbol => name.toString - case sym => exitingTyper(sym.fullName) - } + def allDefinedNames: List[Name] = exitingTyper(replScope.toList.map(_.name).sorted) + def unqualifiedIds: List[String] = allDefinedNames map (_.decode) sorted /** Most recent tree handled which wasn't wholly synthetic. */ private def mostRecentlyHandledTree: Option[Tree] = { @@ -401,9 +414,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } exitingTyper { req.imports foreach (sym => updateReplScope(sym, isDefined = false)) - req.defines foreach { sym => - updateReplScope(sym, isDefined = true) - } + req.defines foreach (sym => updateReplScope(sym, isDefined = true)) } } @@ -746,7 +757,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * following accessPath into the outer one. */ def resolvePathToSymbol(accessPath: String): Symbol = { - val readRoot = getRequiredModule(readPath) // the outermost wrapper + val readRoot = getModuleIfDefined(readPath) // the outermost wrapper (accessPath split '.').foldLeft(readRoot: Symbol) { case (sym, "") => sym case (sym, name) => exitingTyper(termMember(sym, name)) @@ -823,7 +834,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * append to objectName to access anything bound by request. */ val ComputedImports(importsPreamble, importsTrailer, accessPath) = - importsCode(referencedNames.toSet) + exitingTyper(importsCode(referencedNames.toSet)) /** The unmangled symbol name, but supplemented with line info. */ def disambiguated(name: Name): String = name + " (in " + lineRep + ")" @@ -835,7 +846,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** generate the source code for the object that computes this request */ private object ObjectSourceCode extends CodeAssembler[MemberHandler] { - def path = pathToTerm("$intp") + def path = originalPath("$intp") def envLines = { if (!isReplPower) Nil // power mode only for now // $intp is not bound; punt, but include the line. @@ -930,9 +941,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** String representations of same. */ lazy val typeOf = typeMap[String](tp => exitingTyper(tp.toString)) - // lazy val definedTypes: Map[Name, Type] = { - // typeNames map (x => x -> exitingTyper(resultSymbol.info.nonPrivateDecl(x).tpe)) toMap - // } lazy val definedSymbols = ( termNames.map(x => x -> applyToResultMember(x, x => x)) ++ typeNames.map(x => x -> compilerTypeOf(x).typeSymbolDirect) @@ -965,22 +973,18 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends private var mostRecentWarnings: List[(global.Position, String)] = Nil def lastWarnings = mostRecentWarnings - private lazy val globalImporter = global.mkImporter(ru) - private lazy val importer = ru.mkImporter(global) - - private implicit def importFromRu(sym: ru.Symbol): global.Symbol = - globalImporter importSymbol sym - - private implicit def importToRu(sym: global.Symbol): ru.Symbol = - importer importSymbol sym - - private def jmirror = ru.rootMirror match { - case j: ru.JavaMirror => j + private lazy val importToGlobal = global mkImporter ru + private lazy val importToRuntime = ru mkImporter global + private lazy val javaMirror = ru.rootMirror match { + case x: ru.JavaMirror => x case _ => null } + private implicit def importFromRu(sym: ru.Symbol): Symbol = importToGlobal importSymbol sym + private implicit def importToRu(sym: Symbol): ru.Symbol = importToRuntime importSymbol sym + def classOfTerm(id: String): Option[JClass] = symbolOfTerm(id) match { case NoSymbol => None - case sym => Some(jmirror runtimeClass (importer importSymbol sym).asClass) + case sym => Some(javaMirror runtimeClass importToRu(sym).asClass) } def typeOfTerm(id: String): Type = symbolOfTerm(id).tpe @@ -988,10 +992,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def valueOfTerm(id: String): Option[Any] = exitingTyper { def value() = { val sym0 = symbolOfTerm(id) - val sym = (importer importSymbol sym0).asTerm - val mirror = ru.runtimeMirror(classLoader) - val module = mirror.reflectModule(sym.owner.companionSymbol.asModule).instance - val module1 = mirror.reflect(module) + val sym = (importToRuntime importSymbol sym0).asTerm + val module = runtimeMirror.reflectModule(sym.owner.companionSymbol.asModule).instance + val module1 = runtimeMirror.reflect(module) val invoker = module1.reflectField(sym) invoker.get @@ -1000,29 +1003,20 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends try Some(value()) catch { case _: Exception => None } } - def symbolOfPath(path: String): Symbol = { - if (path contains '.') { - tryTwice { - if (path endsWith "$") rmirror.staticModule(path.init) - else rmirror.staticModule(path) orElse rmirror.staticClass(path) - } - } - else { - if (path endsWith "$") symbolOfTerm(path.init) - else symbolOfIdent(path) orElse rumirror.staticClass(path) - } - } - - def tryTwice(op: => Symbol): Symbol = { - exitingTyper(op) orElse exitingFlatten(op) - } + /** It's a bit of a shotgun approach, but for now we will gain in + * robustness. Try a symbol-producing operation at phase typer, and + * if that is NoSymbol, try again at phase flatten. I'll be able to + * lose this and run only from exitingTyper as soon as I figure out + * exactly where a flat name is sneaking in when calculating imports. + */ + def tryTwice(op: => Symbol): Symbol = exitingTyper(op) orElse exitingFlatten(op) - def signatureOf(sym: Symbol) = typerOp sig sym - // exitingTyper(sym.defString) - def symbolOfIdent(id: String): Symbol = symbolOfTerm(id) orElse symbolOfType(id) - def symbolOfType(id: String): Symbol = tryTwice(replScope lookup (id: TypeName)) - def symbolOfTerm(id: String): Symbol = tryTwice(replScope lookup (id: TermName)) - def symbolOfName(id: Name): Symbol = replScope lookup id + def signatureOf(sym: Symbol) = typerOp sig sym + def symbolOfPath(path: String): Symbol = exitingTyper(getPathIfDefined(path)) + def symbolOfIdent(id: String): Symbol = symbolOfTerm(id) orElse symbolOfType(id) + def symbolOfType(id: String): Symbol = tryTwice(replScope lookup (id: TypeName)) + def symbolOfTerm(id: String): Symbol = tryTwice(replScope lookup (id: TermName)) + def symbolOfName(id: Name): Symbol = replScope lookup id def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = { classOfTerm(id) flatMap { clazz => @@ -1068,8 +1062,8 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def typeOfExpression(expr: String, silent: Boolean = true): Type = exprTyper.typeOfExpression(expr, silent) - protected def onlyTerms(xs: List[Name]) = xs collect { case x: TermName => x } - protected def onlyTypes(xs: List[Name]) = xs collect { case x: TypeName => x } + protected def onlyTerms(xs: List[Name]): List[TermName] = xs collect { case x: TermName => x } + protected def onlyTypes(xs: List[Name]): List[TypeName] = xs collect { case x: TypeName => x } def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName def definedTypes = onlyTypes(allDefinedNames) @@ -1144,14 +1138,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def allImplicits = allHandlers filter (_.definesImplicit) flatMap (_.definedNames) def importHandlers = allHandlers collect { case x: ImportHandler => x } - def visibleTermNames: List[Name] = definedTerms ++ importedTerms distinct - - /** Another entry point for tab-completion, ids in scope */ - def unqualifiedIds = visibleTermNames map (_.toString) filterNot (_ contains "$") sorted - - /** Parse the ScalaSig to find type aliases */ - def aliasForType(path: String) = ByteCode.aliasForType(path) - def withoutUnwrapping(op: => Unit): Unit = { val saved = isettings.unwrapStrings isettings.unwrapStrings = false |