diff options
author | Paul Phillips <paulp@improving.org> | 2011-12-16 14:20:36 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-01-30 10:24:58 -0800 |
commit | a4d6992280b179295142f2f7c7d138ec7f08039b (patch) | |
tree | 0cfd4baa12a4128c9c473cde542d3f4c09d54568 | |
parent | 5e9dd4a05c25f463f29d0fbc2f1bec194bf7700b (diff) | |
download | scala-a4d6992280b179295142f2f7c7d138ec7f08039b.tar.gz scala-a4d6992280b179295142f2f7c7d138ec7f08039b.tar.bz2 scala-a4d6992280b179295142f2f7c7d138ec7f08039b.zip |
A couple power mod conveniences.
And disambiguations. And renamed all kinds of methods to something
less inscrutable. Moved all the instance-to-compiler-structure implicit
behind a wrapper to avoid accidental conversions. The wrapper has
a single method, ?, which you can experience like so:
// Sorry tab completion doesn't yet figure out implicit conversions
scala> val x = Map(1 -> 2).?
x: $r.power.InternalInfo[scala.collection.immutable.Map[Int,Int]] = Map(1 -> 2) (Map)
scala> x.
asInstanceOf baseTypeSeq baseTypeSeqMap baseTypeWhichDefines companion
decls declsOriginal declsOverride erasure fullManifest
glb info isInstanceOf lub memberMethods
memberTypes members membersDeclared membersInherited membersUnabridged
moduleClass name owner owners pkg
pkgClass pkgClassSymbols pkgClasses pkgMembers pkgName
pkgSymbols shortClass signature symbol toString
tpe
// This uses an implicit to install sigs (and another for '>' which is
// the generic printing function) but transparency, one step at a time.
scala> Map(1 -> 2).?.membersDeclared.sigs >
def $init$(): Unit
override def empty: scala.collection.immutable.Map[A,B]
override def toMap[T,U](implicit ev: <:<[(A, B),(T, U)]): scala.collection.immutable.Map[T,U]
override def seq: scala.collection.immutable.Map[A,B]
def withDefault[B1 >: B](d: A => B1): scala.collection.immutable.Map[A,B1]
def withDefaultValue[B1 >: B](d: B1): scala.collection.immutable.Map[A,B1]
override def updated[B1 >: B](key: A,value: B1): scala.collection.immutable.Map[A,B1]
def +[B1 >: B](kv: (A, B1)): scala.collection.immutable.Map[A,B1]
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/IMain.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/Power.scala | 144 |
2 files changed, 91 insertions, 56 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 8cdd2334ab..567d6c2f78 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -1125,6 +1125,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends val termname = newTypeName(name) findName(termname) getOrElse getModuleIfDefined(termname) } + def types[T: ClassManifest] : Symbol = types(classManifest[T].erasure.getName) + def terms[T: ClassManifest] : Symbol = terms(classManifest[T].erasure.getName) + def apply[T: ClassManifest] : Symbol = apply(classManifest[T].erasure.getName) /** the previous requests this interpreter has processed */ private lazy val prevRequests = mutable.ListBuffer[Request]() diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index b4a9b9b0e3..2ec41506ab 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -20,7 +20,7 @@ import io.{ Path } class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: ReplValsImpl) { import intp.{ beQuietDuring, typeOfExpression, interpret, parse } import intp.global._ - import definitions.{ manifestToType, getClassIfDefined, getModuleIfDefined } + import definitions.{ manifestToType, manifestToSymbol, getClassIfDefined, getModuleIfDefined } abstract class SymSlurper { def isKeep(sym: Symbol): Boolean @@ -65,10 +65,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl } } - class PackageSlurper(pkgName: String) extends SymSlurper { - val pkgSymbol = getModuleIfDefined(pkgName) - val modClass = pkgSymbol.moduleClass - + class PackageSlurper(packageClass: Symbol) extends SymSlurper { /** Looking for dwindling returns */ def droppedEnough() = unseenHistory.size >= 4 && { unseenHistory takeRight 4 sliding 2 forall { it => @@ -79,9 +76,16 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl def isRecur(sym: Symbol) = true def isIgnore(sym: Symbol) = sym.isAnonOrRefinementClass || (sym.name.toString contains "$mc") - def isKeep(sym: Symbol) = sym.hasTransOwner(modClass) + def isKeep(sym: Symbol) = sym.hasTransOwner(packageClass) def isFinished() = droppedEnough() - def slurp() = apply(modClass) + def slurp() = { + if (packageClass.isPackageClass) + apply(packageClass) + else { + repldbg("Not a package class! " + packageClass) + Set() + } + } } private def customBanner = replProps.powerBanner.option flatMap (f => io.File(f).safeSlurp()) @@ -124,7 +128,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl def to_str(m: Symbol) = "%12s %s".format( m.decodedName, "" + elimRefinement(m.accessedOrSelf.tpe) stripPrefix "scala.tools.nsc.") - ( rutil.info[ReplValsImpl].declares + ( rutil.info[ReplValsImpl].membersDeclared filter (m => m.isPublic && !m.hasModuleFlag && !m.isConstructor) sortBy (_.decodedName) map to_str @@ -136,59 +140,78 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl implicit def apply[T: Manifest] : InternalInfo[T] = new InternalInfo[T](None) } object InternalInfo extends LowPriorityInternalInfo { } + + /** Now dealing with the problem of acidentally calling a method on Type + * when you're holding a Symbol and seeing the Symbol converted to the + * type of Symbol rather than the type of the thing represented by the + * symbol, by only implicitly installing one method, "?", and the rest + * of the conveniences exist on that wrapper. + */ + trait LowPriorityInternalInfoWrapper { + implicit def apply[T: Manifest] : InternalInfoWrapper[T] = new InternalInfoWrapper[T](None) + } + object InternalInfoWrapper extends LowPriorityInternalInfoWrapper { + + } + class InternalInfoWrapper[T: Manifest](value: Option[T] = None) { + def ? : InternalInfo[T] = new InternalInfo[T](value) + } /** Todos... * translate manifest type arguments into applied types * customizable symbol filter (had to hardcode no-spec to reduce noise) */ class InternalInfo[T: Manifest](value: Option[T] = None) { - // 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_ - - def symbol_ : Symbol = getClassIfDefined(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 decls = symbol.info.decls - - def declares = decls.toList - def inherits = members filterNot (declares contains _) - def types = members filter (_.name.isTypeName) - def methods = members filter (_.isMethod) - def overrides = declares filter (_.isOverride) - def inPackage = owners find (x => x.isPackageClass || x.isPackage) getOrElse definitions.RootPackage - - 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 - def btsmap = bts map (x => (x, x.decls.toList)) toMap - def pkgName = Option(erasure.getPackage) map (_.getName) - def pkg = pkgName map getModuleIfDefined getOrElse NoSymbol - def pkgmates = pkg.tpe.members - def pkgslurp = pkgName match { - case Some(name) => new PackageSlurper(name) slurp() - case _ => Set() - } - def ? = this - - def whoHas(name: String) = bts filter (_.decls exists (_.name.toString == name)) - def <:<[U: Manifest](other: U) = tpe <:< InternalInfo[U].tpe - def lub[U: Manifest](other: U) = intp.global.lub(List(tpe, InternalInfo[U].tpe)) - def glb[U: Manifest](other: U) = intp.global.glb(List(tpe, InternalInfo[U].tpe)) + private def newInfo[U: Manifest](value: U): InternalInfo[U] = new InternalInfo[U](Some(value)) + private def isSpecialized(s: Symbol) = s.name.toString contains "$mc" + private def isImplClass(s: Symbol) = s.name.toString endsWith "$class" + + /** Standard noise reduction filter. */ + def excludeMember(s: Symbol) = ( + isSpecialized(s) + || isImplClass(s) + || s.isAnonOrRefinementClass + || s.isAnonymousFunction + ) + def symbol = manifestToSymbol(fullManifest) + def tpe = manifestToType(fullManifest) + def name = symbol.name + def companion = symbol.companionSymbol + def info = symbol.info + def moduleClass = symbol.moduleClass + def owner = symbol.owner + def owners = symbol.ownerChain drop 1 + def signature = symbol.defString + + def decls = info.decls + def declsOverride = membersDeclared filter (_.isOverride) + def declsOriginal = membersDeclared filterNot (_.isOverride) + + def members = membersUnabridged filterNot excludeMember + def membersUnabridged = tpe.members + def membersDeclared = members filterNot excludeMember + def membersInherited = members filterNot (membersDeclared contains _) + def memberTypes = members filter (_.name.isTypeName) + def memberMethods = members filter (_.isMethod) + + def pkg = symbol.enclosingPackage + def pkgName = pkg.fullName + def pkgClass = symbol.enclosingPackageClass + def pkgMembers = pkg.info.members filterNot excludeMember + def pkgClasses = pkgMembers filter (s => s.isClass && s.isDefinedInPackage) + def pkgSymbols = new PackageSlurper(pkgClass).slurp() filterNot excludeMember + + def fullManifest = manifest[T] + def erasure = fullManifest.erasure + def shortClass = erasure.getName split "[$.]" last + def baseTypeSeq = tpe.baseTypeSeq.toList + def baseTypeSeqMap = baseTypeSeq map (x => (x, x.decls.toList)) toMap + + def baseTypeWhichDefines(name: String) = baseTypeSeq filter (_.decls exists (_.name.toString == name)) + def <:<[U: Manifest](other: U) = tpe <:< newInfo(other).tpe + def lub[U: Manifest](other: U) = intp.global.lub(List(tpe, newInfo(other).tpe)) + def glb[U: Manifest](other: U) = intp.global.glb(List(tpe, newInfo(other).tpe)) - def shortClass = erasure.getName split "[$.]" last override def toString = value match { case Some(x) => "%s (%s)".format(x, shortClass) case _ => erasure.getName @@ -288,11 +311,17 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl def slurp(): String = io.Streamable.slurp(url) def pp() { intp prettyPrint slurp() } } - + class RichSymbolList(syms: List[Symbol]) { + def sigs = syms map (_.defString) + def infos = syms map (_.info) + } + trait Implicits1 { // fallback implicit def replPrinting[T](x: T)(implicit pretty: Prettifier[T] = Prettifier.default[T]) = new SinglePrettifierClass[T](x) + + implicit def liftToTypeName(s: String): TypeName = newTypeName(s) } trait Implicits2 extends Implicits1 { class RichSymbol(sym: Symbol) { @@ -309,7 +338,7 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl 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 replInternalInfo[T: Manifest](x: T): InternalInfoWrapper[T] = new InternalInfoWrapper[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) @@ -318,6 +347,9 @@ class Power[ReplValsImpl <: ReplVals : Manifest](val intp: IMain, replVals: Repl implicit def replInputStream(in: InputStream)(implicit codec: Codec) = new RichInputStream(in) implicit def replEnhancedURLs(url: URL)(implicit codec: Codec): RichReplURL = new RichReplURL(url)(codec) + + implicit def liftToTermName(s: String): TermName = newTermName(s) + implicit def replListOfSymbols(xs: List[Symbol]) = new RichSymbolList(xs) } trait ReplUtilities { |