diff options
author | Martin Odersky <odersky@gmail.com> | 2013-11-04 11:29:00 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-11-04 11:29:00 +0100 |
commit | ab95d83444c6397f8859713dd6606602c77c8d23 (patch) | |
tree | fa490998a0ab2d72e4d86760417193a5e504374d /src/dotty/tools/dotc/ast/Trees.scala | |
parent | 19b6784ef1cae9cd0af278c0c3afcee47c0a00ea (diff) | |
download | dotty-ab95d83444c6397f8859713dd6606602c77c8d23.tar.gz dotty-ab95d83444c6397f8859713dd6606602c77c8d23.tar.bz2 dotty-ab95d83444c6397f8859713dd6606602c77c8d23.zip |
Upgraded handling of positions
It turned out the some trees were still carrying NoPosition in their pos fields. The new treatment avoids that and aslo adds some assertions to check for regressions.
Diffstat (limited to 'src/dotty/tools/dotc/ast/Trees.scala')
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 628e7f9d3..5ce505133 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -31,12 +31,15 @@ object Trees { */ abstract class Positioned extends DotClass with Product { - private var curPos: Position = initialPos + private[this] var curPos: Position = initialPos /** The item's position. */ def pos: Position = curPos + /** Destructively update to given poisition */ + protected def setPos(pos: Position): Unit = curPos = pos + /** The envelope containing the item in its entirety. Envelope is different from * `pos` for definitions (instances of MemberDef). */ @@ -49,7 +52,8 @@ object Trees { */ def withPos(pos: Position): this.type = { val newpd = (if (pos == curPos || curPos.isSynthetic) this else clone).asInstanceOf[Positioned] - newpd.curPos = pos + setPos(pos) + setChildPositions(pos.toSynthetic) newpd.asInstanceOf[this.type] } @@ -61,6 +65,27 @@ object Trees { */ def addPos(pos: Position): this.type = withPos(pos union this.pos) + /** If any children of this node do not have positions, set them to the given position, + * and transitively visit their children. + */ + private def setChildPositions(pos: Position): Unit = { + def deepSetPos(x: Any): Unit = x match { + case p: Positioned => + if (!p.pos.exists) { + p.setPos(pos) + p.setChildPositions(pos) + } + case xs: List[_] => + xs foreach deepSetPos + case _ => + } + var n = productArity + while (n > 0) { + n -= 1 + deepSetPos(productElement(n)) + } + } + /** The initial, synthetic position. This is usually the union of all positioned children's * envelopes. */ @@ -661,9 +686,11 @@ object Trees { def forwardTo = arg } - trait WithoutType[-T >: Untyped] extends Tree[T] { + trait WithoutTypeOrPos[-T >: Untyped] extends Tree[T] { override def tpe: T @uncheckedVariance = NoType.asInstanceOf[T] override def withTypeUnchecked(tpe: Type) = this.asInstanceOf[ThisTree[Type]] + override def pos = NoPosition + override def setPos(pos: Position) = {} } /** Temporary class that results from translation of ModuleDefs @@ -672,7 +699,7 @@ object Trees { * a `transform(List[Tree])` call. */ case class Thicket[-T >: Untyped](trees: List[Tree[T]]) - extends Tree[T] with WithoutType[T] { + extends Tree[T] with WithoutTypeOrPos[T] { type ThisTree[-T >: Untyped] = Thicket[T] override def isEmpty: Boolean = trees.isEmpty override def toList: List[Tree[T]] = flatten(trees) @@ -680,7 +707,7 @@ object Trees { } class EmptyValDef[T >: Untyped] extends ValDef[T]( - Modifiers[T](Private), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutType[T] { + Modifiers[T](Private), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutTypeOrPos[T] { override def isEmpty: Boolean = true } |