summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2012-02-20 15:20:54 +0100
committerAdriaan Moors <adriaan.moors@epfl.ch>2012-03-22 18:14:29 +0100
commita1f5933e43831c25fed55969e4d5d2fd530daa2e (patch)
treebac384fa7d217a3c99d03fdd4d4154bdc7ecce2b
parent083970b21ff2fa272ff2cfb26e571682d32f5e84 (diff)
downloadscala-a1f5933e43831c25fed55969e4d5d2fd530daa2e.tar.gz
scala-a1f5933e43831c25fed55969e4d5d2fd530daa2e.tar.bz2
scala-a1f5933e43831c25fed55969e4d5d2fd530daa2e.zip
minimalist refactoring to allow annotating trees
not tested for performance, but shouldn't add any memory overhead see https://github.com/adriaanm/scala/commit/44362c557f for an example usage
-rw-r--r--src/compiler/scala/reflect/runtime/Universe.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Positions.scala9
-rw-r--r--src/compiler/scala/tools/nsc/util/Position.scala13
-rw-r--r--src/library/scala/reflect/api/Positions.scala18
-rw-r--r--src/library/scala/reflect/api/Trees.scala19
5 files changed, 54 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/runtime/Universe.scala b/src/compiler/scala/reflect/runtime/Universe.scala
index 324fee87ab..7a5dda3d8e 100644
--- a/src/compiler/scala/reflect/runtime/Universe.scala
+++ b/src/compiler/scala/reflect/runtime/Universe.scala
@@ -39,6 +39,11 @@ class Universe extends SymbolTable {
definitions.AnyValClass // force it.
+ type TreeAnnotation = Position
+ val NoTreeAnnotation: TreeAnnotation = NoPosition
+ def positionToAnnotation(pos: Position): TreeAnnotation = pos // TODO
+ def annotationToPosition(annot: TreeAnnotation): Position = annot //TODO
+
// establish root association to avoid cyclic dependency errors later
classToScala(classOf[java.lang.Object]).initialize
diff --git a/src/compiler/scala/tools/nsc/symtab/Positions.scala b/src/compiler/scala/tools/nsc/symtab/Positions.scala
index c96c709fb0..680b06f8ce 100644
--- a/src/compiler/scala/tools/nsc/symtab/Positions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Positions.scala
@@ -14,6 +14,15 @@ self: scala.tools.nsc.symtab.SymbolTable =>
type Position = scala.tools.nsc.util.Position
val NoPosition = scala.tools.nsc.util.NoPosition
+ type TreeAnnotation = scala.tools.nsc.util.TreeAnnotation
+ val NoTreeAnnotation: TreeAnnotation = NoPosition
+ def positionToAnnotation(pos: Position): TreeAnnotation = pos
+ def annotationToPosition(annot: TreeAnnotation): Position = annot.pos
+ override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = {
+ if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot)
+ // if ((tree.annotation.isInstanceOf[scala.tools.nsc.util.Position] || !annot.isInstanceOf[scala.tools.nsc.util.Position]) && tree.isInstanceOf[Block])
+ // println("Updating block from "+ tree.annotation +" to "+ annot)
+ }
def focusPos(pos: Position): Position = pos.focus
def isRangePos(pos: Position): Boolean = pos.isRange
def showPos(pos: Position): String = pos.show
diff --git a/src/compiler/scala/tools/nsc/util/Position.scala b/src/compiler/scala/tools/nsc/util/Position.scala
index 53c767be20..bc74717366 100644
--- a/src/compiler/scala/tools/nsc/util/Position.scala
+++ b/src/compiler/scala/tools/nsc/util/Position.scala
@@ -33,6 +33,16 @@ object Position {
}
}
+/**
+ * A tree does not directly store a Position. It stores a TreeAnnotation, which /typically/ is a Position.
+ *
+ * A TreeAnnotion may encompass more than just a Position, though, depending on the exact subclass of TreeAnnotation.
+ */
+trait TreeAnnotation {
+ def pos: Position
+}
+
+
/** The Position class and its subclasses represent positions of ASTs and symbols.
* Except for NoPosition and FakePos, every position refers to a SourceFile
* and to an offset in the sourcefile (its `point`). For batch compilation,
@@ -77,7 +87,8 @@ object Position {
* pos.makeTransparent converts an opaque range position into a transparent one.
* returns all other positions unchanged.
*/
-trait Position {
+trait Position extends TreeAnnotation {
+ def pos: Position = this
/** An optional value containing the source file referred to by this position, or
* None if not defined.
diff --git a/src/library/scala/reflect/api/Positions.scala b/src/library/scala/reflect/api/Positions.scala
index 181e7c1525..4c8c33bec8 100644
--- a/src/library/scala/reflect/api/Positions.scala
+++ b/src/library/scala/reflect/api/Positions.scala
@@ -1,9 +1,21 @@
package scala.reflect
package api
-trait Positions {
+trait Positions { self: Universe =>
+ /** TreeAnnotation is a generalisation of Position.
+ *
+ * TreeAnnotation cannot be an upperbound of Position since the corresponding classes
+ * must live outside of the universe for backwards compatibility (see scala.tools.nsc.util.Position).
+ * Thus, represent subtyping as coercions.
+ *
+ * Typically, positionToAnnotation is the identity, and annotationToPosition returns annot.pos
+ */
+ type TreeAnnotation // <: { def pos: Position }
+ val NoTreeAnnotation: TreeAnnotation
+ implicit def positionToAnnotation(pos: Position): TreeAnnotation // = pos
+ def annotationToPosition(annot: TreeAnnotation): Position // = annot.pos
+ def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = () // check that annot may overwrite tree.annot
- type Position
+ type Position // <: TreeAnnotation, but not practical to enforce this (would require moving Position, SourceFile, Reporter,... into the universe)
val NoPosition: Position
-
} \ No newline at end of file
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 466c380cef..4ee13adf52 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -74,17 +74,24 @@ trait Trees { self: Universe =>
val id = nodeCount
nodeCount += 1
- private[this] var rawpos: Position = NoPosition
-
/** Prefix under which to print this tree type. Defaults to product
* prefix (e.g. DefTree) but because that is used in reification
* it cannot be altered without breaking reflection.
*/
def printingPrefix = productPrefix
- def pos = rawpos
- def pos_=(pos: Position) = rawpos = pos
- def setPos(pos: Position): this.type = { rawpos = pos; this }
+ def pos: Position = annotationToPosition(rawannot)
+ def pos_=(pos: Position): Unit = annotation = pos
+ def setPos(newpos: Position): this.type = { pos = newpos; this }
+
+ private[this] var rawannot: TreeAnnotation = NoTreeAnnotation
+ def annotation: TreeAnnotation = rawannot
+ def annotation_=(annot: TreeAnnotation): Unit = {
+ _checkSetAnnotation(this, annot)
+ rawannot = annot
+ }
+
+ def setAnnotation(annot: TreeAnnotation): this.type = { annotation = annot; this }
private[this] var rawtpe: Type = _
@@ -223,7 +230,7 @@ trait Trees { self: Universe =>
duplicateTree(this).asInstanceOf[this.type]
private[scala] def copyAttrs(tree: Tree): this.type = {
- pos = tree.pos
+ annotation = tree.annotation
tpe = tree.tpe
if (hasSymbol) symbol = tree.symbol
this