@@ -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
@@ -48,16 +52,32 @@ object Annotations {
48
52
}
49
53
50
54
abstract class LazyAnnotation extends Annotation {
51
- override def symbol (implicit ctx : Context ): Symbol
52
- def complete (implicit ctx : Context ): Tree
53
-
54
- private var myTree : Tree = null
55
- def tree (implicit ctx : Context ): Tree = {
56
- if (myTree == null ) myTree = complete(ctx)
57
- myTree
58
- }
55
+ protected var mySym : Symbol | (Context => Symbol )
56
+ override def symbol (using ctx : Context ): Symbol =
57
+ assert(mySym != null )
58
+ mySym match {
59
+ case symFn : (Context => Symbol ) @ unchecked =>
60
+ mySym = null
61
+ mySym = symFn(ctx)
62
+ case sym : Symbol if sym.defRunId != ctx.runId =>
63
+ mySym = sym.denot.current.symbol
64
+ case _ =>
65
+ }
66
+ mySym.asInstanceOf [Symbol ]
67
+
68
+ protected var myTree : Tree | (Context => Tree )
69
+ def tree (using ctx : Context ): Tree =
70
+ assert(myTree != null )
71
+ myTree match {
72
+ case treeFn : (Context => Tree ) @ unchecked =>
73
+ myTree = null
74
+ myTree = treeFn(ctx)
75
+ case _ =>
76
+ }
77
+ myTree.asInstanceOf [Tree ]
59
78
60
- override def isEvaluated : Boolean = myTree != null
79
+ override def isEvaluating : Boolean = myTree == null
80
+ override def isEvaluated : Boolean = myTree.isInstanceOf [Tree ]
61
81
}
62
82
63
83
/** An annotation indicating the body of a right-hand side,
@@ -72,24 +92,31 @@ object Annotations {
72
92
override def ensureCompleted (implicit ctx : Context ): Unit = ()
73
93
}
74
94
75
- case class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
95
+ class ConcreteBodyAnnotation (body : Tree ) extends BodyAnnotation {
76
96
def tree (implicit ctx : Context ): Tree = body
77
97
}
78
98
79
- case class LazyBodyAnnotation ( private var bodyExpr : Context => Tree ) extends BodyAnnotation {
80
- // TODO: Make `bodyExpr` an IFT once #6865 os in bootstrap
81
- private var evaluated = false
82
- private var myBody : Tree = _
83
- def tree ( implicit ctx : Context ) : Tree = {
84
- if (evaluated) assert(myBody != null )
85
- else {
86
- evaluated = true
87
- myBody = bodyExpr (ctx)
88
- bodyExpr = null
99
+ abstract class LazyBodyAnnotation extends BodyAnnotation {
100
+ // Copy-pasted from LazyAnnotation to avoid having to turn it into a trait
101
+ protected var myTree : Tree | ( Context => Tree )
102
+ def tree ( using ctx : Context ) : Tree =
103
+ assert(myTree != null )
104
+ myTree match {
105
+ case treeFn : ( Context => Tree ) @ unchecked =>
106
+ myTree = null
107
+ myTree = treeFn (ctx)
108
+ case _ =>
89
109
}
90
- myBody
91
- }
92
- override def isEvaluated : Boolean = evaluated
110
+ myTree.asInstanceOf [Tree ]
111
+
112
+ override def isEvaluating : Boolean = myTree == null
113
+ override def isEvaluated : Boolean = myTree.isInstanceOf [Tree ]
114
+ }
115
+
116
+ object LazyBodyAnnotation {
117
+ def apply (bodyFn : Context ?=> Tree ): LazyBodyAnnotation =
118
+ new LazyBodyAnnotation :
119
+ protected var myTree : Tree | (Context => Tree ) = ctx => bodyFn(using ctx)
93
120
}
94
121
95
122
object Annotation {
@@ -120,23 +147,15 @@ object Annotations {
120
147
/** Create an annotation where the tree is computed lazily. */
121
148
def deferred (sym : Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
122
149
new LazyAnnotation {
123
- override def symbol ( implicit ctx : Context ) : Symbol = sym
124
- def complete ( implicit ctx : Context ) = treeFn( using ctx)
150
+ protected var myTree : Tree | ( Context => Tree ) = ctx => treeFn( using ctx)
151
+ protected var mySym : Symbol | ( Context => Symbol ) = sym
125
152
}
126
153
127
154
/** Create an annotation where the symbol and the tree are computed lazily. */
128
- def deferredSymAndTree (symf : Context ?=> Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
155
+ def deferredSymAndTree (symFn : Context ?=> Symbol )(treeFn : Context ?=> Tree )(implicit ctx : Context ): Annotation =
129
156
new LazyAnnotation {
130
- private var mySym : Symbol = _
131
-
132
- override def symbol (implicit ctx : Context ): Symbol = {
133
- if (mySym == null || mySym.defRunId != ctx.runId) {
134
- mySym = symf(using ctx)
135
- assert(mySym != null )
136
- }
137
- mySym
138
- }
139
- def complete (implicit ctx : Context ) = treeFn(using ctx)
157
+ protected var mySym : Symbol | (Context => Symbol ) = ctx => symFn(using ctx)
158
+ protected var myTree : Tree | (Context => Tree ) = ctx => treeFn(using ctx)
140
159
}
141
160
142
161
def deferred (atp : Type , args : List [Tree ])(implicit ctx : Context ): Annotation =
0 commit comments