aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-02-23 13:53:22 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-18 11:14:09 +0100
commitf16b12c3a58bdd692089c23288a45a80f14332ab (patch)
treeb8bc321075c2bb022c31ae225a73ad2d880cb4fb /src/dotty
parent8fea2ef8368dc1bf82bb8064dd17368c38bb2347 (diff)
downloaddotty-f16b12c3a58bdd692089c23288a45a80f14332ab.tar.gz
dotty-f16b12c3a58bdd692089c23288a45a80f14332ab.tar.bz2
dotty-f16b12c3a58bdd692089c23288a45a80f14332ab.zip
First version of position pickler.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/pickling/Edge.scala22
-rw-r--r--src/dotty/tools/dotc/core/pickling/PositionBuffer.scala33
-rw-r--r--src/dotty/tools/dotc/core/pickling/PositionPickler.scala51
-rw-r--r--src/dotty/tools/dotc/core/pickling/TastyPrinter.scala23
-rw-r--r--src/dotty/tools/dotc/transform/Pickler.scala2
5 files changed, 131 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/Edge.scala b/src/dotty/tools/dotc/core/pickling/Edge.scala
new file mode 100644
index 000000000..543f85831
--- /dev/null
+++ b/src/dotty/tools/dotc/core/pickling/Edge.scala
@@ -0,0 +1,22 @@
+package dotty.tools.dotc
+package core.pickling
+
+import util.Positions._
+import ast.tpd._
+import core.Contexts._
+
+abstract class Edge {
+ def offset(pos: Position): Int
+ def seq(op1: () => Unit, op2: () => Unit): Unit
+}
+
+object Edge {
+ object left extends Edge {
+ def offset(pos: Position): Int = pos.start
+ def seq(op1: () => Unit, op2: () => Unit) = { op1(); op2() }
+ }
+ object right extends Edge {
+ def offset(pos: Position): Int = pos.end
+ def seq(op1: () => Unit, op2: () => Unit) = { op2(); op1() }
+ }
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala b/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala
new file mode 100644
index 000000000..f564e364d
--- /dev/null
+++ b/src/dotty/tools/dotc/core/pickling/PositionBuffer.scala
@@ -0,0 +1,33 @@
+package dotty.tools
+package dotc
+package core
+package pickling
+
+import TastyBuffer.Addr
+
+class PositionBuffer extends TastyBuffer(100000) { thisBuffer =>
+
+ class PositionRecorder(val edge: Edge) extends TastyBuffer(thisBuffer.bytes.size / 2) {
+ private var lastOffset: Int = -1
+ private var lastIndex: Int = 0
+ def record(addr: Addr, offset: Int): Unit =
+ if (offset != lastOffset) {
+ if (lastOffset < 0) lastOffset = 0
+ writeInt(offset - lastOffset)
+ writeInt(addr.index - lastIndex)
+ lastOffset = offset
+ lastIndex = addr.index
+ }
+ }
+
+ val startPos = new PositionRecorder(Edge.left)
+ val endPos = new PositionRecorder(Edge.right)
+
+ /** Final assembly: copy startPos and endPos into own bytes */
+ override def assemble(): Unit = {
+ writeNat(startPos.length)
+ writeBytes(startPos.bytes, startPos.length)
+ writeNat(endPos.length)
+ writeBytes(endPos.bytes, endPos.length)
+ }
+} \ 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
new file mode 100644
index 000000000..0cf519b23
--- /dev/null
+++ b/src/dotty/tools/dotc/core/pickling/PositionPickler.scala
@@ -0,0 +1,51 @@
+package dotty.tools
+package dotc
+package core
+package pickling
+
+import ast.tpd._
+import PickleFormat._
+import core._
+import Contexts._, Symbols._, Types._, Names._, Constants._, Decorators._, Annotations._
+import collection.mutable
+import TastyBuffer._
+
+class PositionPickler(pickler: TastyPickler, addrOfTree: Tree => Option[Addr]) {
+ val buf = new PositionBuffer
+ pickler.newSection("Positions", buf)
+ import buf._
+
+ val noOp = () => ()
+
+ def traverseAll(root: Tree, recorder: PositionRecorder)(implicit ctx: Context) = {
+ import recorder.edge.{seq, offset}
+
+ def elemsTraversal(xs: TraversableOnce[Any]): () => Unit =
+ (noOp /: xs) ((op, x) => () => seq(op, elemTraversal(x)))
+
+ def elemTraversal(x: Any): () => Unit = () => x match {
+ case x: Tree @ unchecked =>
+ if (x.pos.exists)
+ for (addr <- addrOfTree(x))
+ recorder.record(addr, offset(x.pos))
+
+ val annotTraversal = x match {
+ case x: MemberDef => elemsTraversal(x.symbol.annotations)
+ case _ => noOp
+ }
+ val childrenTraversal = elemsTraversal(x.productIterator)
+ seq(annotTraversal, childrenTraversal)
+ case xs: List[_] =>
+ elemsTraversal(xs)()
+ case _ =>
+ ()
+ }
+
+ elemTraversal(root)()
+ }
+
+ def picklePositions(root: Tree)(implicit ctx: Context) = {
+ traverseAll(root, startPos)
+ traverseAll(root, endPos)
+ }
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/pickling/TastyPrinter.scala b/src/dotty/tools/dotc/core/pickling/TastyPrinter.scala
index 8056e600d..cf531ecac 100644
--- a/src/dotty/tools/dotc/core/pickling/TastyPrinter.scala
+++ b/src/dotty/tools/dotc/core/pickling/TastyPrinter.scala
@@ -34,6 +34,7 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
printNames()
println("Trees:")
unpickle(new TreeUnpickler)
+ unpickle(new PositionUnpickler)
}
class TreeUnpickler extends SectionUnpickler[Unit]("ASTs") {
@@ -101,4 +102,26 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
}
}
}
+
+ class PositionUnpickler extends SectionUnpickler[Unit]("Positions") {
+ def unpickle(reader: TastyReader, tastyName: TastyName.Table): Unit = {
+ import reader._
+
+ def unpickleOffsets(edge: Edge): Unit = {
+ var lastOffset = 0
+ var lastAddr = 0
+ val length = readNat()
+ println(s"$length offset bytes")
+ val end = currentAddr + length
+ until(end) {
+ lastOffset += readInt()
+ lastAddr += readInt()
+ println(s"$lastOffset: $lastAddr")
+ }
+ }
+
+ unpickleOffsets(Edge.left)
+ unpickleOffsets(Edge.right)
+ }
+ }
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala
index f080aa7ad..aa133eeb4 100644
--- a/src/dotty/tools/dotc/transform/Pickler.scala
+++ b/src/dotty/tools/dotc/transform/Pickler.scala
@@ -20,6 +20,8 @@ class Pickler extends MiniPhaseTransform { thisTransform =>
val treePkl = new TreePickler(pickler)
treePkl.pickle(tree)
+ new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree)
+
val bytes = pickler.assembleParts()
def rawBytes = // not needed right now, but useful to print raw format.
bytes.iterator.grouped(10).toList.zipWithIndex.map {