summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-11-08 14:25:01 +0000
committerPaul Phillips <paulp@improving.org>2010-11-08 14:25:01 +0000
commit948f4228c1a279f49093dbc7dc042eea749c463d (patch)
tree851295427a1ce42d810005a2c945a76c345d7046 /src
parent7f8ccd778d34016e6fb63b218524783da3916573 (diff)
downloadscala-948f4228c1a279f49093dbc7dc042eea749c463d.tar.gz
scala-948f4228c1a279f49093dbc7dc042eea749c463d.tar.bz2
scala-948f4228c1a279f49093dbc7dc042eea749c463d.zip
A bit of -Xshow-class / -Xshow-object which did...
A bit of -Xshow-class / -Xshow-object which didn't quite make the Global patch. Now type selections should do the right thing, e.g. scalac -Xshow-class Global#Run src/compiler/scala/tools/nsc/Global.scala will show you interesting things about Run. Or see the test case for even more thrills. No review.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala60
1 files changed, 45 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 60b43a3d17..f3d6b9f41d 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -973,25 +973,55 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable
atPhase(phase.next) { currentRun.units foreach treePrinter.print }
}
- def showDef(name: Name) {
- val segments = name.toString split '.'
- val container = segments.init.foldLeft(definitions.RootClass: Symbol)(_.info member _)
- val target = if (name.isTypeName) newTypeName(segments.last) else newTermName(segments.last)
-
- // If the name as given resolves to an existing symbol, show that.
- // Otherwise we'll show every symbol in the current run with a matching name.
- val syms = (container.info member target) match {
- case NoSymbol => currentRun.symSource.keys filter (_.name == name) toList
- case sym => List(sym)
+ /** We resolve the class/object ambiguity by passing a type/term name.
+ */
+ def showDef(fullName: Name, ph: Phase = currentRun.typerPhase.next) = {
+ def phased[T](body: => T): T = atPhase(ph)(body)
+
+ def walker(sym: Symbol, n: Name) = sym.info member n
+ def walk(root: Symbol, segs: List[Name]) = phased(segs.foldLeft(root)(walker))
+ def defs(sym: Symbol) = phased(sym.info.members map (x => if (x.isTerm) x.defString else x.toString))
+ def bases(sym: Symbol) = phased(sym.info.baseClasses map (_.fullName))
+ def mkName(str: String, term: Boolean) =
+ if (term) newTermName(str)
+ else newTypeName(str)
+
+ def nameSegments(name: String): List[Name] = {
+ name.indexWhere(ch => ch == '.' || ch == '#') match {
+ // it's the last segment: the argument to showDef tells us whether type or term
+ case -1 => if (name == "") Nil else List(mkName(name, fullName.isTermName))
+ // otherwise, we can tell based on whether '#' or '.' is the following char.
+ case idx =>
+ val (id, div, rest) = (name take idx, name charAt idx, name drop (idx + 1))
+ mkName(id, div == '.') :: nameSegments(rest)
+ }
+ }
+
+ val syms = {
+ // creates a list of simple type and term names.
+ val segments = nameSegments(fullName.toString)
+
+ // make the type/term selections walking from the root.
+ walk(definitions.RootClass, segments) match {
+ // The name as given was not found, so we'll sift through every symbol in
+ // the run looking for plausible matches.
+ case NoSymbol => phased {
+ currentRun.symSource.keys.toList .
+ filter (_.simpleName == segments.head) .
+ map (sym => walk(sym, segments.tail)) .
+ filterNot (_ == NoSymbol)
+ }
+ // The name as given matched, so show only that.
+ case sym => List(sym)
+ }
}
syms foreach { sym =>
- val name = "\n<<-- " + sym.kindString + " " + sym.fullName + " -->>\n"
- val baseClasses = sym.info.baseClasses map (_.fullName) mkString ("Base classes:\n ", "\n ", "\n")
- val members = atPhase(currentRun.typerPhase.next)(sym.info.members map (_.defString))
- val memberStr = members.mkString("Members after phase typer:\n ", "\n ", "\n")
+ val name = phased("\n<<-- " + sym.kindString + " " + sym.fullName + " -->>\n")
+ val baseClasses = bases(sym).mkString("Base classes:\n ", "\n ", "\n")
+ val members = defs(sym).mkString("Members after phase typer:\n ", "\n ", "\n")
- inform(List(name, baseClasses, memberStr) mkString "\n")
+ inform(List(name, baseClasses, members) mkString "\n")
}
}