aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-10-16 13:23:59 +0200
committerMartin Odersky <odersky@gmail.com>2016-10-16 13:23:59 +0200
commitf98b847cb2fca7d82cd24c869f4ba5a60c49d8b1 (patch)
tree08303aecf8de2ab744048f9cbf2dd42478946cab /src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
parentbc0bdb198269f040bd0b7fc0abeb30447fd2abe1 (diff)
downloaddotty-f98b847cb2fca7d82cd24c869f4ba5a60c49d8b1.tar.gz
dotty-f98b847cb2fca7d82cd24c869f4ba5a60c49d8b1.tar.bz2
dotty-f98b847cb2fca7d82cd24c869f4ba5a60c49d8b1.zip
Handle shared trees
Shared trees are pickled under multiple addresses. Previously, only the last address was stored, which led to trees with unknown positions. Now, all addresses are stored.
Diffstat (limited to 'src/dotty/tools/dotc/core/tasty/TreeBuffer.scala')
-rw-r--r--src/dotty/tools/dotc/core/tasty/TreeBuffer.scala32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
index b9e1d2b45..f2681ecde 100644
--- a/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
+++ b/src/dotty/tools/dotc/core/tasty/TreeBuffer.scala
@@ -17,13 +17,26 @@ class TreeBuffer extends TastyBuffer(50000) {
private var delta: Array[Int] = _
private var numOffsets = 0
- private val treeAddr = new java.util.IdentityHashMap[Tree, Any] // Value type is really Addr, but that's not compatible with null
+ private type TreeAddrs = Any // really: Addr | List[Addr]
- def registerTreeAddr(tree: Tree) = treeAddr.put(tree, currentAddr)
-
- def addrOfTree(tree: Tree): Option[Addr] = treeAddr.get(tree) match {
- case null => None
- case n => Some(n.asInstanceOf[Addr])
+ /** A map from trees to the address(es) at which a tree is pickled. There may be several
+ * such addresses if the tree is shared. To keep the map compact, the value type is a
+ * disjunction of a single address (which is the common case) and a list of addresses.
+ */
+ private val treeAddrs = new java.util.IdentityHashMap[Tree, TreeAddrs]
+
+ def registerTreeAddr(tree: Tree) =
+ treeAddrs.put(tree,
+ treeAddrs.get(tree) match {
+ case null => currentAddr
+ case x: Addr => x :: currentAddr :: Nil
+ case xs: List[_] => xs :+ currentAddr
+ })
+
+ def addrsOfTree(tree: Tree): List[Addr] = treeAddrs.get(tree) match {
+ case null => Nil
+ case addr: Addr => addr :: Nil
+ case addrs: List[Addr] => addrs
}
private def offset(i: Int): Addr = Addr(offsets(i))
@@ -150,10 +163,13 @@ class TreeBuffer extends TastyBuffer(50000) {
}
def adjustTreeAddrs(): Unit = {
- val it = treeAddr.keySet.iterator
+ val it = treeAddrs.keySet.iterator
while (it.hasNext) {
val tree = it.next
- treeAddr.put(tree, adjusted(treeAddr.get(tree).asInstanceOf[Addr]))
+ treeAddrs.get(tree) match {
+ case addr: Addr => treeAddrs.put(tree, adjusted(addr))
+ case addrs: List[Addr] => treeAddrs.put(tree, addrs.map(adjusted))
+ }
}
}