@@ -134,6 +134,7 @@ trait MethodSynthesis {
134
134
ImplicitClassWrapper (tree).createAndEnterSymbol()
135
135
}
136
136
137
+ // TODO: see standardAccessors
137
138
def enterGetterSetter (tree : ValDef ) {
138
139
val ValDef (mods, name, _, _) = tree
139
140
if (nme.isSetterName(name))
@@ -149,8 +150,11 @@ trait MethodSynthesis {
149
150
val getter = Getter (tree)
150
151
val getterSym = getter.createAndEnterSymbol()
151
152
// Create the setter if necessary.
152
- if (getter.needsSetter)
153
- Setter (tree).createAndEnterSymbol()
153
+ if (getter.needsSetter) {
154
+ val setterSym = Setter (tree).createAndEnterSymbol()
155
+ getterSym.referenced = setterSym
156
+ setterSym.referenced = getterSym
157
+ }
154
158
155
159
// Create a field if the getter requires storage, otherwise,
156
160
// the getter's abstract and the tree gets the getter's symbol.
@@ -224,9 +228,12 @@ trait MethodSynthesis {
224
228
}
225
229
226
230
def standardAccessors (vd : ValDef ): List [DerivedFromValDef ] =
227
- if (vd.mods.isMutable && ! vd.mods.isLazy) List (Getter (vd), Setter (vd))
228
- else if (vd.mods.isLazy) List (LazyValGetter (vd))
229
- else List (Getter (vd))
231
+ if (vd.mods.isLazy) List (LazyValGetter (vd))
232
+ else {
233
+ val getter = Getter (vd)
234
+ if (getter.needsSetter) List (getter, Setter (vd))
235
+ else List (getter)
236
+ }
230
237
231
238
def beanAccessors (vd : ValDef ): List [DerivedFromValDef ] = {
232
239
val setter = if (vd.mods.isMutable) List (BeanSetter (vd)) else Nil
@@ -264,7 +271,10 @@ trait MethodSynthesis {
264
271
def completer (sym : Symbol ): Type
265
272
266
273
/** The derived symbol. It is assumed that this symbol already exists and has been
267
- * entered in the parent scope when derivedSym is called */
274
+ * entered in the parent scope when derivedSym is called
275
+ * this derived symbol business is super shady -- we're creating them,
276
+ * so why do we need to look them up with setterIn/getterIn??
277
+ */
268
278
def derivedSym : Symbol
269
279
270
280
/** The definition tree of the derived symbol. */
@@ -310,14 +320,14 @@ trait MethodSynthesis {
310
320
// - concrete vals in traits don't yield a field here either (their getter's RHS has the initial value)
311
321
// Constructors will move the assignment to the constructor, abstracting over the field using the field setter,
312
322
// and Mixin will add a field to the class that mixes in the trait, implementing the accessors in terms of it
313
- def noFieldHere = nothingToMemoize || derivedSym. owner.isTrait
314
- protected def nothingToMemoize = isDeferred || typeNeedsNoStorage(basisSym.tpe)
323
+ def noFieldHere = nothingToMemoize || owner.isTrait
324
+ protected def nothingToMemoize = isDeferred || typeNeedsNoStorage(basisSym.tpe.resultType )
315
325
316
326
def isSetter = false
317
327
def isDeferred = mods.isDeferred
318
328
def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
319
329
def validate () { }
320
- def createAndEnterSymbol (): Symbol = {
330
+ def createAndEnterSymbol (): MethodSymbol = {
321
331
val sym = owner.newMethod(name, tree.pos.focus, derivedMods.flags)
322
332
setPrivateWithin(tree, sym)
323
333
enterInScope(sym)
@@ -336,14 +346,22 @@ trait MethodSynthesis {
336
346
}
337
347
}
338
348
sealed trait DerivedGetter extends DerivedFromValDef {
339
- def needsSetter = mods.isMutable || (derivedSym.owner.isTrait && ! nothingToMemoize)
349
+ // A getter obviously must be accompanied by a setter if the ValDef is mutable.
350
+ // We also need a setter for any val/var defined in a trait,
351
+ // since an interface in Java can't define a field,
352
+ // so we shall set the initial value indirectly in the trait's init method using the trait setter,
353
+ // which will be implemented in the class
354
+ def needsSetter = mods.isMutable || (owner.isTrait && ! nothingToMemoize)
340
355
}
341
356
sealed trait DerivedSetter extends DerivedFromValDef {
342
357
override def isSetter = true
343
358
private def setterParam = derivedSym.paramss match {
344
359
case (p :: Nil ) :: _ => p
345
360
case _ => NoSymbol
346
361
}
362
+ // TODO: when is `derivedSym.isOverloaded`??? is it always an error?
363
+ // `noFieldHere` does not imply DEFERRED (ask isDeferred if you must know)
364
+ // we automatically implement trait setters (where !isDeferred) in the subclass
347
365
private def setterRhs =
348
366
if (noFieldHere || derivedSym.isOverloaded) EmptyTree
349
367
else Assign (fieldSelection, Ident (setterParam))
@@ -456,7 +474,7 @@ trait MethodSynthesis {
456
474
def flagsMask = SetterFlags
457
475
def flagsExtra = ACCESSOR
458
476
459
- override def derivedSym = basisSym.setterIn(enclClass)
477
+ override def derivedSym = basisSym.setterIn(enclClass, hasExpandedName = false )
460
478
}
461
479
case class Field (tree : ValDef ) extends DerivedFromValDef {
462
480
def name = tree.localName
@@ -467,12 +485,8 @@ trait MethodSynthesis {
467
485
// generated for a class parameter (PARAMACCESSOR).
468
486
override def keepClean = ! mods.isParamAccessor
469
487
470
- override def derivedSym =
471
- if (noFieldHere) NoSymbol
472
- else super .derivedSym
473
-
474
488
override def derivedTree = (
475
- if (derivedSym eq NoSymbol ) EmptyTree
489
+ if (noFieldHere ) EmptyTree
476
490
else if (mods.isLazy) copyValDef(tree)(mods = mods | flagsExtra, name = this .name, rhs = EmptyTree ).setPos(tree.pos.focus)
477
491
else copyValDef(tree)(mods = mods | flagsExtra, name = this .name)
478
492
)
@@ -515,7 +529,7 @@ trait MethodSynthesis {
515
529
)
516
530
}
517
531
}
518
- override def createAndEnterSymbol (): Symbol = enterSyntheticSym(derivedTree)
532
+ override def createAndEnterSymbol (): MethodSymbol = enterSyntheticSym(derivedTree). asInstanceOf [ MethodSymbol ]
519
533
}
520
534
case class BooleanBeanGetter (tree : ValDef ) extends BeanAccessor (" is" ) with AnyBeanGetter { }
521
535
case class BeanGetter (tree : ValDef ) extends BeanAccessor (" get" ) with AnyBeanGetter { }
0 commit comments