Skip to content

Commit ff68dc3

Browse files
committed
Push copyAndKeepAnnotationsCarrying into SymDenotation
1 parent 0bd5087 commit ff68dc3

File tree

6 files changed

+36
-46
lines changed

6 files changed

+36
-46
lines changed

compiler/src/dotty/tools/dotc/core/Annotations.scala

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,20 @@ object Annotations {
8888
def sameAnnotation(that: Annotation)(using Context): Boolean =
8989
symbol == that.symbol && tree.sameTree(that.tree)
9090

91-
def hasOneOfMetaAnnotation(metaSyms: Symbol*)(using Context): Boolean = atPhaseNoLater(erasurePhase) {
92-
def recTp(tp: Type): Boolean = tp.dealiasKeepAnnots match
93-
case AnnotatedType(parent, metaAnnot) => metaSyms.exists(metaAnnot.matches) || recTp(parent)
94-
case _ => false
95-
def rec(tree: Tree): Boolean = methPart(tree) match
96-
case New(tpt) => rec(tpt)
97-
case Select(qual, _) => rec(qual)
98-
case Annotated(arg, metaAnnot) => metaSyms.exists(metaAnnot.tpe.classSymbol.derivesFrom) || rec(arg)
99-
case t @ Ident(_) => recTp(t.tpe)
100-
case Typed(expr, _) => rec(expr)
101-
case _ => false
102-
metaSyms.exists(symbol.hasAnnotation) || rec(tree)
91+
def hasOneOfMetaAnnotation(metaSyms: Set[Symbol], orNoneOf: Set[Symbol] = Set.empty)(using Context): Boolean = atPhaseNoLater(erasurePhase) {
92+
def go(metaSyms: Set[Symbol]) =
93+
def recTp(tp: Type): Boolean = tp.dealiasKeepAnnots match
94+
case AnnotatedType(parent, metaAnnot) => metaSyms.exists(metaAnnot.matches) || recTp(parent)
95+
case _ => false
96+
def rec(tree: Tree): Boolean = methPart(tree) match
97+
case New(tpt) => rec(tpt)
98+
case Select(qual, _) => rec(qual)
99+
case Annotated(arg, metaAnnot) => metaSyms.exists(metaAnnot.tpe.classSymbol.derivesFrom) || rec(arg)
100+
case t @ Ident(_) => recTp(t.tpe)
101+
case Typed(expr, _) => rec(expr)
102+
case _ => false
103+
metaSyms.exists(symbol.hasAnnotation) || rec(tree)
104+
go(metaSyms) || orNoneOf.nonEmpty && !go(orNoneOf)
103105
}
104106

105107
/** Operations for hash-consing, can be overridden */

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,15 @@ object SymDenotations {
252252
final def filterAnnotations(p: Annotation => Boolean)(using Context): Unit =
253253
annotations = annotations.filterConserve(p)
254254

255+
def annotationsCarrying(meta: Set[Symbol], orNoneOf: Set[Symbol] = Set.empty)(using Context): List[Annotation] =
256+
annotations.filterConserve(_.hasOneOfMetaAnnotation(meta, orNoneOf = orNoneOf))
257+
258+
def copyAndKeepAnnotationsCarrying(phase: DenotTransformer, meta: Set[Symbol], orNoneOf: Set[Symbol] = Set.empty)(using Context): Unit =
259+
if annotations.nonEmpty then
260+
val cpy = copySymDenotation()
261+
cpy.annotations = annotationsCarrying(meta, orNoneOf = orNoneOf)
262+
cpy.installAfter(phase)
263+
255264
/** Optionally, the annotation matching the given class symbol */
256265
final def getAnnotation(cls: Symbol)(using Context): Option[Annotation] =
257266
dropOtherAnnotations(annotations, cls) match {

compiler/src/dotty/tools/dotc/transform/BeanProperties.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import core._
55
import ast.tpd._
66
import Annotations._
77
import Contexts._
8-
import Symbols.newSymbol
8+
import Symbols.*
99
import SymUtils.*
1010
import Decorators._
1111
import Flags._
@@ -24,8 +24,6 @@ class BeanProperties(thisPhase: DenotTransformer):
2424
} ::: origBody)
2525

2626
def generateAccessors(valDef: ValDef)(using Context): List[Tree] =
27-
import Symbols.defn
28-
2927
def generateGetter(valDef: ValDef, annot: Annotation)(using Context) : Tree =
3028
val prefix = if annot matches defn.BooleanBeanPropertyAnnot then "is" else "get"
3129
val meth = newSymbol(

compiler/src/dotty/tools/dotc/transform/Memoize.scala

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,27 +108,16 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
108108
if (sym.isGetter) sym.info.resultType
109109
else /*sym.isSetter*/ sym.info.firstParamTypes.head
110110

111-
val fieldSym = newSymbol(
111+
newSymbol(
112112
owner = ctx.owner,
113113
name = sym.name.asTermName.fieldName,
114114
flags = Private | (if (sym.is(StableRealizable)) EmptyFlags else Mutable),
115115
info = fieldType,
116116
coord = tree.span
117-
)
118-
fieldSym.annotations = sym.annotations.filterConserve { annot =>
119-
annot.hasOneOfMetaAnnotation(defn.FieldMetaAnnot)
120-
|| !annot.hasOneOfMetaAnnotation(defn.MetaAnnots.toList*)
121-
}
122-
fieldSym.enteredAfter(thisPhase)
117+
).withAnnotationsCarrying(sym, defn.FieldMetaAnnot, orNoneOf = defn.MetaAnnots)
118+
.enteredAfter(thisPhase)
123119
}
124120

125-
def removeUnwantedAnnotations(denot: SymDenotation, metaAnnotSym: ClassSymbol): Unit =
126-
if (sym.annotations.nonEmpty) {
127-
val cpy = sym.copySymDenotation()
128-
cpy.filterAnnotations(_.hasOneOfMetaAnnotation(metaAnnotSym))
129-
cpy.installAfter(thisPhase)
130-
}
131-
132121
val NoFieldNeeded = Lazy | Deferred | JavaDefined | Inline
133122

134123
def erasedBottomTree(sym: Symbol) =
@@ -178,7 +167,7 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
178167
if isErasableBottomField(field, rhsClass) then erasedBottomTree(rhsClass)
179168
else transformFollowingDeep(ref(field))(using ctx.withOwner(sym))
180169
val getterDef = cpy.DefDef(tree)(rhs = getterRhs)
181-
removeUnwantedAnnotations(sym, defn.GetterMetaAnnot)
170+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.GetterMetaAnnot))
182171
Thicket(fieldDef, getterDef)
183172
else if sym.isSetter then
184173
if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs: @unchecked } // This is intended as an assertion
@@ -204,7 +193,7 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
204193
then Literal(Constant(()))
205194
else Assign(ref(field), adaptToField(field, ref(tree.termParamss.head.head.symbol)))
206195
val setterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(initializer)(using ctx.withOwner(sym)))
207-
removeUnwantedAnnotations(sym, defn.SetterMetaAnnot)
196+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.SetterMetaAnnot))
208197
setterDef
209198
else
210199
// Curiously, some accessors from Scala2 have ' ' suffixes.

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,14 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
157157
checkInferredWellFormed(tree.tpt)
158158
if sym.is(Method) then
159159
if sym.isSetter then
160-
removeUnwantedAnnotations(sym, defn.SetterMetaAnnot, NoSymbol, keepIfNoRelevantAnnot = false)
160+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.SetterMetaAnnot))
161161
else
162162
if sym.is(Param) then
163-
removeUnwantedAnnotations(sym, defn.ParamMetaAnnot, NoSymbol, keepIfNoRelevantAnnot = true)
163+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.ParamMetaAnnot), orNoneOf = defn.NonBeanMetaAnnots)
164+
else if sym.is(ParamAccessor) then
165+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.GetterMetaAnnot, defn.FieldMetaAnnot))
164166
else
165-
removeUnwantedAnnotations(sym, defn.GetterMetaAnnot, defn.FieldMetaAnnot, keepIfNoRelevantAnnot = !sym.is(ParamAccessor))
167+
sym.copyAndKeepAnnotationsCarrying(thisPhase, Set(defn.GetterMetaAnnot, defn.FieldMetaAnnot), orNoneOf = defn.NonBeanMetaAnnots)
166168
if sym.isScala2Macro && !ctx.settings.XignoreScala2Macros.value then
167169
if !sym.owner.unforcedDecls.exists(p => !p.isScala2Macro && p.name == sym.name && p.signature == sym.signature)
168170
// Allow scala.reflect.materializeClassTag to be able to compile scala/reflect/package.scala
@@ -184,13 +186,6 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase
184186
=> Checking.checkAppliedTypesIn(tree)
185187
case _ =>
186188

