From f98b847cb2fca7d82cd24c869f4ba5a60c49d8b1 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 16 Oct 2016 13:23:59 +0200 Subject: 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. --- .../tools/dotc/core/tasty/PositionPickler.scala | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'src/dotty/tools/dotc/core/tasty/PositionPickler.scala') diff --git a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala index 65e9d12be..b528b8aaf 100644 --- a/src/dotty/tools/dotc/core/tasty/PositionPickler.scala +++ b/src/dotty/tools/dotc/core/tasty/PositionPickler.scala @@ -13,12 +13,29 @@ import collection.mutable import TastyBuffer._ import util.Positions._ -class PositionPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Option[Addr]) { +class PositionPickler(pickler: TastyPickler, addrsOfTree: tpd.Tree => List[Addr]) { val buf = new TastyBuffer(5000) pickler.newSection("Positions", buf) import buf._ import ast.tpd._ + private val remainingAddrs = new java.util.IdentityHashMap[Tree, Iterator[Addr]] + + def nextTreeAddr(tree: Tree): Option[Addr] = remainingAddrs.get(tree) match { + case null => + addrsOfTree(tree) match { + case Nil => + None + case addr :: Nil => + Some(addr) + case addrs => + remainingAddrs.put(tree, addrs.iterator) + nextTreeAddr(tree) + } + case it: Iterator[_] => + if (it.hasNext) Some(it.next) else None + } + def header(addrDelta: Int, hasStartDelta: Boolean, hasEndDelta: Boolean) = { def toInt(b: Boolean) = if (b) 1 else 0 (addrDelta << 2) | (toInt(hasStartDelta) << 1) | toInt(hasEndDelta) @@ -40,9 +57,9 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: tpd.Tree => Option[Addr def traverse(x: Any): Unit = x match { case x: Tree @unchecked => if (x.pos.exists /*&& x.pos.toSynthetic != x.initialPos.toSynthetic*/) { - addrOfTree(x) match { + nextTreeAddr(x) match { case Some(addr) => - //println(i"pickling $x") + //println(i"pickling $x ar $addr") pickleDeltas(addr.index, x.pos) case _ => //println(i"no address for $x") -- cgit v1.2.3