aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/ast')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala32
-rw-r--r--src/dotty/tools/dotc/ast/NavigateAST.scala9
-rw-r--r--src/dotty/tools/dotc/ast/Positioned.scala64
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala2
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala4
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala2
6 files changed, 78 insertions, 35 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 7011d13a0..36cae6378 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -505,7 +505,7 @@ object desugar {
val clsTmpl = cpy.Template(tmpl)(self = clsSelf, body = tmpl.body)
val cls = TypeDef(clsName, clsTmpl)
.withMods(mods.toTypeFlags & RetainedModuleClassFlags | ModuleClassCreationFlags)
- Thicket(modul, classDef(cls))
+ Thicket(modul, classDef(cls).withPos(mdef.pos))
}
}
@@ -516,7 +516,7 @@ object desugar {
def patDef(pdef: PatDef)(implicit ctx: Context): Tree = {
val PatDef(mods, pats, tpt, rhs) = pdef
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
- flatTree(pats1 map (makePatDef(mods, _, rhs)))
+ flatTree(pats1 map (makePatDef(pdef, mods, _, rhs)))
}
/** If `pat` is a variable pattern,
@@ -534,9 +534,9 @@ object desugar {
* If the original pattern variable carries a type annotation, so does the corresponding
* ValDef or DefDef.
*/
- def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
+ def makePatDef(original: Tree, mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
case VarPattern(named, tpt) =>
- derivedValDef(named, tpt, rhs, mods)
+ derivedValDef(original, named, tpt, rhs, mods)
case _ =>
val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
val vars = getVariables(pat)
@@ -553,7 +553,7 @@ object desugar {
case Nil =>
matchExpr
case (named, tpt) :: Nil =>
- derivedValDef(named, tpt, matchExpr, mods)
+ derivedValDef(original, named, tpt, matchExpr, mods)
case _ =>
val tmpName = ctx.freshName().toTermName
val patMods = mods & (AccessFlags | Lazy) | Synthetic
@@ -564,8 +564,8 @@ object desugar {
val restDefs =
for (((named, tpt), n) <- vars.zipWithIndex)
yield
- if (mods is Lazy) derivedDefDef(named, tpt, selector(n), mods &~ Lazy)
- else derivedValDef(named, tpt, selector(n), mods)
+ if (mods is Lazy) derivedDefDef(original, named, tpt, selector(n), mods &~ Lazy)
+ else derivedValDef(original, named, tpt, selector(n), mods)
flatTree(firstDef :: restDefs)
}
}
@@ -663,14 +663,18 @@ object desugar {
def makeAnnotated(cls: Symbol, tree: Tree)(implicit ctx: Context) =
Annotated(untpd.New(untpd.TypeTree(cls.typeRef), Nil), tree)
- private def derivedValDef(named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit ctx: Context) = {
- val vdef = ValDef(named.name.asTermName, tpt, rhs).withMods(mods).withPos(named.pos)
+ private def derivedValDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers)(implicit ctx: Context) = {
+ val vdef = ValDef(named.name.asTermName, tpt, rhs)
+ .withMods(mods)
+ .withPos(original.pos.withPoint(named.pos.start))
val mayNeedSetter = valDef(vdef)
mayNeedSetter
}
- private def derivedDefDef(named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers) =
- DefDef(named.name.asTermName, Nil, Nil, tpt, rhs).withMods(mods).withPos(named.pos)
+ private def derivedDefDef(original: Tree, named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers) =
+ DefDef(named.name.asTermName, Nil, Nil, tpt, rhs)
+ .withMods(mods)
+ .withPos(original.pos.withPoint(named.pos.start))
/** Main desugaring method */
def apply(tree: Tree)(implicit ctx: Context): Tree = {
@@ -760,7 +764,7 @@ object desugar {
*/
def makeLambda(pat: Tree, body: Tree): Tree = pat match {
case VarPattern(named, tpt) =>
- Function(derivedValDef(named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
+ Function(derivedValDef(pat, named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
case _ =>
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil, unchecked = false)
}
@@ -863,7 +867,7 @@ object desugar {
val rhss = valeqs map { case GenAlias(_, rhs) => rhs }
val (defpat0, id0) = makeIdPat(pat)
val (defpats, ids) = (pats map makeIdPat).unzip
- val pdefs = (defpats, rhss).zipped map (makePatDef(Modifiers(), _, _))
+ val pdefs = (valeqs, defpats, rhss).zipped.map(makePatDef(_, Modifiers(), _, _))
val rhs1 = makeFor(nme.map, nme.flatMap, GenFrom(defpat0, rhs) :: Nil, Block(pdefs, makeTuple(id0 :: ids)))
val allpats = pat :: pats
val vfrom1 = new IrrefutableGenFrom(makeTuple(allpats), rhs1)
@@ -946,7 +950,7 @@ object desugar {
makeFor(nme.map, nme.flatMap, enums, body) orElse tree
case PatDef(mods, pats, tpt, rhs) =>
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
- flatTree(pats1 map (makePatDef(mods, _, rhs)))
+ flatTree(pats1 map (makePatDef(tree, mods, _, rhs)))
case ParsedTry(body, handler, finalizer) =>
handler match {
case Match(EmptyTree, cases) => Try(body, cases, finalizer)
diff --git a/src/dotty/tools/dotc/ast/NavigateAST.scala b/src/dotty/tools/dotc/ast/NavigateAST.scala
index 2b11f81f3..33aa87d8e 100644
--- a/src/dotty/tools/dotc/ast/NavigateAST.scala
+++ b/src/dotty/tools/dotc/ast/NavigateAST.scala
@@ -19,10 +19,9 @@ object NavigateAST {
case _ =>
val loosePath = untypedPath(tree, exactMatch = false)
throw new
- Error(i"""no untyped tree for $tree, pos = ${tree.pos}, envelope = ${tree.envelope}
+ Error(i"""no untyped tree for $tree, pos = ${tree.pos}
|best matching path =\n$loosePath%\n====\n%
- |path positions = ${loosePath.map(_.pos)}
- |path envelopes = ${loosePath.map(_.envelope)}""")
+ |path positions = ${loosePath.map(_.pos)}""")
}
/** The reverse path of untyped trees starting with a tree that closest matches
@@ -40,7 +39,7 @@ object NavigateAST {
def untypedPath(tree: tpd.Tree, exactMatch: Boolean = false)(implicit ctx: Context): List[Positioned] =
tree match {
case tree: MemberDef[_] =>
- untypedPath(tree.envelope) match {
+ untypedPath(tree.pos) match {
case path @ (last: DefTree[_]) :: _ => path
case path if !exactMatch => path
case _ => Nil
@@ -76,7 +75,7 @@ object NavigateAST {
path
}
def singlePath(p: Positioned, path: List[Positioned]): List[Positioned] =
- if (p.envelope contains pos) childPath(p.productIterator, p :: path)
+ if (p.pos contains pos) childPath(p.productIterator, p :: path)
else path
singlePath(from, Nil)
}
diff --git a/src/dotty/tools/dotc/ast/Positioned.scala b/src/dotty/tools/dotc/ast/Positioned.scala
index e7f5de591..ab9c06ca1 100644
--- a/src/dotty/tools/dotc/ast/Positioned.scala
+++ b/src/dotty/tools/dotc/ast/Positioned.scala
@@ -3,6 +3,10 @@ package ast
import util.Positions._
import util.DotClass
+import core.Contexts.Context
+import core.Decorators._
+import core.Flags.JavaDefined
+import core.StdNames.nme
/** A base class for things that have positions (currently: modifiers and trees)
*/
@@ -16,7 +20,7 @@ abstract class Positioned extends DotClass with Product {
*/
def pos: Position = curPos
- /** Destructively update `curPos` to given position. Also, set any missing
+ /** Destructively update `curPos` to given position. Also, set any missing
* positions in children.
*/
protected def setPos(pos: Position): Unit = {
@@ -24,11 +28,6 @@ abstract class Positioned extends DotClass with Product {
if (pos.exists) setChildPositions(pos.toSynthetic)
}
- /** The envelope containing the item in its entirety. Envelope is different from
- * `pos` for definitions (instances of MemberDef).
- */
- def envelope: Position = pos.toSynthetic
-
/** A positioned item like this one with the position set to `pos`.
* if the positioned item is source-derived, a clone is returned.
* If the positioned item is synthetic, the position is updated
@@ -106,8 +105,7 @@ abstract class Positioned extends DotClass with Product {
}
}
- /** The initial, synthetic position. This is usually the union of all positioned children's
- * envelopes.
+ /** The initial, synthetic position. This is usually the union of all positioned children's positions.
*/
protected def initialPos: Position = {
var n = productArity
@@ -115,7 +113,7 @@ abstract class Positioned extends DotClass with Product {
while (n > 0) {
n -= 1
productElement(n) match {
- case p: Positioned => pos = pos union p.envelope
+ case p: Positioned => pos = pos union p.pos
case xs: List[_] => pos = unionPos(pos, xs)
case _ =>
}
@@ -124,7 +122,7 @@ abstract class Positioned extends DotClass with Product {
}
private def unionPos(pos: Position, xs: List[_]): Position = xs match {
- case (p: Positioned) :: xs1 => unionPos(pos union p.envelope, xs1)
+ case (p: Positioned) :: xs1 => unionPos(pos union p.pos, xs1)
case _ => pos
}
@@ -138,7 +136,7 @@ abstract class Positioned extends DotClass with Product {
false
}
(this eq that) ||
- (this.envelope contains that.pos) && {
+ (this.pos contains that.pos) && {
var n = productArity
var found = false
while (n > 0 && !found) {
@@ -148,4 +146,48 @@ abstract class Positioned extends DotClass with Product {
found
}
}
+
+ /** Check that all positioned items in this tree satisfy the following conditions:
+ * - Parent positions contain child positions
+ * - If item is a non-empty tree, it has a position
+ */
+ def checkPos(complete: Boolean)(implicit ctx: Context): Unit = try {
+ import untpd._
+ def check(p: Any): Unit = p match {
+ case p: Positioned =>
+ assert(pos contains p.pos,
+ s"""position error, parent position does not contain child positon
+ |parent = $this,
+ |parent position = $pos,
+ |child = $p,
+ |child position = ${p.pos}""".stripMargin)
+ p match {
+ case tree: Tree if !tree.isEmpty =>
+ assert(tree.pos.exists,
+ s"position error: position not set for $tree # ${tree.uniqueId}")
+ case _ =>
+ }
+ p.checkPos(complete)
+ case xs: List[_] =>
+ xs.foreach(check)
+ case _ =>
+ }
+ this match {
+ case tree: DefDef if tree.name == nme.CONSTRUCTOR && tree.mods.is(JavaDefined) =>
+ // Special treatment for constructors coming from Java:
+ // Leave out tparams, they are copied with wrong positions from parent class
+ check(tree.mods)
+ check(tree.vparamss)
+ case _ =>
+ var n = productArity
+ while (n > 0) {
+ n -= 1
+ check(productElement(n))
+ }
+ }
+ } catch {
+ case ex: AssertionError =>
+ println(i"error while checking $this")
+ throw ex
+ }
}
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 7c3f7f385..6c371abc1 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -480,7 +480,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
require(sym.pos.exists)
object accum extends TreeAccumulator[List[Tree]] {
def apply(x: List[Tree], tree: Tree)(implicit ctx: Context): List[Tree] = {
- if (tree.envelope.contains(sym.pos))
+ if (tree.pos.contains(sym.pos))
if (definedSym(tree) == sym) tree :: x
else {
val x1 = foldOver(x, tree)
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index cf11c27fa..4ba4eda0a 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -341,8 +341,6 @@ object Trees {
}
protected def setMods(mods: Modifiers[T @uncheckedVariance]) = myMods = mods
-
- override def envelope: Position = rawMods.pos.union(pos).union(initialPos)
}
/** A ValDef or DefDef tree */
@@ -619,7 +617,6 @@ object Trees {
type ThisTree[-T >: Untyped] = Bind[T]
override def isType = name.isTypeName
override def isTerm = name.isTermName
- override def envelope: Position = pos union initialPos
}
/** tree_1 | ... | tree_n */
@@ -740,6 +737,7 @@ object Trees {
val newTrees = trees.map(_.withPos(pos))
new Thicket[T](newTrees).asInstanceOf[this.type]
}
+ override def pos = (NoPosition /: trees) ((pos, t) => pos union t.pos)
override def foreachInThicket(op: Tree[T] => Unit): Unit =
trees foreach (_.foreachInThicket(op))
}
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index 6bbb76b89..4e18b1d5c 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -258,7 +258,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
implicit class UntypedTreeDecorator(val self: Tree) extends AnyVal {
def locateEnclosing(base: List[Tree], pos: Position): List[Tree] = {
def encloses(elem: Any) = elem match {
- case t: Tree => t.envelope contains pos
+ case t: Tree => t.pos contains pos
case _ => false
}
base.productIterator find encloses match {