@@ -28,34 +28,7 @@ class ErasurePreservation extends MiniPhase {
2828
2929 override def description : String = ErasurePreservation .description
3030
31- def getOuterTyParamSyms (sym : Symbol )(using Context ): List [Symbol ] =
32- if ! sym.exists then List ()
33- else getOuterTyParamSyms(sym.owner) ++ (sym.paramSymss.flatten)
34-
35- def typeParamToTypeBKM (tr : TypeRef , sourceSym : Symbol )(using Context ): TypeB = trace.force(i " ${tr}, ${tr.symbol.owner}" ){
36- val outerTyParams = getOuterTyParamSyms(sourceSym)
37- val owner = tr.symbol.owner
38- if owner.isClass then
39- val ind = (outerTyParams++ owner.typeParams).indexOf(tr.symbol)
40- val n = debrujin(sourceSym.enclosingClass, owner)
41- if ind != - 1 then TypeB .K (n, ind) else TypeB .None
42- else
43- val ind = (outerTyParams++ owner.paramSymss.flatten).indexWhere(tr.isRef(_))
44- if ind != - 1 then TypeB .M (ind) else TypeB .None
45- }
46-
47- def typeParamToTypeAKM (tr : TypeRef , sourceSym : Symbol )(using Context ): TypeA =
48- val outerTyParams = getOuterTyParamSyms(sourceSym)
49- val owner = tr.symbol.owner
50- if owner.isClass then
51- val ind = (outerTyParams++ owner.typeParams).indexOf(tr.symbol)
52- val n = debrujin(sourceSym.enclosingClass, owner)
53- if ind != - 1 then TypeA .K (n, ind) else ???
54- else
55- val ind = (outerTyParams++ owner.paramSymss.flatten).indexWhere(tr.isRef(_))
56- if ind != - 1 then TypeA .M (ind) else ???
57-
58- def toTypeA (tp : Type , sourceSym : Symbol )(using Context ): TypeA = trace(i " toTypeA ${tp}, ${sourceSym}" ) {tp.widen match
31+ def toTypeA (tp : Type , outers : List [List [Symbol ]])(using Context ): TypeA = trace(i " toTypeA ${tp}" ){ tp.widen match
5932 case tpr : TypeParamRef => TypeA .M (tpr.paramNum)
6033 case tr : TypeRef =>
6134 // println(tr.symbol.owner.paramSymss)
@@ -68,72 +41,106 @@ class ErasurePreservation extends MiniPhase {
6841 if tr.isRef(defn.ShortClass ) then TypeA .Short else
6942 if tr.isRef(defn.BooleanClass ) then TypeA .Boolean else
7043 if tr.symbol.isTypeParam then
71- typeParamToTypeAKM(tr, sourceSym)
44+ def search (tr : TypeRef , depth : Int , outers : List [List [Symbol ]]): TypeA =
45+ outers.head.indexOf(tr.symbol) match
46+ case - 1 =>
47+ search(tr, depth+ 1 , outers.tail)
48+ case ind =>
49+ if depth != 0 then
50+ TypeA .K (depth- 1 , ind)
51+ else
52+ TypeA .M (ind)
53+ search(tr, 0 , outers)
7254 else TypeA .Ref
7355 case _ =>
7456 TypeA .Ref
7557 }
7658
77- def debrujin (source : Symbol , outer : Symbol )(using Context ): Int = trace(i " debrujin: $source, $outer" ) {
78- if (source.enclosingClass == outer) then 0
79- else
80- // println(s"$source, $outer, ${outer.owner}")
81- debrujin(source.owner, outer)+ 1
82- }
59+ def indexTypeParam (method : Type , tpr : TypeParamRef ): Int = method match
60+ case pt : PolyType =>
61+ if tpr.binder == pt then
62+ tpr.paramNum
63+ else indexTypeParam(pt.resType, tpr) + pt.paramNames.size
64+ case mt : MethodType => indexTypeParam(mt.resType, tpr)
65+ case _ => ???
66+
8367
84- def toTypeB (tp : Type , sourceSym : Symbol , method : Type )(using Context ): TypeB = trace.force(i " toTypeB ${tp}, ${sourceSym }" ){ tp match
68+ def toTypeB (tp : Type , outers : List [ List [ Symbol ]] )(using Context ): TypeB = trace.force(i " toTypeB ${tp}, ${outers }" ){ tp match
8569 case tpr : TypeParamRef =>
86- val outerTyParams = getOuterTyParamSyms(sourceSym)
87- TypeB .M (outerTyParams.length+ indexTypeParam(method, tpr))
70+ TypeB .M (outers.head.indexWhere(sym => sym.name == tpr.paramName))
8871 case tr : TypeRef if tr.symbol.isTypeParam =>
89- typeParamToTypeBKM(tr, sourceSym)
72+ def search (tr : TypeRef , depth : Int , outers : List [List [Symbol ]]): TypeB =
73+ outers.head.indexOf(tr.symbol) match
74+ case - 1 =>
75+ search(tr, depth+ 1 , outers.tail)
76+ case ind =>
77+ if depth != 0 then
78+ TypeB .K (depth- 1 , ind)
79+ else
80+ TypeB .M (ind)
81+ search(tr, 0 , outers)
9082 case _ => TypeB .None
9183 }
9284
9385 def toReturnTypeB (tp : Type , sourceSym : Symbol )(using Context ): TypeB = tp match
9486 case tr : TypeRef if tr.symbol.isTypeParam =>
95- typeParamToTypeBKM(tr, sourceSym)
87+ ???
9688 case _ => TypeB .None
9789
98- def indexTypeParam (method : Type , tpr : TypeParamRef ): Int = method match
99- case pt : PolyType =>
100- if tpr.binder == pt then
101- tpr.paramNum
102- else indexTypeParam(pt.resType, tpr) + pt.paramNames.size
103- case mt : MethodType => indexTypeParam(mt.resType, tpr)
104- case _ => ???
90+
91+ /**
92+ * Return all outer type parameters that originate from a method
93+ * until we reach a class
94+ */
95+ def getOuterParamss (sym : Symbol , isConstructor : Boolean )(using Context ): List [List [Symbol ]] = trace.force(i " getOuterParamss ${sym}" ) {
96+ if ! sym.exists then List (List ())
97+ else if sym.isClass && isConstructor then
98+ // println(sym.typeParams)
99+ val outers = getOuterParamss(sym.owner, false )
100+ (outers.head ++ sym.typeParams) :: outers.tail
101+ else if sym.isClass then
102+ val outers = getOuterParamss(sym.owner, false )
103+ List () :: (outers.head ++ sym.typeParams) :: outers.tail
104+ else
105+ val tyParams = sym.paramSymss.headOption
106+ val outers = getOuterParamss(sym.owner, false )
107+ tyParams match
108+ case Some (tps) =>
109+ (outers.head ++ sym.paramSymss.headOption.getOrElse(List ())) :: outers.tail
110+ case None => outers
111+ }
112+
113+ def methodToInfos (
114+ params : List [Type ],
115+ resType : Type ,
116+ tyParams : List [Symbol ],
117+ isConstructor : Boolean )(using Context ): Tuple3 [Int , List [TypeB ], TypeB ] = trace.force(i " methodToInfos ${params}, ${resType}" )
118+ {
119+ var outers = getOuterParamss(ctx.owner, isConstructor)
120+ if (! isConstructor)
121+ outers = outers.head ++ tyParams :: outers.tail
122+ val paramsTypeB : List [TypeB ] = params.map(tp => toTypeB(tp, outers))
123+ val ret : TypeB = toTypeB(resType, outers)
124+ (outers.head.length, paramsTypeB, ret)
125+ }
126+
105127
106128 override def transformDefDef (tree : tpd.DefDef )(using Context ): tpd.Tree = trace.force(i " transformDefDef $tree, ${tree.tpe}, ${tree.tpe.widen}" ){
107- val tup = tree.tpe.widen match
129+ val tup : Tuple3 [ Int , List [ TypeB ], TypeB ] = tree.tpe.widen match
108130 case pt : PolyType => pt.resType match
109131 case mt : MethodType =>
110- // println(mt.paramInfos)
111- // println(mt.paramInfoss)
112- // println(tree.tpe.widen)
113- val ptParams = pt.paramInfoss.flatten
114- Some ((ptParams.size, mt.paramInfoss.flatten.map(p => toTypeB(p, ctx.owner, pt)), toTypeB(mt.resType, ctx.owner, pt)))
132+ methodToInfos(mt.paramInfos, mt.resType, tree.symbol.paramSymss.head, tree.symbol.isConstructor)
115133 case other =>
116- Some ((pt.paramInfoss.flatten.size, Nil , toTypeB( other.widenExpr, ctx.owner, pt)) )
134+ methodToInfos( Nil , other.widenExpr, tree.symbol.paramSymss.head, tree.symbol.isConstructor )
117135 case mt : MethodType =>
118- val params = mt.paramInfos.map(p => toTypeB(p, ctx.owner, mt))
119- val ret = toTypeB(mt.resType, ctx.owner, mt)
120- if (params.exists(_ != TypeB .None ) || ret != TypeB .None ) then
121- Some ((0 , params, ret))
122- else
123- None
136+ methodToInfos(mt.paramInfos, mt.resType, Nil , false )
124137 // case tr: TypeRef => Some((0, Nil, toTypeB(tr, ctx.owner)))
125138 case et : ExprType =>
126139 ???
127- val ret = toTypeB(et.widenExpr, ctx.owner, ??? )
128- if (ret != TypeB .None ) then
129- Some ((0 , Nil , ret))
130- else
131- None
132- case other => None
133- if tup.isDefined then
134- val outerTyParams = getOuterTyParamSyms(ctx.owner)
135- val (paramCount, paramRefs, retType) = tup.get
136- tree.putAttachment(MethodParameterReturnType , (paramCount+ outerTyParams.length, paramRefs, retType))
140+ case other =>
141+ ???
142+ val (paramCount, paramRefs, retType) = tup
143+ tree.putAttachment(MethodParameterReturnType , (paramCount, paramRefs, retType))
137144 tree
138145 }
139146
@@ -143,8 +150,9 @@ class ErasurePreservation extends MiniPhase {
143150 }
144151
145152 override def transformTypeApply (tree : tpd.TypeApply )(using Context ): tpd.Tree = trace(i " transfromTypeApply ${tree}" ) {
146- val args = tree.args.map(_.tpe).map(p => toTypeA(p, ctx.owner))
147- tree.fun.putAttachment(InstructionTypeArguments , args) // Pattern match args based on their types
153+ val outers = getOuterParamss(ctx.owner, false )
154+ val args = tree.args.map(_.tpe).map(p => toTypeA(p, outers))
155+ tree.fun.putAttachment(InstructionTypeArguments , args)
148156 tree
149157 }
150158
0 commit comments