aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/Trees.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/ast/Trees.scala')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala73
1 files changed, 54 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index ff44a48c5..57cbb7f8f 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -334,9 +334,9 @@ object Trees {
}
/** A ValDef or DefDef tree */
- trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] {
+ trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] with WithLazyField[Tree[T]] {
def tpt: Tree[T]
- def rhs: Tree[T]
+ def rhs: Tree[T] = forceIfLazy
}
// ----------- Tree case classes ------------------------------------
@@ -619,17 +619,22 @@ object Trees {
}
/** mods val name: tpt = rhs */
- case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], rhs: Tree[T])
+ case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: Any /*Tree[T] | Lazy[Tree[T]]*/)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = ValDef[T]
assert(isEmpty || tpt != genericEmptyTree)
+ protected def maybeLazy = preRhs
+ protected def maybeLazy_=(x: Any) = preRhs = x
}
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
- case class DefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])
+ case class DefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]],
+ vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: Any /*Tree[T] | Lazy[Tree[T]]*/)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = DefDef[T]
assert(tpt != genericEmptyTree)
+ protected def maybeLazy = preRhs
+ protected def maybeLazy_=(x: Any) = preRhs = x
}
/** mods class name template or
@@ -652,9 +657,12 @@ object Trees {
}
/** extends parents { self => body } */
- case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])
- extends DefTree[T] {
+ case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], private var preBody: Any /*List[Tree[T]] | Lazy[List[Tree]]]*/)
+ extends DefTree[T] with WithLazyField[List[Tree[T]]] {
type ThisTree[-T >: Untyped] = Template[T]
+ protected def maybeLazy = preBody
+ protected def maybeLazy_=(x: Any) = preBody = x
+ def body: List[Tree[T]] = forceIfLazy
}
/** import expr.selectors
@@ -746,6 +754,33 @@ object Trees {
if (buf != null) buf.toList else trees
}
+ // ----- Lazy trees and tree sequences
+
+ /** A tree that can have a lazy field
+ * The field is represented by some private `var` which is
+ * proxied by the `maybeLazy` accessors. Forcing the field will
+ * set the `var` to the underlying value.
+ */
+ trait WithLazyField[+T] {
+ protected def maybeLazy: Any
+ protected def maybeLazy_=(x: Any): Unit
+ def forceIfLazy: T = maybeLazy match {
+ case lzy: Lazy[T] =>
+ val x = lzy.complete
+ maybeLazy = x
+ x
+ case x: T @ unchecked => x
+ }
+ }
+
+ /** A base trait for lazy tree fields.
+ * These can be instantiated with Lazy instances which
+ * can delay tree construction until the field is first demanded.
+ */
+ trait Lazy[T] {
+ def complete: T
+ }
+
// ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
abstract class Instance[T >: Untyped <: Type] extends DotClass { inst =>
@@ -1114,16 +1149,16 @@ object Trees {
cpy.UnApply(tree)(transform(fun), transform(implicits), transform(patterns))
case EmptyValDef =>
tree
- case tree @ ValDef(name, tpt, rhs) =>
+ case tree @ ValDef(name, tpt, _) =>
val tpt1 = transform(tpt)
- val rhs1 = transform(rhs)
- cpy.ValDef(tree)(name, tpt1, rhs1)
- case tree @ DefDef(name, tparams, vparamss, tpt, rhs) =>
- cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs))
+ val rhs1 = transform(tree.rhs)
+ cpy.ValDef(tree)(name, transform(tpt1), transform(rhs1))
+ case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
+ cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(tree.rhs))
case tree @ TypeDef(name, rhs) =>
cpy.TypeDef(tree)(name, transform(rhs), tree.tparams)
- case Template(constr, parents, self, body) =>
- cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(body))
+ case tree @ Template(constr, parents, self, _) =>
+ cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(tree.body))
case Import(expr, selectors) =>
cpy.Import(tree)(transform(expr), selectors)
case PackageDef(pid, stats) =>
@@ -1213,14 +1248,14 @@ object Trees {
this(x, trees)
case UnApply(fun, implicits, patterns) =>
this(this(this(x, fun), implicits), patterns)
- case ValDef(name, tpt, rhs) =>
- this(this(x, tpt), rhs)
- case DefDef(name, tparams, vparamss, tpt, rhs) =>
- this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
+ case tree @ ValDef(name, tpt, _) =>
+ this(this(x, tpt), tree.rhs)
+ case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
+ this(this((this(x, tparams) /: vparamss)(apply), tpt), tree.rhs)
case TypeDef(name, rhs) =>
this(x, rhs)
- case Template(constr, parents, self, body) =>
- this(this(this(this(x, constr), parents), self), body)
+ case tree @ Template(constr, parents, self, _) =>
+ this(this(this(this(x, constr), parents), self), tree.body)
case Import(expr, selectors) =>
this(x, expr)
case PackageDef(pid, stats) =>