@@ -35,6 +35,10 @@ object Annotations {
35
35
def argumentConstant (i : Int )(implicit ctx : Context ): Option [Constant ] =
36
36
for (ConstantType (c) <- argument(i) map (_.tpe)) yield c
37
37
38
+ /** The tree evaluaton is in progress. */
39
+ def isEvaluating : Boolean = false
40
+
41
+ /** The tree evaluation has finished. */
38
42
def isEvaluated : Boolean = true
39
43
40
44
def ensureCompleted (implicit ctx : Context ): Unit = tree
@@ -74,6 +78,7 @@ object Annotations {
74
78
}
75
79
myTree.asInstanceOf [Tree ]
76
80
81
+ override def isEvaluating : Boolean = myTree == null
77
82
override def isEvaluated : Boolean = myTree.isInstanceOf [Tree ]
78
83
}
79
84
@@ -89,24 +94,32 @@ object Annotations {
89
94
override def ensureCompleted (implicit ctx : Context ): Unit = ()
90
95
}
91
96
92
- case class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
97
+ class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
93
98
def tree (implicit ctx : Context ): Tree = body
94
99
}
95
100
96
- case class LazyBodyAnnotation (private var bodyExpr : Context => Tree ) extends BodyAnnotation {
97
- // TODO: Make `bodyExpr` an IFT once #6865 os in bootstrap
98
- private var evaluated = false
99
- private var myBody : Tree = _
100
- def tree (implicit ctx : Context ): Tree = {
101
- if (evaluated) assert(myBody != null )
102
- else {
103
- evaluated = true
104
- myBody = bodyExpr(ctx)
105
- bodyExpr = null
101
+ abstract class LazyBodyAnnotation extends BodyAnnotation {
102
+ // Copy-pasted from LazyAnnotation to avoid having to turn it into a trait
103
+ protected var myTree : Tree | (Context => Tree )
104
+ def tree (using ctx : Context ): Tree =
105
+ assert(myTree != null )
106
+ myTree match {
107
+ case treeFn : (Context => Tree ) @ unchecked =>
108
+ val fn = treeFn
109
+ myTree = null
110
+ myTree = fn(ctx)
111
+ case _ =>
106
112
}
107
- myBody
108
- }
109
- override def isEvaluated : Boolean = evaluated
113
+ myTree.asInstanceOf [Tree ]
114
+
115
+ override def isEvaluating : Boolean = myTree == null
116
+ override def isEvaluated : Boolean = myTree.isInstanceOf [Tree ]
117
+ }
118
+
119
+ object LazyBodyAnnotation {
120
+ def apply (bodyFn : Context ?=> Tree ): LazyBodyAnnotation =
121
+ new LazyBodyAnnotation :
122
+ protected var myTree : Tree | (Context => Tree ) = ctx => bodyFn(using ctx)
110
123
}
111
124
112
125
object Annotation {
0 commit comments