@@ -407,12 +407,12 @@ object Trees {
407407 }
408408
409409 /** A ValDef or DefDef tree */
410- abstract class ValOrDefDef [+ T <: Untyped ](implicit @ constructorOnly src : SourceFile ) extends MemberDef [T ] with WithLazyField [ Tree [ T ]] {
410+ abstract class ValOrDefDef [+ T <: Untyped ](implicit @ constructorOnly src : SourceFile ) extends MemberDef [T ], WithLazyFields {
411411 type ThisTree [+ T <: Untyped ] <: ValOrDefDef [T ]
412412 def name : TermName
413413 def tpt : Tree [T ]
414- def unforcedRhs : LazyTree [T ] = unforced
415- def rhs (using Context ): Tree [T ] = forceIfLazy
414+ def unforcedRhs : LazyTree [T ]
415+ def rhs (using Context ): Tree [T ]
416416 }
417417
418418 trait ValOrTypeDef [+ T <: Untyped ] extends MemberDef [T ]:
@@ -808,8 +808,10 @@ object Trees {
808808 extends ValOrDefDef [T ], ValOrTypeDef [T ] {
809809 type ThisTree [+ T <: Untyped ] = ValDef [T ]
810810 assert(isEmpty || (tpt ne genericEmptyTree))
811- def unforced : LazyTree [T ] = preRhs
812- protected def force (x : Tree [T @ uncheckedVariance]): Unit = preRhs = x
811+
812+ def unforcedRhs : LazyTree [T ] = preRhs
813+ def forceFields ()(using Context ): Unit = preRhs = force(preRhs)
814+ def rhs (using Context ): Tree [T ] = { forceFields(); preRhs.asInstanceOf [Tree [T ]] }
813815 }
814816
815817 /** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
@@ -818,8 +820,10 @@ object Trees {
818820 extends ValOrDefDef [T ] {
819821 type ThisTree [+ T <: Untyped ] = DefDef [T ]
820822 assert(tpt ne genericEmptyTree)
821- def unforced : LazyTree [T ] = preRhs
822- protected def force (x : Tree [T @ uncheckedVariance]): Unit = preRhs = x
823+
824+ def unforcedRhs : LazyTree [T ] = preRhs
825+ def forceFields ()(using Context ): Unit = preRhs = force(preRhs)
826+ def rhs (using Context ): Tree [T ] = { forceFields(); preRhs.asInstanceOf [Tree [T ]] }
823827
824828 def leadingTypeParams (using Context ): List [TypeDef [T ]] = paramss match
825829 case (tparams @ (tparam : TypeDef [_]) :: _) :: _ => tparams.asInstanceOf [List [TypeDef [T ]]]
@@ -855,16 +859,20 @@ object Trees {
855859 * if this is of class untpd.DerivingTemplate.
856860 * Typed templates only have parents.
857861 */
858- case class Template [+ T <: Untyped ] private [ast] (constr : DefDef [T ], parentsOrDerived : List [ Tree [ T ] ], self : ValDef [T ], private var preBody : LazyTreeList [T ])(implicit @ constructorOnly src : SourceFile )
859- extends DefTree [T ] with WithLazyField [ List [ Tree [ T ]]] {
862+ case class Template [+ T <: Untyped ] private [ast] (constr : DefDef [T ], private var preParentsOrDerived : LazyTreeList [ T ], self : ValDef [T ], private var preBody : LazyTreeList [T ])(implicit @ constructorOnly src : SourceFile )
863+ extends DefTree [T ] with WithLazyFields {
860864 type ThisTree [+ T <: Untyped ] = Template [T ]
861- def unforcedBody : LazyTreeList [T ] = unforced
862- def unforced : LazyTreeList [T ] = preBody
863- protected def force (x : List [Tree [T @ uncheckedVariance]]): Unit = preBody = x
864- def body (using Context ): List [Tree [T ]] = forceIfLazy
865865
866- def parents : List [Tree [T ]] = parentsOrDerived // overridden by DerivingTemplate
867- def derived : List [untpd.Tree ] = Nil // overridden by DerivingTemplate
866+ def forceFields ()(using Context ): Unit =
867+ preParentsOrDerived = force(preParentsOrDerived)
868+ preBody = force(preBody)
869+
870+ def unforcedBody : LazyTreeList [T ] = preBody
871+ def body (using Context ): List [Tree [T ]] = { forceFields(); preBody.asInstanceOf [List [Tree [T ]]] }
872+ def parentsOrDerived (using Context ): List [Tree [T ]] = { forceFields(); preParentsOrDerived.asInstanceOf [List [Tree [T ]]] }
873+
874+ def parents (using Context ): List [Tree [T ]] = parentsOrDerived // overridden by DerivingTemplate
875+ def derived : List [untpd.Tree ] = Nil // overridden by DerivingTemplate
868876 }
869877
870878
@@ -1008,30 +1016,27 @@ object Trees {
10081016
10091017 // ----- Lazy trees and tree sequences
10101018
1011- /** A tree that can have a lazy field
1012- * The field is represented by some private `var` which is
1013- * accessed by `unforced` and `force`. Forcing the field will
1014- * set the `var` to the underlying value.
1015- */
1016- trait WithLazyField [+ T <: AnyRef ] {
1017- def unforced : T | Lazy [T ]
1018- protected def force (x : T @ uncheckedVariance): Unit
1019- def forceIfLazy (using Context ): T = unforced match {
1020- case lzy : Lazy [T @ unchecked] =>
1021- val x = lzy.complete
1022- force(x)
1023- x
1024- case x : T @ unchecked => x
1025- }
1026- }
1027-
10281019 /** A base trait for lazy tree fields.
10291020 * These can be instantiated with Lazy instances which
10301021 * can delay tree construction until the field is first demanded.
10311022 */
1032- trait Lazy [+ T <: AnyRef ] {
1023+ trait Lazy [+ T <: AnyRef ]:
10331024 def complete (using Context ): T
1034- }
1025+
1026+ /** A tree that can have a lazy fields.
1027+ * Such fields are variables of type `T | Lazy[T]`, for some tyope `T`.
1028+ */
1029+ trait WithLazyFields :
1030+
1031+ /** If `x` is lazy, computes the underlying value */
1032+ protected def force [T <: AnyRef ](x : T | Lazy [T ])(using Context ): T = x match
1033+ case x : Lazy [T ] @ unchecked => x.complete
1034+ case x : T @ unchecked => x
1035+
1036+ /** Assigns all lazy fields their underlying non-lazy value. */
1037+ def forceFields ()(using Context ): Unit
1038+
1039+ end WithLazyFields
10351040
10361041 // ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
10371042
@@ -1355,7 +1360,7 @@ object Trees {
13551360 DefDef (tree : Tree )(name, paramss, tpt, rhs)
13561361 def TypeDef (tree : TypeDef )(name : TypeName = tree.name, rhs : Tree = tree.rhs)(using Context ): TypeDef =
13571362 TypeDef (tree : Tree )(name, rhs)
1358- def Template (tree : Template )(constr : DefDef = tree.constr, parents : List [Tree ] = tree.parents, derived : List [untpd.Tree ] = tree.derived, self : ValDef = tree.self, body : LazyTreeList = tree.unforcedBody)( using Context ): Template =
1363+ def Template (tree : Template )(using Context )( constr : DefDef = tree.constr, parents : List [Tree ] = tree.parents, derived : List [untpd.Tree ] = tree.derived, self : ValDef = tree.self, body : LazyTreeList = tree.unforcedBody): Template =
13591364 Template (tree : Tree )(constr, parents, derived, self, body)
13601365 def Hole (tree : Hole )(isTerm : Boolean = tree.isTerm, idx : Int = tree.idx, args : List [Tree ] = tree.args, content : Tree = tree.content, tpt : Tree = tree.tpt)(using Context ): Hole =
13611366 Hole (tree : Tree )(isTerm, idx, args, content, tpt)
@@ -1618,8 +1623,8 @@ object Trees {
16181623 inContext(localCtx(tree)) {
16191624 this (x, rhs)
16201625 }
1621- case tree @ Template (constr, parents , self, _) if tree.derived.isEmpty =>
1622- this (this (this (this (x, constr), parents), self), tree.body)
1626+ case tree @ Template (constr, _ , self, _) if tree.derived.isEmpty =>
1627+ this (this (this (this (x, constr), tree. parents), self), tree.body)
16231628 case Import (expr, _) =>
16241629 this (x, expr)
16251630 case Export (expr, _) =>
0 commit comments