@@ -15,17 +15,9 @@ import symtab.Flags._
15
15
* For traits:
16
16
*
17
17
* - Namers translates a definition `val x = rhs` into a getter `def x = rhs` -- no underlying field is created.
18
- * - This phase moves `rhs` into a block nested under the template's local dummy.
19
- * If the value is memoized (stored), the block's final expression assigns the value to the val,
20
- * and the val itself is left without a rhs.
21
- * If the value of the rhs is a literal (ConstantType), it is not stored and the final expression of the block is ().
22
- * The val then retains this statically known value as its rhs.
23
- * (We could extend this to other fields that needn't be stored,
24
- * but would still need to lift their side-effects to the block.
25
- * We're mostly to set up for this, and experimented with doing this for Unit-typed vals.
26
- * No longer storing and writing to fields is too much of a a change in semantics.
27
- * Mainly regarding the memory model -- visibility of writes across threads etc would change.)
28
- * - This phase also synthesizes accessors and fields for any vals mixed into a non-trait class.
18
+ * - This phase synthesizes accessors and fields for any vals mixed into a non-trait class.
19
+ * - During erasure, AddInterfaces will move the rhs to an assignment in the template body.
20
+ * We need to maintain the connection between getter and rhs until then, so specialization can duplicate as needed.
29
21
* - Constructors moves the statements in the template into the constructor,
30
22
* which means it will initialize the fields defined in this template (and execute the corresponding side effects).
31
23
*
@@ -72,9 +64,11 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
72
64
private def excludedAccessorOrFieldByFlags (statSym : Symbol ): Boolean = statSym hasFlag LAZY | PRESUPER
73
65
74
66
// used for internal communication between info and tree transform of this phase -- not pickled, not in initialflags
75
- // TODO: reuse TRANS_FLAG for NEEDS_TREES
67
+ // TODO: reuse MIXEDIN for NEEDS_TREES
76
68
override def phaseNewFlags : Long = NEEDS_TREES | OVERRIDDEN_TRAIT_SETTER
77
69
70
+ private final val OVERRIDDEN_TRAIT_SETTER = TRANS_FLAG
71
+
78
72
final val TRAIT_SETTER_FLAGS = NEEDS_TREES | DEFERRED
79
73
80
74
private def accessorImplementedInSubclass (accessor : Symbol ) = accessor hasAllFlags (ACCESSOR | SYNTHESIZE_IMPL_IN_SUBCLASS )
@@ -164,17 +158,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
164
158
private def newTraitSetter (getter : Symbol , clazz : Symbol ) = {
165
159
// Add setter for an immutable, memoizing getter
166
160
// (can't emit during namers because we don't yet know whether it's going to be memoized or not)
167
- // TODO: any flags to inherit from getter??? (probably not -- certainly exclude: stable, override, implicit, private, local)
168
- // TODO: stable/mutable? (we need to access the setter from the init method, so it needs to be in the interface)
169
161
// TODO: annotations?
170
- // TODO: ARTIFACT or SYNTHETIC?? neither?
171
- // protected, because implemented by subclass, never used outside of hierarchy
172
162
val setterFlags = (getter.flags & ~ (STABLE | PrivateLocal | OVERRIDE | IMPLICIT | FINAL )) | MUTABLE | ACCESSOR | TRAIT_SETTER_FLAGS
173
- val setterName = nme.expandedSetterName(getter.name.setterName, clazz)
174
- val setter = clazz.newMethod(setterName, getter.pos.focus, setterFlags)
175
- val fieldTp = fieldTypeForGetterIn(getter, clazz.thisType)
176
-
177
- // println(s"newTraitSetter in $clazz for $getter = $setterName : $fieldTp")
163
+ val setterName = nme.expandedSetterName(getter.name.setterName, clazz)
164
+ val setter = clazz.newMethod(setterName, getter.pos.focus, setterFlags)
165
+ val fieldTp = fieldTypeForGetterIn(getter, clazz.thisType)
166
+ // println(s"newTraitSetter in $clazz for $getter = $setterName : $fieldTp")
178
167
179
168
setter setInfo MethodType (List (setter.newSyntheticValueParam(fieldTp)), UnitTpe )
180
169
setter
0 commit comments