@@ -22,17 +22,6 @@ trait MethodSynthesis {
22
22
import definitions ._
23
23
import CODE ._
24
24
25
- /** The annotations amongst those found on the original symbol which
26
- * should be propagated to this kind of accessor.
27
- */
28
- def deriveAnnotations (initial : List [AnnotationInfo ], category : Symbol , keepClean : Boolean ): List [AnnotationInfo ] = {
29
- def annotationFilter (ann : AnnotationInfo ) = ann.metaAnnotations match {
30
- case Nil if ann.defaultTargets.isEmpty => keepClean // no meta-annotations or default targets
31
- case Nil => ann.defaultTargets contains category // default targets exist for ann
32
- case metas => metas exists (_ matches category) // meta-annotations attached to ann
33
- }
34
- initial filter annotationFilter
35
- }
36
25
37
26
class ClassMethodSynthesis (val clazz : Symbol , localTyper : Typer ) {
38
27
def mkThis = This (clazz) setPos clazz.pos.focus
@@ -160,13 +149,15 @@ trait MethodSynthesis {
160
149
enterBeans(tree)
161
150
}
162
151
152
+ import AnnotationInfo .{mkFilter => annotationFilter }
153
+
163
154
/** This is called for those ValDefs which addDerivedTrees ignores, but
164
155
* which might have a warnable annotation situation.
165
156
*/
166
157
private def warnForDroppedAnnotations (tree : Tree ) {
167
158
val annotations = tree.symbol.initialize.annotations
168
159
val targetClass = defaultAnnotationTarget(tree)
169
- val retained = deriveAnnotations( annotations, targetClass, keepClean = true )
160
+ val retained = annotations filter annotationFilter( targetClass, defaultRetention = true )
170
161
171
162
annotations filterNot (retained contains _) foreach (ann => issueAnnotationWarning(tree, ann, targetClass))
172
163
}
@@ -208,8 +199,8 @@ trait MethodSynthesis {
208
199
context.unit.synthetics get meth match {
209
200
case Some (mdef) =>
210
201
context.unit.synthetics -= meth
211
- meth setAnnotations deriveAnnotations (annotations, MethodTargetClass , keepClean = false )
212
- cd.symbol setAnnotations deriveAnnotations (annotations, ClassTargetClass , keepClean = true )
202
+ meth setAnnotations (annotations filter annotationFilter( MethodTargetClass , defaultRetention = false ) )
203
+ cd.symbol setAnnotations (annotations filter annotationFilter( ClassTargetClass , defaultRetention = true ) )
213
204
List (cd, mdef)
214
205
case _ =>
215
206
// Shouldn't happen, but let's give ourselves a reasonable error when it does
@@ -293,10 +284,6 @@ trait MethodSynthesis {
293
284
def tree : ValDef
294
285
final def enclClass = basisSym.enclClass
295
286
296
- /** Which meta-annotation is associated with this kind of entity.
297
- * Presently one of: field, getter, setter, beanGetter, beanSetter, param.
298
- */
299
- def category : Symbol
300
287
301
288
/* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
302
289
final def completer (sym : Symbol ) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
@@ -307,7 +294,6 @@ trait MethodSynthesis {
307
294
308
295
def isSetter = false
309
296
def isDeferred = mods.isDeferred
310
- def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
311
297
def validate () { }
312
298
def createAndEnterSymbol (): MethodSymbol = {
313
299
val sym = owner.newMethod(name, tree.pos.focus, derivedMods.flags)
@@ -323,7 +309,29 @@ trait MethodSynthesis {
323
309
}
324
310
final def derive (initial : List [AnnotationInfo ]): Tree = {
325
311
validate()
326
- derivedSym setAnnotations deriveAnnotations(initial, category, keepClean)
312
+
313
+ // see scala.annotation.meta's package class for more info
314
+ // Annotations on ValDefs can be targeted towards the following: field, getter, setter, beanGetter, beanSetter, param.
315
+ // The defaults are:
316
+ // - (`val`-, `var`- or plain) constructor parameter annotations end up on the parameter, not on any other entity.
317
+ // - val/var member annotations solely end up on the underlying field.
318
+ //
319
+ // TODO: these defaults can be surprising for annotations not meant for accessors/fields -- should we revisit?
320
+ // (In order to have `@foo val X` result in the X getter being annotated with `@foo`, foo needs to be meta-annotated with @getter)
321
+ val annotFilter : AnnotationInfo => Boolean = this match {
322
+ case _ : Param => annotationFilter(ParamTargetClass , defaultRetention = true )
323
+ // By default annotations go to the field, except if the field is generated for a class parameter (PARAMACCESSOR).
324
+ case _ : Field => annotationFilter(FieldTargetClass , defaultRetention = ! mods.isParamAccessor)
325
+ case _ : BaseGetter => annotationFilter(GetterTargetClass , defaultRetention = false )
326
+ case _ : Setter => annotationFilter(SetterTargetClass , defaultRetention = false )
327
+ case _ : BeanSetter => annotationFilter(BeanSetterTargetClass , defaultRetention = false )
328
+ case _ : AnyBeanGetter => annotationFilter(BeanGetterTargetClass , defaultRetention = false )
329
+ }
330
+
331
+ // The annotations amongst those found on the original symbol which
332
+ // should be propagated to this kind of accessor.
333
+ derivedSym setAnnotations (initial filter annotFilter)
334
+
327
335
logDerived(derivedTree)
328
336
}
329
337
}
@@ -370,7 +378,6 @@ trait MethodSynthesis {
370
378
371
379
sealed abstract class BaseGetter (tree : ValDef ) extends DerivedGetter {
372
380
def name = tree.name
373
- def category = GetterTargetClass
374
381
def flagsMask = GetterFlags
375
382
def flagsExtra = ACCESSOR .toLong | ( if (tree.mods.isMutable) 0 else STABLE )
376
383
@@ -450,7 +457,6 @@ trait MethodSynthesis {
450
457
}
451
458
case class Setter (tree : ValDef ) extends DerivedSetter {
452
459
def name = tree.setterName
453
- def category = SetterTargetClass
454
460
def flagsMask = SetterFlags
455
461
def flagsExtra = ACCESSOR
456
462
@@ -470,18 +476,14 @@ trait MethodSynthesis {
470
476
// NOTE: do not look at `vd.symbol` when called from `enterGetterSetter` (luckily, that call-site implies `!mods.isLazy`),
471
477
// as the symbol info is in the process of being created then.
472
478
// TODO: harmonize tree & symbol creation
473
- // TODO: the `def field` call-site does not tollerate including `|| vd.symbol.owner.isTrait` --> tests break
474
- def noFieldFor (vd : ValDef ) = vd.mods.isDeferred || (vd.mods.isLazy && isUnitType(vd.symbol.info)) // || vd.symbol.owner.isTrait))
479
+ // TODO: the `def field` call-site breaks when you add `|| vd.symbol.owner.isTrait` (detected in test suite)
480
+ def noFieldFor (vd : ValDef ) = vd.mods.isDeferred || (vd.mods.isLazy && isUnitType(vd.symbol.info))
475
481
}
476
482
477
483
case class Field (tree : ValDef ) extends DerivedFromValDef {
478
484
def name = tree.localName
479
- def category = FieldTargetClass
480
485
def flagsMask = FieldFlags
481
486
def flagsExtra = PrivateLocal
482
- // By default annotations go to the field, except if the field is
483
- // generated for a class parameter (PARAMACCESSOR).
484
- override def keepClean = ! mods.isParamAccessor
485
487
486
488
// handle lazy val first for now (we emit a Field even though we probably shouldn't...)
487
489
override def derivedTree =
@@ -492,10 +494,8 @@ trait MethodSynthesis {
492
494
}
493
495
case class Param (tree : ValDef ) extends DerivedFromValDef {
494
496
def name = tree.name
495
- def category = ParamTargetClass
496
497
def flagsMask = - 1L
497
498
def flagsExtra = 0L
498
- override def keepClean = true
499
499
override def derivedTree = EmptyTree
500
500
}
501
501
def validateParam (tree : ValDef ) {
@@ -509,7 +509,6 @@ trait MethodSynthesis {
509
509
override def derivedSym = enclClass.info decl name
510
510
}
511
511
sealed trait AnyBeanGetter extends BeanAccessor with DerivedGetter {
512
- def category = BeanGetterTargetClass
513
512
override def validate () {
514
513
if (derivedSym == NoSymbol ) {
515
514
// the namer decides whether to generate these symbols or not. at that point, we don't
@@ -532,9 +531,7 @@ trait MethodSynthesis {
532
531
}
533
532
case class BooleanBeanGetter (tree : ValDef ) extends BeanAccessor (" is" ) with AnyBeanGetter { }
534
533
case class BeanGetter (tree : ValDef ) extends BeanAccessor (" get" ) with AnyBeanGetter { }
535
- case class BeanSetter (tree : ValDef ) extends BeanAccessor (" set" ) with DerivedSetter {
536
- def category = BeanSetterTargetClass
537
- }
534
+ case class BeanSetter (tree : ValDef ) extends BeanAccessor (" set" ) with DerivedSetter
538
535
539
536
// No Symbols available.
540
537
private def beanAccessorsFromNames (tree : ValDef ) = {
0 commit comments