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