aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-05-23 11:18:53 +0200
committerMartin Odersky <odersky@gmail.com>2013-05-23 11:18:53 +0200
commitdb39f1a5f5062f00e09e20a897e8f6d26e1e4193 (patch)
treef367993fb537210f2b297c7ec8ec0be857b3603b
parent66fe5aaba6d5f7ae3694bcc942487cd1fe00c533 (diff)
downloaddotty-db39f1a5f5062f00e09e20a897e8f6d26e1e4193.tar.gz
dotty-db39f1a5f5062f00e09e20a897e8f6d26e1e4193.tar.bz2
dotty-db39f1a5f5062f00e09e20a897e8f6d26e1e4193.zip
Moved TempTrees to Trees, get automatically flattened in transforms.
-rw-r--r--src/dotty/tools/dotc/ast/CheckTrees.scala2
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala54
-rw-r--r--src/dotty/tools/dotc/ast/TypedTrees.scala9
-rw-r--r--test/test/showTree.scala8
4 files changed, 41 insertions, 32 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala
index c10a2dacb..881980d4a 100644
--- a/src/dotty/tools/dotc/ast/CheckTrees.scala
+++ b/src/dotty/tools/dotc/ast/CheckTrees.scala
@@ -236,7 +236,7 @@ object CheckTrees {
check(annot.isInstantiation)
check(annot.symbol.owner.isSubClass(defn.AnnotationClass))
check(arg.isValueType || arg.isValue)
- case tpd.EmptyTree =>
+ case EmptyTree() =>
case SharedTree(shared) =>
check(shared.isType || shared.isTerm)
}
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index dd4567c50..5e3509441 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -612,8 +612,33 @@ object Trees {
def forwardTo: Tree[T] = shared
}
+ /** Temporary class that results from translation of ModuleDefs
+ * (and possibly other statements).
+ * The contained trees will be integrated when transformed with
+ * a `transform(List[Tree])` call.
+ */
+ case class TempTrees[T >: Untyped](trees: List[Tree[T]]) extends Tree[T] {
+ override def tpe: T = unsupported("tpe")
+ }
+
// ----- Auxiliary creation methods ------------------
+ /** Integrates nested TempTrees in given list of trees */
+ def flatten[T >: Untyped](trees: List[Tree[T]]): List[Tree[T]] =
+ if (trees exists isTempTrees)
+ trees flatMap {
+ case TempTrees(ts) => ts
+ case t => t :: Nil
+ }
+ else trees
+
+ def combine[T >: Untyped](trees: List[Tree[T]]): Tree[T] = flatten(trees) match {
+ case tree :: Nil => tree
+ case ts => TempTrees[T](ts)
+ }
+
+ private val isTempTrees: Any => Boolean = (_.isInstanceOf[TempTrees[_]])
+
def Block[T >: Untyped](stat: Tree[T], expr: Tree[T]): Block[T] =
Block(stat :: Nil, expr)
@@ -681,6 +706,7 @@ object Trees {
type Annotated = Trees.Annotated[T]
type EmptyTree = Trees.EmptyTree[T]
type SharedTree = Trees.SharedTree[T]
+ type TempTrees = Trees.TempTrees[T]
protected implicit def pos(implicit ctx: Context): Position = ctx.position
@@ -688,30 +714,6 @@ object Trees {
def Parameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers()): ValDef =
ValDef(mods | Param, pname, tpe, EmptyTree())
-
- /** Temporary class that results from translation of ModuleDefs
- * (and possibly other statements).
- * The contained trees will be integrated in enclosing Blocks or Templates
- */
- case class TempTrees(trees: List[Tree]) extends Tree {
- override def tpe: T = unsupported("tpe")
- }
-
- /** Integrates nested TempTrees in given list of trees */
- def flatten(trees: List[Tree]): List[Tree] =
- if (trees exists isTempTrees)
- trees flatMap {
- case TempTrees(ts) => ts
- case t => t :: Nil
- }
- else trees
-
- def combine(trees: List[Tree]): Tree = flatten(trees) match {
- case tree :: Nil => tree
- case ts => TempTrees(ts)
- }
-
- private val isTempTrees: Tree => Boolean = (_.isInstanceOf[TempTrees])
}
// ----- Helper functions and classes ---------------------------------------
@@ -974,7 +976,7 @@ object Trees {
tree, c, plugins)
}
def transform(trees: List[Tree[T]], c: C): List[Tree[T]] =
- trees mapConserve (transform(_, c))
+ flatten(trees mapConserve (transform(_, c)))
def transformSub(tree: Tree[T], c: C): tree.ThisTree[T] =
transform(tree, c).asInstanceOf[tree.ThisTree[T]]
def transformSub[TT <: Tree[T]](trees: List[TT], c: C): List[TT] =
@@ -1121,7 +1123,7 @@ object Trees {
}
}
def transform(trees: List[Tree[T]]): List[Tree[T]] =
- trees mapConserve (transform(_))
+ flatten(trees mapConserve (transform(_)))
def transformSub(tree: Tree[T]): tree.ThisTree[T] =
transform(tree).asInstanceOf[tree.ThisTree[T]]
def transformSub[TT <: Tree[T]](trees: List[TT]): List[TT] =
diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala
index 266664cce..e5e0c99fd 100644
--- a/src/dotty/tools/dotc/ast/TypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/TypedTrees.scala
@@ -256,11 +256,10 @@ object tpd extends Trees.Instance[Type] {
*
* gets expanded to
*
- * <module> lazy val obj = {
- * class obj$ extends parents { this: obj.type => decls }
- * new obj$
- * }
+ * <module> lazy val obj = new obj$
+ * <module> class obj$ extends parents { this: obj.type => decls }
*
+ * (The following no longer applies:
* What's interesting here is that the block is well typed
* (because class obj$ is hoistable), but the type of the `obj` val is
* not expressible. What needs to happen in general when
@@ -275,7 +274,7 @@ object tpd extends Trees.Instance[Type] {
*
* On the other hand, for method result type inference, if the type of
* the RHS of a method contains a class owned by the method, this would be
- * an error.
+ * an error.)
*/
def ModuleDef(sym: TermSymbol, body: List[Tree])(implicit ctx: Context): tpd.TempTrees = {
val modcls = sym.moduleClass.asClass
diff --git a/test/test/showTree.scala b/test/test/showTree.scala
index b9b68ed19..546a6a357 100644
--- a/test/test/showTree.scala
+++ b/test/test/showTree.scala
@@ -3,10 +3,18 @@ import dotty.tools.dotc.ast.untpd._
object showTree extends ParserTest {
+ object DeSugar extends TreeTransformer {
+ override def transform(tree: Tree) = desugar(tree, Mode.Expr) match {
+ case PostfixOp(od, op) => PostfixOp(transform(od), op)
+ case tree1 => super.transform(tree1)
+ }
+ }
+
def main(args: Array[String]): Unit = {
for (arg <- args) {
val tree: Tree = parse(arg)
println("result = "+tree.show)
+ println("desugared = "+DeSugar.transform(tree).show)
}
}
} \ No newline at end of file