aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/PositionReader.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/PositionReader.scala')
-rw-r--r--src/dotty/tools/dotc/core/pickling/PositionReader.scala67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/PositionReader.scala b/src/dotty/tools/dotc/core/pickling/PositionReader.scala
new file mode 100644
index 000000000..5acb3c6d8
--- /dev/null
+++ b/src/dotty/tools/dotc/core/pickling/PositionReader.scala
@@ -0,0 +1,67 @@
+package dotty.tools
+package dotc
+package core
+package pickling
+
+import java.io.IOException
+
+import Contexts._
+import ast.tpd
+import ast.Trees.{Lazy,WithLazyField}
+import TastyBuffer._
+import Traversals._
+import util.Positions._
+
+/** Unpickler for start or end offset of tree positions */
+class PositionReader(reader: TastyReader, startOffset: Int, initNextOffset: Int, initNextAddr: Int) {
+ import reader._
+ import tpd._
+
+ def this(reader: TastyReader) = {
+ this(reader, 0, 0, 0)
+ next()
+ }
+
+ var lastOffset: Int = startOffset
+ var nextOffset = initNextOffset
+ var nextAddr = initNextAddr
+
+ private def fork =
+ new PositionReader(subReader(currentAddr, endAddr), lastOffset, nextOffset, nextAddr)
+
+ private def next() = {
+ lastOffset = nextOffset
+ if (!isAtEnd) {
+ nextOffset += readInt()
+ nextAddr += readInt()
+ }
+ }
+
+ def readStart(tree: Tree) =
+ if (tree.pos.exists) { // TODO assign positions of tree nodes with NoPosition afterwards based on the context.
+ val addr = tree.pos.end
+ if (addr == nextAddr) next()
+ tree.setPosUnchecked(tree.pos.withStart(lastOffset))
+ }
+
+ def readEnd(tree: Tree) = {
+ if (tree.pos.exists) {
+ val addr = tree.pos.end
+ tree match {
+ case tree: WithLazyField[_] =>
+ tree.unforced match {
+ case rdr: TreeUnpickler#LazyReader[_] =>
+ rdr.posReader = Some(fork)
+ while (addr != nextAddr) next()
+ case _ =>
+ }
+ case _ =>
+ }
+ if (addr == nextAddr) next()
+ tree.setPosUnchecked(tree.pos.withEnd(lastOffset))
+ }
+ }
+
+ def unpickle(x: Any) =
+ traverse(x, readStart, readEnd)
+} \ No newline at end of file