@@ -13,23 +13,20 @@ import core.NameKinds.TempResultName
13
13
import core .Constants ._
14
14
import util .Store
15
15
import dotty .tools .uncheckedNN
16
+ import ast .tpd .*
17
+ import compiletime .uninitialized
16
18
17
19
/** This phase translates variables that are captured in closures to
18
20
* heap-allocated refs.
19
21
*/
20
22
class CapturedVars extends MiniPhase with IdentityDenotTransformer :
21
23
thisPhase =>
22
- import ast .tpd ._
23
24
24
25
override def phaseName : String = CapturedVars .name
25
26
26
27
override def description : String = CapturedVars .description
27
28
28
- private [this ] var Captured : Store .Location [util.ReadOnlySet [Symbol ]] = _
29
- private def captured (using Context ) = ctx.store(Captured )
30
-
31
- override def initContext (ctx : FreshContext ): Unit =
32
- Captured = ctx.addLocation(util.ReadOnlySet .empty)
29
+ private val captured = util.HashSet [Symbol ]()
33
30
34
31
private class RefInfo (using Context ) {
35
32
/** The classes for which a Ref type exists. */
@@ -55,33 +52,10 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
55
52
myRefInfo.uncheckedNN
56
53
}
57
54
58
- private class CollectCaptured extends TreeTraverser {
59
- private val captured = util.HashSet [Symbol ]()
60
- def traverse (tree : Tree )(using Context ) = tree match {
61
- case id : Ident =>
62
- val sym = id.symbol
63
- if (sym.is(Mutable , butNot = Method ) && sym.owner.isTerm) {
64
- val enclMeth = ctx.owner.enclosingMethod
65
- if (sym.enclosingMethod != enclMeth) {
66
- report.log(i " capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth" )
67
- captured += sym
68
- }
69
- }
70
- case _ =>
71
- traverseChildren(tree)
72
- }
73
- def runOver (tree : Tree )(using Context ): util.ReadOnlySet [Symbol ] = {
74
- traverse(tree)
75
- captured
76
- }
77
- }
78
-
79
- override def prepareForUnit (tree : Tree )(using Context ): Context = {
80
- val captured = atPhase(thisPhase) {
81
- CollectCaptured ().runOver(ctx.compilationUnit.tpdTree)
82
- }
83
- ctx.fresh.updateStore(Captured , captured)
84
- }
55
+ override def prepareForUnit (tree : Tree )(using Context ): Context =
56
+ captured.clear()
57
+ atPhase(thisPhase)(CapturedVars .collect(captured)).traverse(tree)
58
+ ctx
85
59
86
60
/** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
87
61
* depending on whether the reference should be @volatile
@@ -141,3 +115,16 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
141
115
object CapturedVars :
142
116
val name : String = " capturedVars"
143
117
val description : String = " represent vars captured by closures as heap objects"
118
+
119
+ def collect (captured : util.HashSet [Symbol ]): TreeTraverser = new :
120
+ def traverse (tree : Tree )(using Context ) = tree match
121
+ case id : Ident =>
122
+ val sym = id.symbol
123
+ if sym.is(Mutable , butNot = Method ) && sym.owner.isTerm then
124
+ val enclMeth = ctx.owner.enclosingMethod
125
+ if sym.enclosingMethod != enclMeth then
126
+ report.log(i " capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth" )
127
+ captured += sym
128
+ case _ =>
129
+ traverseChildren(tree)
130
+ end CapturedVars
0 commit comments