@@ -16,25 +16,34 @@ import SymUtils._
16
16
import util .Attachment
17
17
import collection .mutable
18
18
19
- /** This phase decorates News and parent constructors of non-static inner classes
20
- * with an attachment indicating the outer reference as a tree. This is necessary because
21
- * outer prefixes are erased, and explicit outer runs only after erasure.
19
+ /** This phase adds outer accessors to classes and traits that need them.
20
+ * Compared to Scala 2.x, it tries to minimize the set of classes
21
+ * that take outer accessors and also tries to minimize the number
22
+ * of objects referred to by outer accessors. This helps prevent space
23
+ * leaks.
24
+ *
25
+ * The following things are delayed until erasure and are performed
26
+ * by class OuterOps:
27
+ *
28
+ * - add outer parameters to constructors
29
+ * - pass outer arguments in constructor calls
30
+ * - replace outer this by outer paths.
22
31
*/
23
- class OuterAccessors extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
24
- import OuterAccessors ._
32
+ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
33
+ import ExplicitOuter ._
25
34
import ast .tpd ._
26
35
27
36
val Outer = new Attachment .Key [Tree ]
28
37
29
- override def phaseName : String = " outerAccessors "
38
+ override def phaseName : String = " ExplicitOuter "
30
39
31
40
override def treeTransformPhase = thisTransformer.next
32
41
33
42
/** Add outer accessors if a class always needs an outer pointer */
34
43
override def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ) = tp match {
35
44
case tp @ ClassInfo (_, cls, _, decls, _) if needsOuterAlways(cls) =>
36
45
val newDecls = decls.cloneScope
37
- newOuterAccessors (cls).foreach(newDecls.enter)
46
+ newExplicitOuter (cls).foreach(newDecls.enter)
38
47
tp.derivedClassInfo(decls = newDecls)
39
48
case _ =>
40
49
tp
@@ -58,7 +67,7 @@ class OuterAccessors extends MiniPhaseTransform with InfoTransformer { thisTrans
58
67
newOuterSym(cls, cls, nme.OUTER , Private | ParamAccessor )
59
68
60
69
/** The outer accessor and potentially outer param accessor needed for class `cls` */
61
- private def newOuterAccessors (cls : ClassSymbol )(implicit ctx : Context ) =
70
+ private def newExplicitOuter (cls : ClassSymbol )(implicit ctx : Context ) =
62
71
newOuterAccessor(cls, cls) :: (if (cls is Trait ) Nil else newOuterParamAccessor(cls) :: Nil )
63
72
64
73
/** First, add outer accessors if a class does not have them yet and it references an outer this.
@@ -76,7 +85,7 @@ class OuterAccessors extends MiniPhaseTransform with InfoTransformer { thisTrans
76
85
val cls = ctx.owner.asClass
77
86
val isTrait = cls.is(Trait )
78
87
if (needsOuterIfReferenced(cls) && ! needsOuterAlways(cls) && referencesOuter(cls, impl))
79
- newOuterAccessors (cls).foreach(_.enteredAfter(thisTransformer))
88
+ newExplicitOuter (cls).foreach(_.enteredAfter(thisTransformer))
80
89
if (hasOuter(cls)) {
81
90
val newDefs = new mutable.ListBuffer [Tree ]
82
91
if (isTrait)
@@ -107,7 +116,7 @@ class OuterAccessors extends MiniPhaseTransform with InfoTransformer { thisTrans
107
116
}
108
117
}
109
118
110
- object OuterAccessors {
119
+ object ExplicitOuter {
111
120
import ast .tpd ._
112
121
113
122
private val LocalInstantiationSite = Module | Private
@@ -146,7 +155,7 @@ object OuterAccessors {
146
155
cls.info.member(outerAccName(cls)).suchThat(_ is OuterAccessor ).symbol orElse
147
156
cls.info.decls.find(_ is OuterAccessor ).getOrElse(NoSymbol )
148
157
149
- /** Class has an outer accessor. Can be called only after phase OuterAccessors . */
158
+ /** Class has an outer accessor. Can be called only after phase ExplicitOuter . */
150
159
private def hasOuter (cls : ClassSymbol )(implicit ctx : Context ): Boolean =
151
160
needsOuterIfReferenced(cls) && outerAccessor(cls).exists
152
161
0 commit comments