diff options
5 files changed, 54 insertions, 108 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala b/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala deleted file mode 100644 index 88e4733d1..000000000 --- a/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala +++ /dev/null @@ -1,21 +0,0 @@ -package dotty.tools -package dotc -package core -package pickling - -import TastyBuffer.Addr - -class PositionBuffer extends TastyBuffer(100000) { thisBuffer => - - private var lastOffset: Int = -1 - private var lastIndex: Int = 0 - - def record(addr: Addr, offset: Int, recordAlways: Boolean): Unit = - if (offset != lastOffset || recordAlways) { - if (lastOffset < 0) lastOffset = 0 - writeInt(offset - lastOffset) - writeInt(addr.index - lastIndex) - lastOffset = offset - lastIndex = addr.index - } -}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/pickling/PositionPickler.scala b/src/dotty/tools/dotc/core/pickling/PositionPickler.scala index 7cb7de6e3..6215a452d 100644 --- a/src/dotty/tools/dotc/core/pickling/PositionPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/PositionPickler.scala @@ -10,21 +10,56 @@ import core._ import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annotations._ import collection.mutable import TastyBuffer._ -import Traversals._ +import util.Positions._ + +object PositionPickler { + + trait DeferredPosition { + var parentPos: Position = NoPosition + } + + def traverse(x: Any, parentPos: Position, op: (Tree, Position) => Unit)(implicit ctx: Context): Unit = + if (parentPos.exists) + x match { + case x: Tree @unchecked => + op(x, parentPos) + x match { + case x: MemberDef @unchecked => traverse(x.symbol.annotations, x.pos, op) + case _ => + } + traverse(x.productIterator, x.pos, op) + case x: DeferredPosition => + x.parentPos = parentPos + case xs: TraversableOnce[_] => + xs.foreach(traverse(_, parentPos, op)) + case _ => + } +} +import PositionPickler._ class PositionPickler(pickler: TastyPickler, addrOfTree: Tree => Option[Addr]) { - val buf = new PositionBuffer + val buf = new TastyBuffer(100000) pickler.newSection("Positions", buf) import buf._ + + private def record(tree: Tree, parentPos: Position): Unit = { + assert(tree.pos.exists) + val startDelta = tree.pos.start - parentPos.start + val endDelta = tree.pos.end - parentPos.end + if (startDelta != 0 || endDelta != 0) + for (addr <- addrOfTree(tree)) { + buf.writeInt(addr.index) + if (startDelta != 0) buf.writeInt(startDelta) + if (endDelta != 0) { + assert(endDelta < 0) + buf.writeInt(endDelta) + } else assert(startDelta >= 0) + } - private def record(tree: Tree, start: Boolean) = - if (tree.pos.exists) - for (addr <- addrOfTree(tree)) - buf.record( - addr, - offset = if (start) tree.pos.start else tree.pos.end, - recordAlways = !start && tree.isInstanceOf[WithLazyField[_]]) + } - def picklePositions(roots: List[Tree])(implicit ctx: Context) = - traverse(roots, record(_, true), record(_, false)) + def picklePositions(roots: List[Tree], totalRange: Position)(implicit ctx: Context) = { + buf.writeNat(totalRange.end) + traverse(roots, totalRange, record) + } }
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/pickling/Traversals.scala b/src/dotty/tools/dotc/core/pickling/Traversals.scala deleted file mode 100644 index 85dc53cd0..000000000 --- a/src/dotty/tools/dotc/core/pickling/Traversals.scala +++ /dev/null @@ -1,54 +0,0 @@ -package dotty.tools.dotc -package core -package pickling - -import util.Positions._ -import ast.tpd._ -import ast.Trees.Lazy -import core.Contexts._ - -object Traversals { - - def traverse(x: Any, leftOp: Tree => Unit, rightOp: Tree => Unit) = { - - def traverseElems(xs: TraversableOnce[Any]) = xs.foreach(traverseElem) - - def traverseElem(x: Any): Unit = x match { - case x: Tree @ unchecked => -/** TODO: pickle annotation positions - x match { - case x: MemberDef => traverseElems(x.symbol.annotations) - case _ => - } */ - leftOp(x) - x match { - case x: ValDef => - traverseElem(x.tpt) - traverseUnlessLazy(x.unforced) - case x: DefDef => - traverseElems(x.tparams) - traverseElems(x.vparamss) - traverseElem(x.tpt) - traverseUnlessLazy(x.unforced) - case x: Template => - traverseElem(x.constr) - traverseElems(x.parents) - traverseElem(x.self) - traverseUnlessLazy(x.unforced) - case _ => - traverseElems(x.productIterator) - } - rightOp(x) - case xs: List[_] => - traverseElems(xs) - case _ => - } - - def traverseUnlessLazy(x: Any) = x match { - case x: Lazy[_] => - case _ => traverseElem(x) - } - - traverseElem(x) - } -}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala b/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala index ceb1f7db1..eaf7dfc55 100644 --- a/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala +++ b/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala @@ -13,6 +13,7 @@ import TastyUnpickler._, TastyBuffer._ import annotation.switch import scala.collection.{ mutable, immutable } import typer.Mode +import PositionPickler._ /** Unpickler for typed trees * @param reader the reader from which to unpickle @@ -686,29 +687,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, } } - trait DeferredPosition { - var parentPos: Position = NoPosition + private def setNormalized(tree: Tree, parentPos: Position): Unit = { + assert(tree.pos.exists) + val absPos = Position(parentPos.start + tree.pos.start, parentPos.end - tree.pos.end) + tree.setPosUnchecked(absPos) } - def normalizePos(x: Any, parentPos: Position)(implicit ctx: Context): Unit = { - if (parentPos.exists) - x match { - case x: Tree @unchecked if !x.pos.isSynthetic => - assert(x.pos.exists) - val absPos = Position(parentPos.start + x.pos.start, parentPos.end - x.pos.end) - x.setPosUnchecked(absPos) - x match { - case x: MemberDef => normalizePos(x.symbol.annotations, absPos) - case _ => - } - normalizePos(x.productIterator, absPos) - case x: DeferredPosition => - x.parentPos = parentPos - case xs: List[_] => - xs.foreach(normalizePos(_, parentPos)) - case _ => - } - } + def normalizePos(x: Any, parentPos: Position)(implicit ctx: Context): Unit = + traverse(x, parentPos, setNormalized) class LazyReader[T <: AnyRef](reader: TreeReader, op: TreeReader => Context => T) extends Trees.Lazy[T] with DeferredPosition { def complete(implicit ctx: Context): T = { diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala index 91d0fac34..bf7c771cc 100644 --- a/src/dotty/tools/dotc/transform/Pickler.scala +++ b/src/dotty/tools/dotc/transform/Pickler.scala @@ -20,7 +20,7 @@ class Pickler extends MiniPhaseTransform { thisTransform => val treePkl = new TreePickler(pickler) treePkl.pickle(tree :: Nil) - new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil) + new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil, tree.pos) val bytes = pickler.assembleParts() ctx.compilationUnit.pickled = bytes |