summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-02-06 21:02:54 +0000
committerPaul Phillips <paulp@improving.org>2011-02-06 21:02:54 +0000
commit7b19ec8b1b296913adb5c226decd16f1e091c76b (patch)
treeb54781ad6e570e7b2d54b95fecb63b46b779a21c /src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
parentd3701a58189de3fc1548ec1caaf1bbb02e04b813 (diff)
downloadscala-7b19ec8b1b296913adb5c226decd16f1e091c76b.tar.gz
scala-7b19ec8b1b296913adb5c226decd16f1e091c76b.tar.bz2
scala-7b19ec8b1b296913adb5c226decd16f1e091c76b.zip
A bit more work on the symbol trackers.
minor inaccuracy, and added flag change tracking as well. Now the left column zone may show any of: * // new symbol F // flags changed O // owner changed Or sometimes the awe-inspiring "FO" as in this example. class A { def foo(unit: String) { def bar(x: String) = x == null } } [[symbol layout at end of lambdalift]] class A#17 constructor A#8017 FO method bar$1#9953 [Owner was method foo#8018, now class A#17] [+private +final +<local>] value x#9954 method foo#8018 value unit#9882 value <local A>#8019 No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala98
1 files changed, 73 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
index 353b1ffd89..aaa53c284a 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala
@@ -31,7 +31,8 @@ trait SymbolTrackers {
case class Change(
added: Set[Symbol],
removed: Set[Symbol],
- changedOwner: Map[Symbol, Symbol]
+ owners: Map[Symbol, Symbol], // symbol -> previous owner
+ flags: Map[Symbol, Long] // symbol -> previous flags
)
object SymbolTracker {
@@ -47,19 +48,22 @@ trait SymbolTrackers {
}
class SymbolTracker(sourceFn: () => Set[Symbol]) {
- private var history = List[Change]()
+ 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 prevFlags = Map[Symbol, Long]()
private var prevOwners = Map[Symbol, Symbol]()
- private def changedOwner(sym: Symbol) = prevOwners get sym filter (_ != sym.owner)
- private def changedOwnerString(sym: Symbol) = changedOwner(sym) match {
- case Some(prev) => "[Owner changed: was " + ownersString(sym, 2) + "]"
- case _ => ""
- }
+
+ private def changed = history.head
+ private def isAdded(sym: Symbol) = changed added sym
+ private def isOwnerChange(sym: Symbol) = changed.owners contains sym
+ private def isFlagsChange(sym: Symbol) = changed.flags contains sym
+
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 " -> "
- private def isAdded(sym: Symbol) = history.nonEmpty && history.head.added(sym)
- private def isOwnerChange(sym: Symbol) = history.nonEmpty && (history.head.changedOwner contains sym)
+ private def allOwnersString(sym: Symbol) = sym.ownerChain mkString " -> "
object Node {
def nodes(syms: Set[Symbol]): List[Node] = {
@@ -80,11 +84,43 @@ trait SymbolTrackers {
}
}
class Node(val root: Symbol, val children: List[Hierarchy]) extends Hierarchy {
- def indicatorString = if (isAdded(root)) "* " else " "
-
+ def masked = root.flags & flagsMask
+ def indicatorString =
+ if (isAdded(root)) "* "
+ else List(
+ if (isFlagsChange(root)) "F" else "",
+ if (isOwnerChange(root)) "O" else "",
+ " "
+ ).mkString take 2
+
+ def changedOwnerString = changed.owners get root match {
+ case Some(prev) => " [Owner was " + prev + ", now " + root.owner + "]"
+ case _ => ""
+ }
+ def flagSummaryString = changed.flags get root match {
+ case Some(oldFlags) =>
+ val added = masked & ~oldFlags
+ val removed = oldFlags & ~masked
+ val steady = masked & ~(added | removed)
+ val all = masked | oldFlags
+ val strs = 0 to 63 map { bit =>
+ val flag = 1L << bit
+ val prefix = (
+ if ((added & flag) != 0L) "+"
+ else if ((removed & flag) != 0L) "-"
+ else ""
+ )
+ if ((all & flag) == 0L) ""
+ else prefix + Flags.flagToString(flag)
+ }
+
+ " " + strs.filterNot(_ == "").mkString("[", " ", "]")
+ case _ =>
+ if (masked == 0L) ""
+ else " " + Flags.flagsToString(masked)
+ }
def symString(sym: Symbol) = (
- sym + changedOwnerString(sym) + " " +
- sym.hasFlagsToString(Flags.PrintableFlags)
+ sym + changedOwnerString + flagSummaryString
)
def flatten = children.foldLeft(Set(root))(_ ++ _.flatten)
@@ -101,24 +137,36 @@ trait SymbolTrackers {
}
def snapshot(): Unit = {
- val syms = sourceFn()
- val added = syms filterNot prev
- val removed = prev filterNot syms
- val changed = ({
- for (sym <- prev intersect syms; old <- changedOwner(sym)) yield
+ current = sourceFn()
+
+ val added = current filterNot prev
+ val removed = prev filterNot current
+ val steady = prev intersect current
+
+ def changedOwner(sym: Symbol) = prevOwners get sym filter (_ != sym.owner)
+ def changedFlags(sym: Symbol) = prevFlags get sym filter (_ != (sym.flags & flagsMask))
+
+ val owners = ({
+ for (sym <- steady; old <- changedOwner(sym)) yield
(sym, old)
}).toMap
+ val flags = ({
+ for (sym <- steady; old <- changedFlags(sym)) yield
+ (sym, old)
+ }).toMap
+
+ val change = Change(added, removed, owners, flags)
- val change = Change(added, removed, changed)
- prev = syms
- prevOwners = syms map (s => (s, s.owner)) toMap;
+ prev = current
+ 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(sourceFn())
- val removed = if (history.isEmpty) Set() else history.head.removed
+ val hierarchy = Node(current)
+ val removed = history.head.removed
- hierarchy.toString() + (
+ "" + hierarchy + (
if (removed.isEmpty) ""
else removed map allOwnersString mkString (
"\n\n!!! " + removed.size + " symbols vanished:\n", "\n", ""