summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala62
2 files changed, 44 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index ee5bb8dc93..90d1135517 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -107,6 +107,7 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
})
def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
+ def shortClass: String = tree.getClass.getName split "[.$]" last
}
private[scala] override def duplicateTree(tree: Tree): Tree = duplicator transform tree
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
index aaa53c284a..870787a9ea 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
@@ -6,6 +6,8 @@
package scala.tools.nsc
package symtab
+import scala.collection.{ mutable, immutable }
+
/** Printing the symbol graph (for those symbols attached to an AST node)
* after each phase.
*/
@@ -13,6 +15,9 @@ trait SymbolTrackers {
val global: Global
import global._
+ private implicit lazy val TreeOrdering: Ordering[Tree] =
+ Ordering by (x => (x.shortClass, x.symbol))
+
private implicit lazy val SymbolOrdering: Ordering[Symbol] =
Ordering by (x => (x.kindString, x.name.toString))
@@ -31,28 +36,35 @@ trait SymbolTrackers {
case class Change(
added: Set[Symbol],
removed: Set[Symbol],
- owners: Map[Symbol, Symbol], // symbol -> previous owner
- flags: Map[Symbol, Long] // symbol -> previous flags
+ trees: Map[Symbol, Set[Tree]], // symbol -> trees which proudly display it
+ owners: Map[Symbol, Symbol], // symbol -> previous owner
+ flags: Map[Symbol, Long] // symbol -> previous flags
)
object SymbolTracker {
def containsSymbol(t: Tree) = t.symbol != null && t.symbol != NoSymbol
- def symbolsInUnit(unit: CompilationUnit): Set[Symbol] = {
- if (unit.body == null) Set.empty[Symbol]
- else unit.body filter containsSymbol map (_.symbol) toSet
+ // This is noise reduction only.
+ def dropSymbol(sym: Symbol) = sym.ownerChain exists (_ hasFlag Flags.SPECIALIZED)
+
+ def symbolSnapshot(unit: CompilationUnit): Map[Symbol, Set[Tree]] = {
+ if (unit.body == null) Map()
+ else unit.body filter containsSymbol groupBy (_.symbol) mapValues (_.toSet) toMap
}
def apply(unit: CompilationUnit) = new SymbolTracker(
- () => symbolsInUnit(unit) filterNot (_.ownerChain.exists(_ hasFlag Flags.SPECIALIZED))
+ () => symbolSnapshot(unit) filterNot { case (k, _) => dropSymbol(k) }
)
}
- class SymbolTracker(sourceFn: () => Set[Symbol]) {
+ class SymbolTracker(snapshotFn: () => Map[Symbol, Set[Tree]]) {
def flagsMask: Long = Flags.PrintableFlags
- private var current = Set[Symbol]()
- private var history = List[Change](Change(Set(), Set(), Map(), Map()))
- private var prev = Set[Symbol]()
+ private var currentMap = Map[Symbol, Set[Tree]]()
+ private var prevMap = Map[Symbol, Set[Tree]]()
+ private def current = currentMap.keySet
+ private def prev = prevMap.keySet
+
+ private var history = List[Change](Change(Set(), Set(), Map(), Map(), Map()))
private var prevFlags = Map[Symbol, Long]()
private var prevOwners = Map[Symbol, Symbol]()
@@ -63,7 +75,6 @@ trait SymbolTrackers {
private implicit def NodeOrdering: Ordering[Node] = Ordering by (_.root)
private def ownersString(sym: Symbol, num: Int) = sym.ownerChain drop 1 take num mkString " -> "
- private def allOwnersString(sym: Symbol) = sym.ownerChain mkString " -> "
object Node {
def nodes(syms: Set[Symbol]): List[Node] = {
@@ -117,7 +128,7 @@ trait SymbolTrackers {
" " + strs.filterNot(_ == "").mkString("[", " ", "]")
case _ =>
if (masked == 0L) ""
- else " " + Flags.flagsToString(masked)
+ else " (" + Flags.flagsToString(masked) + ")"
}
def symString(sym: Symbol) = (
sym + changedOwnerString + flagSummaryString
@@ -137,7 +148,7 @@ trait SymbolTrackers {
}
def snapshot(): Unit = {
- current = sourceFn()
+ currentMap = snapshotFn()
val added = current filterNot prev
val removed = prev filterNot current
@@ -155,22 +166,35 @@ trait SymbolTrackers {
(sym, old)
}).toMap
- val change = Change(added, removed, owners, flags)
+ val change = Change(added, removed, prevMap, owners, flags)
- prev = current
+ prevMap = currentMap
prevOwners = current map (s => (s, s.owner)) toMap;
prevFlags = current map (s => (s, (s.flags & flagsMask))) toMap;
history = change :: history
}
def show(): String = {
val hierarchy = Node(current)
- val removed = history.head.removed
+ val Change(added, removed, symMap, owners, flags) = history.head
+ def detailString(sym: Symbol) = {
+ val ownerString = sym.ownerChain splitAt 3 match {
+ case (front, back) =>
+ val xs = if (back.isEmpty) front else front :+ "..."
+ xs mkString " -> "
+ }
+ val treeStrings = symMap(sym) map { t =>
+ "%10s: %s".format(t.shortClass, t)
+ }
+
+ ownerString :: treeStrings mkString "\n"
+ }
+ def removedString = (removed: List[Symbol]).zipWithIndex map {
+ case (t, i) => "(%2s) ".format(i + 1) + detailString(t)
+ } mkString "\n"
"" + hierarchy + (
if (removed.isEmpty) ""
- else removed map allOwnersString mkString (
- "\n\n!!! " + removed.size + " symbols vanished:\n", "\n", ""
- )
+ else "\n\n!!! %s symbols vanished:\n".format(removed.size) + removedString
)
}
}