@@ -18,42 +18,87 @@ import typer.NoChecking
1818import ast .{tpd , untpd }
1919import reporting .*
2020import dotty .tools .dotc .transform .MegaPhase .MiniPhase
21+ import dotty .tools .dotc .util .Property
2122
22- class ErasurePreservation extends MiniPhase {
23+ class ErasurePreservation extends MiniPhase with InfoTransformer {
2324
2425 override def phaseName : String = ErasurePreservation .name
2526
2627 override def description : String = ErasurePreservation .description
2728
28- override def transformDefDef (tree : tpd.DefDef )(using Context ): tpd.Tree =
29- val sym = tree.symbol
30- sym.info match
29+ def toTypeA (tp : Type )(using Context ): TypeA = trace(s " toTypeA ${tp}" ) {tp match
30+ case tpr : TypeParamRef => TypeA .M (tpr.paramNum)
31+ case tr : TypeRef =>
32+ // println(tr.symbol.owner.paramSymss)
33+ if tr.isRef(defn.IntClass ) then TypeA .Int else
34+ if tr.symbol.isTypeParam then
35+ val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
36+ if ind != - 1 then TypeA .M (ind)
37+ else TypeA .Ref
38+ else TypeA .Ref
39+ case _ => assert(false )
40+ }
41+
42+
43+ def toTypeB (tp : Type )(using Context ): TypeB = tp match
44+ case tpr : TypeParamRef => TypeB .M (tpr.paramNum)
45+ case _ => TypeB .None
46+
47+ def toReturnTypeB (tp : Type )(using Context ): TypeB = tp match
48+ case tr : TypeRef =>
49+ // println(tr.symbol.owner.paramSymss)
50+ if tr.symbol.isTypeParam then
51+ val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
52+ if ind != - 1 then TypeB .M (ind)
53+ else TypeB .None
54+ else TypeB .None
55+ case _ => TypeB .None
56+
57+
58+ override def transformInfo (tp : Type , sym : Symbol )(using Context ): Type =
59+ tp match
3160 case pt : PolyType =>
32- def toTypeB (tp : Type ): TypeB = tp match
33- case tpr : TypeParamRef => TypeB .M (tpr.paramNum)
34- case _ => TypeB .None
3561 pt.resType match
3662 case mt : MethodType =>
3763 sym.addAnnotation(ErasedInfo (pt.paramInfos.size, mt.paramInfos.map(toTypeB), toTypeB(mt.resType)))
3864 case other =>
3965 sym.addAnnotation(ErasedInfo (pt.paramInfos.size, Nil , toTypeB(other.widenExpr)))
4066 case _ => ()
67+ tp
68+
69+ override def transformApply (tree : tpd.Apply )(using Context ): tpd.Tree =
70+ tree.putAttachment(InvokeReturnType , toReturnTypeB(tree.tpe))
4171 tree
72+
73+ override def transformTypeApply (tree : tpd.TypeApply )(using Context ): tpd.Tree =
74+ val args = tree.args.map(_.tpe).map(toTypeA)
75+ tree.fun.putAttachment(InstructionTypeArguments , args) // Pattern match args based on their types
76+ tree
77+
4278}
4379
4480object ErasurePreservation {
4581 val name : String = " erasure preservation"
4682 val description : String = " preserve information in annotations before erasure"
4783}
4884
85+ enum TypeA :
86+ case Int
87+ case M (x : Int )
88+ case K (x : Int )
89+ case Ref
90+
4991enum TypeB :
5092 case None
5193 case M (x : Int )
5294// case class TypeB(tp: Type)
5395
96+ object InstructionTypeArguments extends Property .StickyKey [List [TypeA ]]
97+ object InvokeReturnType extends Property .StickyKey [TypeB ]
98+
5499class ErasedInfo (paramCount : Int , paramType : List [TypeB ], returnType : TypeB ) extends Annotation {
55100 override def tree (using Context ) =
56- tpd.New (defn.SourceFileAnnot .typeRef,
101+ tpd.New (defn.ErasurePreservationAnnot .typeRef,
57102 List (tpd.Literal (Constant (toString))))
58103
59104 override def toString =
0 commit comments