Skip to content

Commit 537d2ea

Browse files
committed
simplify annotation derivation
1 parent 3227844 commit 537d2ea

File tree

2 files changed

+51
-35
lines changed

2 files changed

+51
-35
lines changed

src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,6 @@ trait MethodSynthesis {
2222
import definitions._
2323
import CODE._
2424

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-
}
3625

3726
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
3827
def mkThis = This(clazz) setPos clazz.pos.focus
@@ -160,13 +149,15 @@ trait MethodSynthesis {
160149
enterBeans(tree)
161150
}
162151

152+
import AnnotationInfo.{mkFilter => annotationFilter}
153+
163154
/** This is called for those ValDefs which addDerivedTrees ignores, but
164155
* which might have a warnable annotation situation.
165156
*/
166157
private def warnForDroppedAnnotations(tree: Tree) {
167158
val annotations = tree.symbol.initialize.annotations
168159
val targetClass = defaultAnnotationTarget(tree)
169-
val retained = deriveAnnotations(annotations, targetClass, keepClean = true)
160+
val retained = annotations filter annotationFilter(targetClass, defaultRetention = true)
170161

171162
annotations filterNot (retained contains _) foreach (ann => issueAnnotationWarning(tree, ann, targetClass))
172163
}
@@ -208,8 +199,8 @@ trait MethodSynthesis {
208199
context.unit.synthetics get meth match {
209200
case Some(mdef) =>
210201
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))
213204
List(cd, mdef)
214205
case _ =>
215206
// Shouldn't happen, but let's give ourselves a reasonable error when it does
@@ -293,10 +284,6 @@ trait MethodSynthesis {
293284
def tree: ValDef
294285
final def enclClass = basisSym.enclClass
295286

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
300287

301288
/* Explicit isSetter required for bean setters (beanSetterSym.isSetter is false) */
302289
final def completer(sym: Symbol) = namerOf(sym).accessorTypeCompleter(tree, isSetter)
@@ -307,7 +294,6 @@ trait MethodSynthesis {
307294

308295
def isSetter = false
309296
def isDeferred = mods.isDeferred
310-
def keepClean = false // whether annotations whose definitions are not meta-annotated should be kept.
311297
def validate() { }
312298
def createAndEnterSymbol(): MethodSymbol = {
313299
val sym = owner.newMethod(name, tree.pos.focus, derivedMods.flags)
@@ -323,7 +309,32 @@ trait MethodSynthesis {
323309
}
324310
final def derive(initial: List[AnnotationInfo]): Tree = {
325311
validate()
326-
derivedSym setAnnotations deriveAnnotations(initial, category, keepClean)
312+
313+
// Which meta-annotation is associated with this kind of entity.
314+
// Presently one of: field, getter, setter, beanGetter, beanSetter, param.
315+
// For traits, getter must play role of field as there isn't one until Constructors (we'll triage there)
316+
val categories = this match {
317+
case _: BaseGetter => List(GetterTargetClass)
318+
case _: Setter => List(SetterTargetClass)
319+
case _: BeanSetter => List(BeanSetterTargetClass)
320+
case _: AnyBeanGetter => List(BeanGetterTargetClass)
321+
case _: Param => List(ParamTargetClass)
322+
case _: Field => List(FieldTargetClass)
323+
}
324+
325+
// whether annotations whose definitions are not meta-annotated should be kept.
326+
val defaultRetention = this match {
327+
case _: Param => true
328+
// By default annotations go to the field, except if the field is
329+
// generated for a class parameter (PARAMACCESSOR).
330+
case _: Field => !mods.isParamAccessor
331+
case _ => false
332+
}
333+
334+
// The annotations amongst those found on the original symbol which
335+
// should be propagated to this kind of accessor.
336+
val sym = derivedSym setAnnotations (initial filter annotationFilter(categories, defaultRetention))
337+
327338
logDerived(derivedTree)
328339
}
329340
}
@@ -370,7 +381,6 @@ trait MethodSynthesis {
370381

371382
sealed abstract class BaseGetter(tree: ValDef) extends DerivedGetter {
372383
def name = tree.name
373-
def category = GetterTargetClass
374384
def flagsMask = GetterFlags
375385
def flagsExtra = ACCESSOR.toLong | ( if (tree.mods.isMutable) 0 else STABLE )
376386

@@ -450,11 +460,10 @@ trait MethodSynthesis {
450460
}
451461
case class Setter(tree: ValDef) extends DerivedSetter {
452462
def name = tree.setterName
453-
def category = SetterTargetClass
454463
def flagsMask = SetterFlags
455464
def flagsExtra = ACCESSOR
456465

457-
override def derivedSym = basisSym.setterIn(enclClass)
466+
override def derivedSym = basisSym.setterIn(enclClass, hasExpandedName = false) // we'll expand it later
458467
}
459468

460469
object Field {
@@ -470,18 +479,14 @@ trait MethodSynthesis {
470479
// NOTE: do not look at `vd.symbol` when called from `enterGetterSetter` (luckily, that call-site implies `!mods.isLazy`),
471480
// as the symbol info is in the process of being created then.
472481
// 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))
482+
// TODO: the `def field` call-site breaks when you add `|| vd.symbol.owner.isTrait` (detected in test suite)
483+
def noFieldFor(vd: ValDef) = vd.mods.isDeferred || (vd.mods.isLazy && isUnitType(vd.symbol.info)) || owner.isTrait
475484
}
476485

477486
case class Field(tree: ValDef) extends DerivedFromValDef {
478487
def name = tree.localName
479-
def category = FieldTargetClass
480488
def flagsMask = FieldFlags
481489
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
485490

486491
// handle lazy val first for now (we emit a Field even though we probably shouldn't...)
487492
override def derivedTree =
@@ -492,10 +497,8 @@ trait MethodSynthesis {
492497
}
493498
case class Param(tree: ValDef) extends DerivedFromValDef {
494499
def name = tree.name
495-
def category = ParamTargetClass
496500
def flagsMask = -1L
497501
def flagsExtra = 0L
498-
override def keepClean = true
499502
override def derivedTree = EmptyTree
500503
}
501504
def validateParam(tree: ValDef) {
@@ -509,7 +512,6 @@ trait MethodSynthesis {
509512
override def derivedSym = enclClass.info decl name
510513
}
511514
sealed trait AnyBeanGetter extends BeanAccessor with DerivedGetter {
512-
def category = BeanGetterTargetClass
513515
override def validate() {
514516
if (derivedSym == NoSymbol) {
515517
// the namer decides whether to generate these symbols or not. at that point, we don't
@@ -532,9 +534,7 @@ trait MethodSynthesis {
532534
}
533535
case class BooleanBeanGetter(tree: ValDef) extends BeanAccessor("is") with AnyBeanGetter { }
534536
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-
}
537+
case class BeanSetter(tree: ValDef) extends BeanAccessor("set") with DerivedSetter
538538

539539
// No Symbols available.
540540
private def beanAccessorsFromNames(tree: ValDef) = {

src/reflect/scala/reflect/internal/AnnotationInfos.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,22 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
175175

176176
def unapply(info: AnnotationInfo): Option[(Type, List[Tree], List[(Name, ClassfileAnnotArg)])] =
177177
Some((info.atp, info.args, info.assocs))
178+
179+
def mkFilter(category: Symbol, defaultRetention: Boolean)(ann: AnnotationInfo) =
180+
(ann.metaAnnotations, ann.defaultTargets) match {
181+
case (Nil, Nil) => defaultRetention
182+
case (Nil, defaults) => defaults contains category
183+
case (metas, _) => metas exists (_ matches category)
184+
}
185+
186+
def mkFilter(categories: List[Symbol], defaultRetention: Boolean)(ann: AnnotationInfo) =
187+
(ann.metaAnnotations, ann.defaultTargets) match {
188+
case (Nil, Nil) => defaultRetention
189+
case (Nil, defaults) => categories exists defaults.contains
190+
case (metas, _) =>
191+
val metaSyms = metas collect { case ann if !ann.symbol.isInstanceOf[StubSymbol] => ann.symbol }
192+
categories exists (category => metaSyms exists (_ isNonBottomSubClass category))
193+
}
178194
}
179195

180196
class CompleteAnnotationInfo(

0 commit comments

Comments
 (0)