diff options
author | Martin Odersky <odersky@gmail.com> | 2013-05-23 11:18:53 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-05-23 11:18:53 +0200 |
commit | db39f1a5f5062f00e09e20a897e8f6d26e1e4193 (patch) | |
tree | f367993fb537210f2b297c7ec8ec0be857b3603b | |
parent | 66fe5aaba6d5f7ae3694bcc942487cd1fe00c533 (diff) | |
download | dotty-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.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 54 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/TypedTrees.scala | 9 | ||||
-rw-r--r-- | test/test/showTree.scala | 8 |
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 |