@@ -8,62 +8,44 @@ import ast._
88import Trees ._
99import Flags ._
1010import Symbols ._
11+ import Contexts ._
1112import Decorators ._
1213import DenotTransformers ._
13- import StdNames .nme
14+ import ExplicitOuter .isOuterParamAccessor
15+ import CountOuterAccesses .mightBeDropped
1416import collection .mutable
17+ import annotation .threadUnsafe
1518
1619object DropOuterAccessors :
1720 val name : String = " dropOuterAccessors"
1821
19- /** Drops outer accessors of final classes that are unused */
22+ /** Drops unused outer accessors of inner classes that are visible only in one
23+ * toplevel class. For other classes, we can't tell whether an outer accessor
24+ * is used or not. It could for instance be used in a type test in some other source.
25+ */
2026class DropOuterAccessors extends MiniPhase with IdentityDenotTransformer :
2127 thisPhase =>
2228 import tpd ._
2329
2430 override def phaseName : String = DropOuterAccessors .name
2531
26- override def runsAfter : Set [String ] = Set (LambdaLift .name)
27- // LambdaLift can create outer paths. These need to be known in this phase
32+ override def runsAfterGroupsOf : Set [String ] = Set (CountOuterAccesses .name)
2833
2934 override def changesMembers : Boolean = true // the phase drops outer accessors
3035
31- def (sym : Symbol ).isOuterParamAccessor(using Context ) =
32- sym.is(ParamAccessor ) && sym.name == nme.OUTER
33-
34- /** Characterizes outer accessors and outer fields that can be dropped
35- * if there are no references to them from within the class in which they
36- * are defined.
37- */
38- private def mightBeDropped (sym : Symbol )(using Context ) =
39- (sym.is(OuterAccessor ) || sym.isOuterParamAccessor)
40- && sym.owner.isAnonymousClass
41-
42- /** The number of times an outer accessor that might be dropped is accessed */
43- private val accessCount = new mutable.HashMap [Symbol , Int ]:
44- override def default (key : Symbol ): Int = 0
45-
46- private def markAccessed (tree : RefTree )(implicit ctx : Context ): Tree =
47- val sym = tree.symbol
48- if mightBeDropped(sym) then accessCount(sym) += 1
49- tree
50-
51- override def transformIdent (tree : Ident )(using Context ): Tree =
52- markAccessed(tree)
53-
54- override def transformSelect (tree : Select )(using Context ): Tree =
55- markAccessed(tree)
56-
5736 override def transformTemplate (impl : Template )(using ctx : Context ): Tree =
37+ val outerAccessCount = ctx.base.countOuterAccessesPhase
38+ .asInstanceOf [CountOuterAccesses ]
39+ .outerAccessCount
5840
5941 def dropOuterAccessor (stat : Tree ): Boolean = stat match
6042 case stat : DefDef
6143 if stat.symbol.is(OuterAccessor )
6244 && mightBeDropped(stat.symbol)
63- && accessCount (stat.symbol) == 0 =>
45+ && outerAccessCount (stat.symbol) == 0 =>
6446 assert(stat.rhs.isInstanceOf [RefTree ], stat)
65- assert(accessCount (stat.rhs.symbol) > 0 )
66- accessCount (stat.rhs.symbol) -= 1
47+ assert(outerAccessCount (stat.rhs.symbol) > 0 )
48+ outerAccessCount (stat.rhs.symbol) -= 1
6749 stat.symbol.dropAfter(thisPhase)
6850 true
6951 case _ =>
@@ -75,7 +57,7 @@ class DropOuterAccessors extends MiniPhase with IdentityDenotTransformer:
7557 case stat : ValDef
7658 if stat.symbol.isOuterParamAccessor
7759 && mightBeDropped(stat.symbol)
78- && accessCount (stat.symbol) == 1 =>
60+ && outerAccessCount (stat.symbol) == 1 =>
7961 droppedParamAccessors += stat.symbol
8062 stat.symbol.dropAfter(thisPhase)
8163 true
0 commit comments