diff options
author | Paul Phillips <paulp@improving.org> | 2012-01-05 14:26:01 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-05 15:25:58 -0800 |
commit | 020053c3215579e8aeb871a4ad0078516994270d (patch) | |
tree | 447f518a7361a9a49993a22012b37a5c653e6284 /src/compiler/scala/tools/nsc/interpreter/IMain.scala | |
parent | 749b476beca481b48cad8ea3810865634a010686 (diff) | |
download | scala-020053c3215579e8aeb871a4ad0078516994270d.tar.gz scala-020053c3215579e8aeb871a4ad0078516994270d.tar.bz2 scala-020053c3215579e8aeb871a4ad0078516994270d.zip |
More consistent use of Names.
Several large helpings of tedium later, fewer strings are being
discarded like so much refuse. Some names now cache a String, but only
"named Names", so it's not very many and they pay for themselves pretty
quickly. Many fewer name-related implicit conversions now taking place.
A number of efficiency related measures.
Diffstat (limited to 'src/compiler/scala/tools/nsc/interpreter/IMain.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 79 |
1 files changed, 37 insertions, 42 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 8e4ff8aa37..0f0ab69e6d 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -188,7 +188,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends import global._ import definitions.{ ScalaPackage, JavaLangPackage, PredefModule, RootClass, - getClassIfDefined, getModuleIfDefined + getClassIfDefined, getModuleIfDefined, getRequiredModule, getRequiredClass } private implicit def privateTreeOps(t: Tree): List[Tree] = { @@ -196,6 +196,12 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def foreach[U](f: Tree => U): Unit = t foreach { x => f(x) ; () } }).toList } + + implicit def installReplTypeOps(tp: Type): ReplTypeOps = new ReplTypeOps(tp) + 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) + } // TODO: If we try to make naming a lazy val, we run into big time // scalac unhappiness with what look like cycles. It has not been easy to @@ -204,12 +210,13 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val global: imain.global.type = imain.global } with Naming { // make sure we don't overwrite their unwisely named res3 etc. - override def freshUserVarName(): String = { - val name = super.freshUserVarName() - if (definedNameMap contains name) freshUserVarName() + def freshUserTermName(): TermName = { + val name = newTermName(freshUserVarName()) + if (definedNameMap contains name) freshUserTermName() else name } - def isInternalVarName(name: Name): Boolean = isInternalVarName("" + name) + def isUserTermName(name: Name) = isUserVarName("" + name) + def isInternalTermName(name: Name) = isInternalVarName("" + name) } import naming._ @@ -359,7 +366,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends 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 && !isInternalTermName(x.name) => return Some(x.member) case _ => () } } @@ -501,7 +508,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends trees.last match { case _:Assign => // we don't want to include assignments case _:TermTree | _:Ident | _:Select => // ... but do want other unnamed terms. - val varName = if (synthetic) freshInternalVarName() else freshUserVarName() + val varName = if (synthetic) freshInternalVarName() else ("" + freshUserTermName()) val rewrittenLine = ( // In theory this would come out the same without the 1-specific test, but // it's a cushion against any more sneaky parse-tree position vs. code mismatches: @@ -643,7 +650,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def directBind(name: String, boundType: String, value: Any): IR.Result = { val result = bind(name, boundType, value) if (result == IR.Success) - directlyBoundNames += name + directlyBoundNames += newTermName(name) result } def directBind(p: NamedParam): IR.Result = directBind(p.name, p.tpe, p.value) @@ -651,7 +658,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def rebind(p: NamedParam): IR.Result = { val name = p.name - val oldType = typeOfTerm(name) getOrElse { return IR.Error } + val oldType = typeOfTerm(name) orElse { return IR.Error } val newType = p.tpe val tempName = freshInternalVarName() @@ -666,7 +673,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p)) def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value) def bind[T: Manifest](name: String, value: T): IR.Result = bind((name, value)) - def bindValue(x: Any): IR.Result = bindValue(freshUserVarName(), x) + def bindValue(x: Any): IR.Result = bindValue("" + freshUserTermName(), x) def bindValue(name: String, x: Any): IR.Result = bind(name, TypeStrings.fromValue(x), x) /** Reset this interpreter, forgetting all user-specified requests. */ @@ -789,7 +796,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends * following accessPath into the outer one. */ def resolvePathToSymbol(accessPath: String): Symbol = { - val readRoot = definitions.getModule(readPath) // the outermost wrapper + val readRoot = getRequiredModule(readPath) // the outermost wrapper (accessPath split '.').foldLeft(readRoot) { (sym, name) => if (name == "") sym else lineAfterTyper(sym.info member newTermName(name)) @@ -1039,16 +1046,6 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def requestHistoryForName(name: Name): List[Request] = prevRequests.toList.reverse filter (_.definedNames contains name) - def safeClass(name: String): Option[Symbol] = { - 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 } - } - def definitionForName(name: Name): Option[MemberHandler] = requestForName(name) flatMap { req => req.handlers find (_.definedNames contains name) @@ -1060,34 +1057,32 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends def classOfTerm(id: String): Option[JClass] = valueOfTerm(id) map (_.getClass) - def typeOfTerm(id: String): Option[Type] = newTermName(id) match { - case nme.ROOTPKG => Some(definitions.RootClass.tpe) - case name => requestForName(name) flatMap (_.compilerTypeOf get name) + def typeOfTerm(id: String): Type = newTermName(id) match { + case nme.ROOTPKG => definitions.RootClass.tpe + case name => requestForName(name) flatMap (_.compilerTypeOf get name) getOrElse NoType } def symbolOfTerm(id: String): Symbol = requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = { - for { - clazz <- classOfTerm(id) - tpe <- runtimeTypeOfTerm(id) - nonAnon <- clazz.supers find (!_.isScalaAnonymous) - } yield { - (nonAnon, tpe) + classOfTerm(id) flatMap { clazz => + clazz.supers find (!_.isScalaAnonymous) map { nonAnon => + (nonAnon, runtimeTypeOfTerm(id)) + } } } - def runtimeTypeOfTerm(id: String): Option[Type] = { - for { - tpe <- typeOfTerm(id) - clazz <- classOfTerm(id) - staticSym = tpe.typeSymbol - runtimeSym <- safeClass(clazz.getName) - if runtimeSym != staticSym - if runtimeSym isSubClass staticSym + def runtimeTypeOfTerm(id: String): Type = { + typeOfTerm(id) andAlso { tpe => + val clazz = classOfTerm(id) getOrElse { return NoType } + val staticSym = tpe.typeSymbol + val runtimeSym = getClassIfDefined(clazz.getName) + + if ((runtimeSym != NoSymbol) && (runtimeSym != staticSym) && (runtimeSym isSubClass staticSym)) + runtimeSym.info + else NoType } - yield runtimeSym.info } object replTokens extends { @@ -1099,16 +1094,16 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends } with ExprTyper { } def parse(line: String): Option[List[Tree]] = exprTyper.parse(line) - def typeOfExpression(expr: String, silent: Boolean = true): Option[Type] = { + def typeOfExpression(expr: String, silent: Boolean = true): Type = exprTyper.typeOfExpression(expr, silent) - } + def prettyPrint(code: String) = replTokens.prettyPrint(exprTyper tokens code) protected def onlyTerms(xs: List[Name]) = xs collect { case x: TermName => x } protected def onlyTypes(xs: List[Name]) = xs collect { case x: TypeName => x } - def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalVarName + def definedTerms = onlyTerms(allDefinedNames) filterNot isInternalTermName def definedTypes = onlyTypes(allDefinedNames) def definedSymbols = prevRequests.toSet flatMap ((x: Request) => x.definedSymbols.values) |