Skip to content

Commit 880ff3e

Browse files
committed
Extract AnnotationTransformer functionality from ElimRepeated to a trait
to be reused by FirstTransform
1 parent d25e6b4 commit 880ff3e

File tree

2 files changed

+40
-37
lines changed

2 files changed

+40
-37
lines changed

src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ package transform
44
import core._
55
import Names._
66
import Types._
7-
import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
7+
import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
88
import ast.Trees.flatten
99
import Flags._
1010
import Contexts.Context
1111
import Symbols._
1212
import Denotations._, SymDenotations._
1313
import Decorators.StringInterpolators
14+
import dotty.tools.dotc.ast.tpd
15+
import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
1416
import scala.collection.mutable
1517
import DenotTransformers._
1618
import Names.Name
@@ -20,39 +22,11 @@ import TypeUtils._
2022
/** A transformer that removes repeated parameters (T*) from all types, replacing
2123
* them with Seq types.
2224
*/
23-
class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
25+
class ElimRepeated extends MiniPhaseTransform with InfoTransformer with AnnotationTransformer { thisTransformer =>
2426
import ast.tpd._
2527

2628
override def phaseName = "elimRepeated"
2729

28-
object annotTransformer extends TreeMap {
29-
override def transform(tree: Tree)(implicit ctx: Context): Tree = super.transform(tree) match {
30-
case x @(_: Ident|_ :Select|_: Apply| _: TypeApply| _: DefDef) => transformTypeOfTree(x)
31-
case x => x
32-
}
33-
}
34-
35-
/**
36-
* Overriden to solve a particular problem with <repeated> not being eliminated inside annotation trees
37-
* Dmitry: this should solve problem for now,
38-
* following YAGNI principle I am convinced that we shouldn't make a solution
39-
* for a generalized problem(transforming annotations trees)
40-
* that manifests itself only here.
41-
*/
42-
override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
43-
val info1 = transformInfo(ref.info, ref.symbol)
44-
45-
ref match {
46-
case ref: SymDenotation =>
47-
val annotTrees = ref.annotations.map(_.tree)
48-
val annotTrees1 = annotTrees.mapConserve(annotTransformer.transform)
49-
val annots1 = if(annotTrees eq annotTrees1) ref.annotations else annotTrees1.map(new ConcreteAnnotation(_))
50-
if ((info1 eq ref.info) && (annots1 eq ref.annotations)) ref
51-
else ref.copySymDenotation(info = info1, annotations = annots1)
52-
case _ => if (info1 eq ref.info) ref else ref.derivedSingleDenotation(ref.symbol, info1)
53-
}
54-
}
55-
5630
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type =
5731
elimRepeated(tp)
5832

@@ -87,17 +61,15 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
8761
transformTypeOfTree(tree)
8862

8963
/** If method overrides a Java varargs method, add a varargs bridge.
64+
* Also transform trees inside method annotation
9065
*/
9166
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
9267
assert(ctx.phase == thisTransformer)
9368
def overridesJava = tree.symbol.allOverriddenSymbols.exists(_ is JavaDefined)
94-
val newAnnots = tree.mods.annotations.mapConserve(annotTransformer.transform)
95-
val newTree = if (newAnnots eq tree.mods.annotations) tree
96-
else cpy.DefDef(tree)(mods = Modifiers(tree.mods.flags, tree.mods.privateWithin, newAnnots))
9769
if (tree.symbol.info.isVarArgsMethod && overridesJava)
98-
addVarArgsBridge(newTree)(ctx.withPhase(thisTransformer.next))
99-
else
100-
newTree
70+
addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next))
71+
else
72+
transformAnnotations(tree)
10173
}
10274

10375
/** Add a Java varargs bridge
@@ -120,7 +92,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
12092
.appliedToArgs(vrefs :+ TreeGen.wrapArray(varArgRef, elemtp))
12193
.appliedToArgss(vrefss1)
12294
})
123-
Thicket(ddef, bridgeDef)
95+
Thicket(transformAnnotations(ddef), transformAnnotations(bridgeDef))
12496
}
12597

12698
/** Convert type from Scala to Java varargs method */

src/dotty/tools/dotc/transform/TreeTransform.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,37 @@ object TreeTransforms {
168168
def phase = this
169169
}
170170

171+
/** A helper trait to transform annotations on MemberDefs */
172+
trait AnnotationTransformer extends MiniPhaseTransform {
173+
174+
val annotationTransformer = mkTreeTransformer
175+
176+
def transformAnnotations(tree: MemberDef)(implicit ctx: Context): MemberDef ={
177+
val newAnnots = tree.mods.annotations.mapConserve(annotationTransformer.transform)
178+
if (newAnnots eq tree.mods.annotations) tree
179+
else {
180+
val mods = tree.mods.copy(annotations = newAnnots)
181+
tree match {
182+
case t: DefDef => cpy.DefDef(t)(mods = mods)
183+
case t: ValDef => cpy.ValDef(t)(mods = mods)
184+
case t: TypeDef => cpy.TypeDef(t)(mods = mods)
185+
}
186+
}
187+
}
188+
189+
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
190+
transformAnnotations(tree)
191+
}
192+
193+
override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
194+
transformAnnotations(tree)
195+
}
196+
197+
override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
198+
transformAnnotations(tree)
199+
}
200+
}
201+
171202
val NoTransform = new TreeTransform {
172203
def phase = unsupported("phase")
173204
idx = -1

0 commit comments

Comments
 (0)