aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/util/Positions.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-17 09:48:22 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-17 10:16:22 +0200
commitca8dc7ada663e44aafe470944dd17256dbde151c (patch)
treed15939e204042e358e0c83064250f1f18c1c4f25 /src/dotty/tools/dotc/util/Positions.scala
parente32fedb6844eab11a27e365a570b2033a0f6f78d (diff)
downloaddotty-ca8dc7ada663e44aafe470944dd17256dbde151c.tar.gz
dotty-ca8dc7ada663e44aafe470944dd17256dbde151c.tar.bz2
dotty-ca8dc7ada663e44aafe470944dd17256dbde151c.zip
Scanners added.
Moving Positions, Chars to new packages. Added Source positions. Added untyped trees module. Factored out behavior between typed and untyped trees.
Diffstat (limited to 'src/dotty/tools/dotc/util/Positions.scala')
-rw-r--r--src/dotty/tools/dotc/util/Positions.scala88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/util/Positions.scala b/src/dotty/tools/dotc/util/Positions.scala
new file mode 100644
index 000000000..31eb2ff0d
--- /dev/null
+++ b/src/dotty/tools/dotc/util/Positions.scala
@@ -0,0 +1,88 @@
+package dotty.tools.dotc
+package util
+
+/** Position format in little endian:
+ * Start: unsigned 26 Bits (works for source files up to 64M)
+ * End: unsigned 26 Bits
+ * Point: unsigned 12 Bits relative to start
+ * NoPosition encoded as -1L (this is a normally invalid position
+ * because point would lie beyond end.
+ */
+object Positions {
+
+ private val StartEndBits = 26
+ private val StartEndMask = (1 << StartEndBits) - 1
+ private val PointOffsetLimit = 1L << (64 - StartEndBits * 2)
+
+ class Position(val coords: Long) extends AnyVal {
+ def point: Int = start + (coords >>> (StartEndBits * 2)).toInt
+ def start: Int = (coords & StartEndMask).toInt
+ def end: Int = ((coords >>> StartEndBits) & StartEndMask).toInt
+
+ /** The union of two positions. Tries to keep the point offset of
+ * the first positon if within range. Otherwise, pointoffset will be 0.
+ */
+ def union(that: Position) =
+ if (!this.exists) that
+ else if (!that.exists) this
+ else {
+ val start = this.start min that.start
+ val end = this.end max that.end
+ var pointOffset = this.point - start
+ if (pointOffset >= PointOffsetLimit) pointOffset = 0
+ Position(start, end, pointOffset)
+ }
+
+ def exists = this != NoPosition
+
+ def shift(offset: Int) =
+ if (exists) Position(start + offset, end + offset, point - start)
+ else this
+
+ def focus = Position(point)
+
+ def withStart(start: Int) = Position(start, this.end, this.point - start)
+ def withEnd(end: Int) = Position(this.start, end, this.point - this.start)
+ def withPoint(point: Int) = Position(this.start, this.end, point - this.start)
+ }
+
+ def Position(start: Int, end: Int, pointOffset: Int = 0): Position =
+ new Position(
+ (start & StartEndMask).toLong |
+ ((end & StartEndMask).toLong << StartEndBits) |
+ (pointOffset.toLong << (StartEndBits * 2)))
+
+ def Position(point: Int): Position = Position(point, point, 0)
+
+ val NoPosition = new Position(-1L)
+
+ case class SourcePosition(source: SourceFile, pos: Position) {
+ def point: Int = pos.point
+ def start: Int = pos.start
+ def end: Int = pos.end
+ def exists = pos.exists
+ }
+
+ val NoSourcePosition = SourcePosition(NoSource, NoPosition)
+
+ /** The coordinate of a symbol. This is either an index or
+ * a point position.
+ */
+ class Coord(val encoding: Int) extends AnyVal {
+ def isIndex = encoding > 0
+ def isPosition = encoding <= 0
+ def toIndex: Int = {
+ assert(isIndex)
+ encoding - 1
+ }
+ def toPosition = {
+ assert(isPosition)
+ if (this == NoCoord) NoPosition else Position(1 - encoding)
+ }
+ }
+
+ def indexCoord(n: Int) = new Coord(n + 1)
+ def positionCoord(n: Int) = new Coord(-(n + 1))
+
+ val NoCoord = new Coord(0)
+} \ No newline at end of file