diff options
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/PositionPickler.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/PositionPickler.scala | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/PositionPickler.scala b/src/dotty/tools/dotc/core/pickling/PositionPickler.scala index 6215a452d..8ee70719e 100644 --- a/src/dotty/tools/dotc/core/pickling/PositionPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/PositionPickler.scala @@ -41,24 +41,34 @@ class PositionPickler(pickler: TastyPickler, addrOfTree: Tree => Option[Addr]) { 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) - } - - } def picklePositions(roots: List[Tree], totalRange: Position)(implicit ctx: Context) = { + var lastIndex = 0 + def record(tree: Tree, parentPos: Position): Unit = + if (tree.pos.exists) { + def msg = s"failure to pickle $tree at ${tree.pos}, parent = $parentPos" + val endPos = tree.pos.end min parentPos.end + // end positions can be larger than their parents + // e.g. in the case of synthetic empty ranges, which are placed at the next token after + // the current construct. + val endDelta = endPos - parentPos.end + val startPos = + if (endDelta == 0) tree.pos.start max parentPos.start else tree.pos.start min endPos + // Since end positions are corrected above, start positions have to follow suit. + val startDelta = startPos - parentPos.start + if (startDelta != 0 || endDelta != 0) + for (addr <- addrOfTree(tree)) { + buf.writeInt(addr.index - lastIndex) + lastIndex = addr.index + if (startDelta != 0) buf.writeInt(startDelta) + if (endDelta != 0) { + assert(endDelta < 0, msg) + buf.writeInt(endDelta) + } else + assert(startDelta >= 0, msg) + } + } + buf.writeNat(totalRange.end) traverse(roots, totalRange, record) } |