187-
private def removeUnwantedAnnotations(sym: Symbol, metaAnnotSym: Symbol,
188-
metaAnnotSymBackup: Symbol, keepIfNoRelevantAnnot: Boolean)(using Context): Unit =
189-
def shouldKeep(annot: Annotation): Boolean =
190-
annot.hasOneOfMetaAnnotation(metaAnnotSym, metaAnnotSymBackup)
191-
|| keepIfNoRelevantAnnot && !annot.hasOneOfMetaAnnotation(defn.NonBeanMetaAnnots.toList*)
192-
if sym.annotations.nonEmpty then
193-
sym.filterAnnotations(shouldKeep(_))
194189

195190
private def transformSelect(tree: Select, targs: List[Tree])(using Context): Tree = {
196191
val qual = tree.qualifier

compiler/src/dotty/tools/dotc/transform/SymUtils.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,8 @@ object SymUtils:
270270
def isEnumCase(using Context): Boolean =
271271
self.isAllOf(EnumCase, butNot = JavaDefined)
272272

273-
def annotationsCarrying(meta: ClassSymbol)(using Context): List[Annotation] =
274-
self.annotations.filterConserve(_.hasOneOfMetaAnnotation(meta))
275-
276-
def withAnnotationsCarrying(from: Symbol, meta: ClassSymbol)(using Context): self.type = {
277-
self.addAnnotations(from.annotationsCarrying(meta))
273+
def withAnnotationsCarrying(from: Symbol, meta: Symbol, orNoneOf: Set[Symbol] = Set.empty)(using Context): self.type = {
274+
self.addAnnotations(from.annotationsCarrying(Set(meta), orNoneOf))
278275
self
279276
}
280277

0 commit comments

Comments
 (0)