@@ -10,6 +10,10 @@ import Symbols._
10
10
import MegaPhase ._
11
11
import Flags ._
12
12
import ValueClasses ._
13
+ import SymUtils ._
14
+ import NameOps ._
15
+ import collection .mutable
16
+
13
17
14
18
/** Performs the following rewritings for fields of a class:
15
19
*
@@ -30,13 +34,20 @@ import ValueClasses._
30
34
* <mods> non-static <module> val x$ = e
31
35
* --> <mods> <module> <accessor> def x$ = e
32
36
*
37
+ * Also, generate setters for fields that are private but not private[this]
38
+ * The form of a setter is
39
+ *
40
+ * <mods> def x_=(init: T): Unit = ()
41
+ *
33
42
* Omitted from the rewritings are
34
43
*
35
44
* - private[this] fields in classes (excluding traits, value classes)
36
45
* - fields generated for static modules (TODO: needed?)
37
46
* - parameters, static fields, and fields coming from Java
38
47
*
39
- * Furthermore, assignments to mutable vars are replaced by setter calls
48
+ * The rhs is computed later, in phase Memoize.
49
+ *
50
+ * Furthermore, assignments to mutable vars with setters are replaced by setter calls
40
51
*
41
52
* p.x = e
42
53
* --> p.x_=(e)
@@ -46,7 +57,7 @@ import ValueClasses._
46
57
* Also, drop the Local flag from all private[this] and protected[this] members.
47
58
* This allows subsequent code motions in Flatten.
48
59
*/
49
- class Getters extends MiniPhase with SymTransformer {
60
+ class Getters extends MiniPhase with SymTransformer { thisPhase =>
50
61
import ast .tpd ._
51
62
52
63
override def phaseName : String = Getters .name
@@ -80,11 +91,31 @@ class Getters extends MiniPhase with SymTransformer {
80
91
}
81
92
private val NoGetterNeededFlags = Method | Param | JavaDefined | JavaStatic
82
93
94
+ val newSetters = mutable.HashSet [Symbol ]()
95
+
96
+ def ensureSetter (sym : TermSymbol )(given Context ) =
97
+ if ! sym.setter.exists then
98
+ newSetters += sym.copy(
99
+ name = sym.name.setterName,
100
+ info = MethodType (sym.info.widenExpr :: Nil , defn.UnitType )
101
+ ).enteredAfter(thisPhase)
102
+
83
103
override def transformValDef (tree : ValDef )(implicit ctx : Context ): Tree =
84
- if (tree.symbol.is(Method )) DefDef (tree.symbol.asTerm, tree.rhs).withSpan(tree.span) else tree
104
+ val sym = tree.symbol
105
+ if ! sym.is(Method ) then return tree
106
+ val getterDef = DefDef (sym.asTerm, tree.rhs).withSpan(tree.span)
107
+ if ! sym.is(Mutable ) then return getterDef
108
+ ensureSetter(sym.asTerm)
109
+ if ! newSetters.contains(sym.setter) then return getterDef
110
+ val setterDef = DefDef (sym.setter.asTerm, unitLiteral)
111
+ Thicket (getterDef, setterDef)
85
112
86
113
override def transformAssign (tree : Assign )(implicit ctx : Context ): Tree =
87
- if (tree.lhs.symbol.is(Method )) tree.lhs.becomes(tree.rhs).withSpan(tree.span) else tree
114
+ val lsym = tree.lhs.symbol.asTerm
115
+ if (lsym.is(Method ))
116
+ ensureSetter(lsym)
117
+ tree.lhs.becomes(tree.rhs).withSpan(tree.span)
118
+ else tree
88
119
}
89
120
90
121
object Getters {
0 commit comments