@@ -13,25 +13,20 @@ import core.NameKinds.TempResultName
1313import core .Constants ._
1414import util .Store
1515import dotty .tools .uncheckedNN
16-
17- import scala . compiletime .uninitialized
16+ import ast . tpd . *
17+ import compiletime .uninitialized
1818
1919/** This phase translates variables that are captured in closures to
2020 * heap-allocated refs.
2121 */
2222class CapturedVars extends MiniPhase with IdentityDenotTransformer :
2323 thisPhase =>
24- import ast .tpd ._
2524
2625 override def phaseName : String = CapturedVars .name
2726
2827 override def description : String = CapturedVars .description
2928
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 ]()
3530
3631 private class RefInfo (using Context ) {
3732 /** The classes for which a Ref type exists. */
@@ -57,33 +52,10 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
5752 myRefInfo.uncheckedNN
5853 }
5954
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
8759
8860 /** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
8961 * depending on whether the reference should be @volatile
@@ -143,3 +115,16 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer:
143115object CapturedVars :
144116 val name : String = " capturedVars"
145117 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