From db39f1a5f5062f00e09e20a897e8f6d26e1e4193 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 23 May 2013 11:18:53 +0200 Subject: Moved TempTrees to Trees, get automatically flattened in transforms. --- src/dotty/tools/dotc/ast/CheckTrees.scala | 2 +- src/dotty/tools/dotc/ast/Trees.scala | 54 ++++++++++++++++--------------- src/dotty/tools/dotc/ast/TypedTrees.scala | 9 +++--- 3 files changed, 33 insertions(+), 32 deletions(-) (limited to 'src/dotty') 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 * - * lazy val obj = { - * class obj$ extends parents { this: obj.type => decls } - * new obj$ - * } + * lazy val obj = new obj$ + * 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 -- cgit v1.2.3