Skip to content

Commit 8f76a4c

Browse files
committed
AnnotationTransformer now also transforms types
Required as gettersAndSetters ignores modifiers in tree and uses ones in the type instead. This means that gettersAndSetters carries over modifiers from type to tree and this one violates postconditions.
1 parent 4dcec1c commit 8f76a4c

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package transform
33

44
import core._
55
import Names._
6-
import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
6+
import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
77
import ast.Trees._
88
import Flags._
99
import Types._
@@ -12,6 +12,8 @@ import Contexts.Context
1212
import Symbols._
1313
import SymDenotations._
1414
import Decorators._
15+
import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
16+
import dotty.tools.dotc.core.Denotations.SingleDenotation
1517
import scala.collection.mutable
1618
import DenotTransformers._
1719
import typer.Checking
@@ -27,11 +29,14 @@ import NameOps._
2729
* - checks the bounds of AppliedTypeTrees
2830
* - stubs out native methods
2931
*/
30-
class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer { thisTransformer =>
32+
class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer with AnnotationTransformer { thisTransformer =>
3133
import ast.tpd._
3234

3335
override def phaseName = "firstTransform"
3436

37+
38+
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = tp
39+
3540
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match {
3641
case Select(qual, _) if tree.symbol.exists =>
3742
assert(qual.tpe derivesFrom tree.symbol.owner, i"non member selection of ${tree.symbol.showLocated} from ${qual.tpe}")
@@ -82,13 +87,16 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer {
8287
addMissingCompanions(reorder(stats))
8388
}
8489

85-
override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) =
90+
override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
91+
val r =
8692
if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) {
8793
ddef.symbol.resetFlag(Deferred)
8894
DefDef(ddef.symbol.asTerm,
8995
_ => ref(defn.Sys_error).withPos(ddef.pos)
9096
.appliedTo(Literal(Constant("native method stub"))))
9197
} else ddef
98+
transformAnnotations(r)
99+
}
92100

93101
override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] =
94102
ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisTransformer.next)))
@@ -107,6 +115,8 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer {
107115
case _ => normalizeType(tree)
108116
}
109117

118+
119+
110120
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
111121
normalizeType {
112122
val qual = tree.qualifier

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ package dotty.tools.dotc
22
package transform
33

44
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Annotations.ConcreteAnnotation
56
import dotty.tools.dotc.core.Contexts.Context
7+
import dotty.tools.dotc.core.DenotTransformers.{InfoTransformer, DenotTransformer}
8+
import dotty.tools.dotc.core.Denotations.SingleDenotation
69
import dotty.tools.dotc.core.Phases.Phase
10+
import dotty.tools.dotc.core.SymDenotations.SymDenotation
711
import dotty.tools.dotc.core.Symbols.Symbol
812
import dotty.tools.dotc.core.Flags.PackageVal
913
import dotty.tools.dotc.typer.Mode
@@ -170,10 +174,24 @@ object TreeTransforms {
170174
}
171175

172176
/** A helper trait to transform annotations on MemberDefs */
173-
trait AnnotationTransformer extends MiniPhaseTransform {
177+
trait AnnotationTransformer extends MiniPhaseTransform with InfoTransformer {
174178

175179
val annotationTransformer = mkTreeTransformer
176180

181+
override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
182+
val info1 = transformInfo(ref.info, ref.symbol)
183+
184+
ref match {
185+
case ref: SymDenotation =>
186+
val annotTrees = ref.annotations.map(_.tree)
187+
val annotTrees1 = annotTrees.mapConserve(annotationTransformer.transform)
188+
val annots1 = if(annotTrees eq annotTrees1) ref.annotations else annotTrees1.map(new ConcreteAnnotation(_))
189+
if ((info1 eq ref.info) && (annots1 eq ref.annotations)) ref
190+
else ref.copySymDenotation(info = info1, annotations = annots1)
191+
case _ => if (info1 eq ref.info) ref else ref.derivedSingleDenotation(ref.symbol, info1)
192+
}
193+
}
194+
177195
def transformAnnotations(tree: MemberDef)(implicit ctx: Context): MemberDef ={
178196
val newAnnots = tree.mods.annotations.mapConserve(annotationTransformer.transform)
179197
if (newAnnots eq tree.mods.annotations) tree

0 commit comments

Comments
 (0)