aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/PositionPickler.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-02-27 12:13:34 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-18 11:14:11 +0100
commit43a03c39a39b039c28e17485af39d14fea1e5600 (patch)
treeb92516dd4533d3f1d07d43e6d20886cf63502d5e /src/dotty/tools/dotc/core/pickling/PositionPickler.scala
parent471881d0d51460c93294e006982aa7022a627814 (diff)
downloaddotty-43a03c39a39b039c28e17485af39d14fea1e5600.tar.gz
dotty-43a03c39a39b039c28e17485af39d14fea1e5600.tar.bz2
dotty-43a03c39a39b039c28e17485af39d14fea1e5600.zip
Added testing hooks for unpickler
New option -Ytest-pickler compares trees before and after pickling.
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/PositionPickler.scala')
-rw-r--r--src/dotty/tools/dotc/core/pickling/PositionPickler.scala42
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)
}