aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-04 11:29:00 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-04 11:29:00 +0100
commitab95d83444c6397f8859713dd6606602c77c8d23 (patch)
treefa490998a0ab2d72e4d86760417193a5e504374d /src/dotty
parent19b6784ef1cae9cd0af278c0c3afcee47c0a00ea (diff)
downloaddotty-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')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala37
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala8
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
6 files changed, 44 insertions, 9 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
}
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index 8fbd3502c..664655d7c 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -127,10 +127,16 @@ extends TyperState(reporter) {
override def withCheckingDisabled[T](op: => T)(implicit ctx: Context): T = {
val prev = enableChecking(false)
+ var thrown = false
try op
+ catch {
+ case ex: Throwable =>
+ thrown = true
+ throw ex
+ }
finally {
enableChecking(prev)
- checkConsistent
+ if (!thrown) checkConsistent
}
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 904e11399..305261213 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1944,6 +1944,8 @@ object Types {
*/
final class TypeVar(val origin: PolyParam, creatorState: TyperState, val pos: Position) extends UncachedProxyType with ValueType {
+ assert(pos.exists)
+
/** The permanent instance type of the the variable, or NoType is none is given yet */
private[core] var inst: Type = NoType
diff --git a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
index 669efcbef..b497ffe9c 100644
--- a/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
+++ b/src/dotty/tools/dotc/parsing/SymbolicXMLBuilder.scala
@@ -153,7 +153,7 @@ class SymbolicXMLBuilder(parser: Parser, preserveWS: Boolean)(implicit ctx: Cont
case EntityRef(s) => entityRef(pos, s)
}
ts.length match {
- case 0 => TypedSplice(tpd.ref(defn.NilModule))
+ case 0 => TypedSplice(tpd.ref(defn.NilModule) withPos pos)
case 1 => ts.head
case _ => makeXMLseq(pos, ts.toList)
}
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 6e1044281..36dee475a 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -301,7 +301,7 @@ trait Implicits { self: Typer =>
pt)(ctx.fresh.addMode(Mode.RestrictedInterpolation))
val generated1 = interpolateAndAdapt(generated, pt)
lazy val shadowing =
- typed(untpd.Ident(ref.name), ref)(nestedContext).tpe
+ typed(untpd.Ident(ref.name) withPos pos.toSynthetic, ref)(nestedContext).tpe
if (ctx.typerState.reporter.hasErrors) nonMatchingImplicit(ref)
else if (contextual && !(shadowing =:= ref)) shadowedImplicit(ref, shadowing)
else SearchSuccess(generated)(ref, ctx.typerState)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 14345a627..efb89cc4c 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1090,7 +1090,7 @@ class Typer extends Namer with Applications with Implicits {
}
tree match {
- case _: MemberDef | _: PackageDef | _: Import | _: WithoutType[_] => tree
+ case _: MemberDef | _: PackageDef | _: Import | _: WithoutTypeOrPos[_] => tree
case _ => tree.tpe.widen match {
case ErrorType =>
tree