Skip to content

Commit 4dcec1c

Browse files
committed
Extract AnnotationTransformer functionality from ElimRepeated to a trait
to be reused by FirstTransform
1 parent 6789e4c commit 4dcec1c

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

@@ -89,17 +63,15 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
8963
transformTypeOfTree(tree)
9064

9165
/** If method overrides a Java varargs method, add a varargs bridge.
66+
* Also transform trees inside method annotation
9267
*/
9368
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
9469
assert(ctx.phase == thisTransformer)
9570
def overridesJava = tree.symbol.allOverriddenSymbols.exists(_ is JavaDefined)
96-
val newAnnots = tree.mods.annotations.mapConserve(annotTransformer.transform)
97-
val newTree = if (newAnnots eq tree.mods.annotations) tree
98-
else cpy.DefDef(tree)(mods = Modifiers(tree.mods.flags, tree.mods.privateWithin, newAnnots))
9971
if (tree.symbol.info.isVarArgsMethod && overridesJava)
100-
addVarArgsBridge(newTree)(ctx.withPhase(thisTransformer.next))
101-
else
102-
newTree
72+
addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next))
73+
else
74+
transformAnnotations(tree)
10375
}
10476

10577
/** Add a Java varargs bridge
@@ -122,7 +94,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
12294
.appliedToArgs(vrefs :+ TreeGen.wrapArray(varArgRef, elemtp))
12395
.appliedToArgss(vrefss1)
12496
})
125-
Thicket(ddef, bridgeDef)
97+
Thicket(transformAnnotations(ddef), transformAnnotations(bridgeDef))
12698
}
12799

128100
/** 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
@@ -169,6 +169,37 @@ object TreeTransforms {
169169
def phase = this
170170
}
171171

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

0 commit comments

Comments
 (0)