Skip to content

Commit 5d7faed

Browse files
committed
merging erasure-annot to insertAttr
2 parents ef088f9 + 6b5b4fa commit 5d7faed

File tree

4 files changed

+86
-37
lines changed

4 files changed

+86
-37
lines changed

compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ trait BCodeHelpers extends BCodeIdiomatic {
221221
val av = cw.visitAnnotation(typeDescriptor(typ), isRuntimeVisible(annot))
222222
emitAssocs(av, assocs, BCodeHelpers.this)(this)
223223
}
224-
225-
def toJTypeB(tpe: dotty.tools.dotc.transform.TypeB): TypeHints.TypeB =
224+
225+
def toJTypeB(tpe: dotty.tools.dotc.transform.TypeB): TypeHints.TypeB =
226226
tpe match
227227
case dotty.tools.dotc.transform.TypeB.None => TypeHints.TypeB.NO_HINT
228228
case dotty.tools.dotc.transform.TypeB.M(index) => new TypeHints.TypeB(TypeHints.TypeB.M_KIND, index)
229229
case dotty.tools.dotc.transform.TypeB.K(y, x) => new TypeHints.TypeB(TypeHints.TypeB.K_KIND, y, x)
230230

231-
def addMethodTypeParameterCountAttribute(mw: asm.MethodVisitor, count: Int): Unit =
231+
def addMethodTypeParameterCountAttribute(mw: asm.MethodVisitor, count: Int): Unit =
232232
if (count > 0){
233233
val attr = new MethodTypeParameterCount(count)
234234
mw.visitAttribute(attr)
@@ -248,7 +248,8 @@ trait BCodeHelpers extends BCodeIdiomatic {
248248
}
249249

250250

251-
def addMethodParameterTypeAttribute(mw: asm.MethodVisitor, lst: List[dotty.tools.dotc.transform.TypeB]) : Unit =
251+
252+
def addMethodParameterTypeAttribute(mw: asm.MethodVisitor, lst: List[dotty.tools.dotc.transform.TypeB]) : Unit =
252253
if (lst.isEmpty) return
253254
val lstJTypeB = lst.map(toJTypeB)
254255
val len = lstJTypeB.length

compiler/src/dotty/tools/backend/jvm/BCodeIdiomatic.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,13 @@ trait BCodeIdiomatic {
426426
emitInvoke(Opcodes.INVOKEVIRTUAL, owner, name, desc, itf = false)
427427
}
428428

429-
def toJTypeB(tpe: dotty.tools.dotc.transform.TypeB): TypeHints.TypeB =
429+
def toJTypeB(tpe: dotty.tools.dotc.transform.TypeB): TypeHints.TypeB =
430430
tpe match
431431
case dotty.tools.dotc.transform.TypeB.None => TypeHints.TypeB.NO_HINT
432432
case dotty.tools.dotc.transform.TypeB.M(index) => new TypeHints.TypeB(TypeHints.TypeB.M_KIND, index)
433433
case dotty.tools.dotc.transform.TypeB.K(y, x) => new TypeHints.TypeB(TypeHints.TypeB.K_KIND, y, x)
434434

435-
def toJTypeA(tpe: dotty.tools.dotc.transform.TypeA): TypeHints.TypeA =
435+
def toJTypeA(tpe: dotty.tools.dotc.transform.TypeA): TypeHints.TypeA =
436436
tpe match
437437
case dotty.tools.dotc.transform.TypeA.Byte => TypeHints.TypeA.TYPEA_BYTE
438438
case dotty.tools.dotc.transform.TypeA.Char => TypeHints.TypeA.TYPEA_CHAR
@@ -445,9 +445,9 @@ trait BCodeIdiomatic {
445445
case dotty.tools.dotc.transform.TypeA.M(x) => TypeHints.TypeA(TypeHints.TypeA.M_KIND, x)
446446
case dotty.tools.dotc.transform.TypeA.K(y, x) => TypeHints.TypeA(TypeHints.TypeA.K_KIND, y, x)
447447
case dotty.tools.dotc.transform.TypeA.Ref => TypeHints.TypeA.TYPEA_REFERENCE
448-
449448

450-
def emitInvoke(opcode: Int, owner: String, name: String, desc: String, itf: Boolean,
449+
450+
def emitInvoke(opcode: Int, owner: String, name: String, desc: String, itf: Boolean,
451451
invokeReturnType : Option[dotty.tools.dotc.transform.TypeB] = None, instrTypeArgs : Option[List[dotty.tools.dotc.transform.TypeA]] = None): Unit = {
452452
val node = new MethodInsnNode(opcode, owner, name, desc, itf)
453453
jmethod.instructions.add(node)

compiler/src/dotty/tools/dotc/transform/ErasurePreservation.scala

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,69 +19,113 @@ import ast.{tpd, untpd}
1919
import reporting.*
2020
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
2121
import dotty.tools.dotc.util.Property
22+
import dotty.tools.dotc.cc.pathOwner
23+
import scala.annotation.tailrec
2224

2325
class ErasurePreservation extends MiniPhase with InfoTransformer {
2426

2527
override def phaseName: String = ErasurePreservation.name
2628

2729
override def description: String = ErasurePreservation.description
2830

29-
def toTypeA(tp: Type)(using Context): TypeA = trace(s"toTypeA ${tp}") {tp match
31+
def toTypeA(tp: Type, sourceSym: Symbol)(using Context): TypeA = trace(s"toTypeA ${tp}") {tp match
3032
case tpr: TypeParamRef => TypeA.M(tpr.paramNum)
3133
case tr: TypeRef =>
3234
// println(tr.symbol.owner.paramSymss)
3335
if tr.isRef(defn.ByteClass) then TypeA.Byte else
3436
if tr.isRef(defn.CharClass) then TypeA.Char else
35-
if tr.isRef(defn.DoubleClass) then TypeA.Double else
36-
if tr.isRef(defn.FloatClass) then TypeA.Float else
37+
if tr.isRef(defn.DoubleClass) then TypeA.Double else
38+
if tr.isRef(defn.FloatClass) then TypeA.Float else
3739
if tr.isRef(defn.IntClass) then TypeA.Int else
38-
if tr.isRef(defn.LongClass) then TypeA.Long else
40+
if tr.isRef(defn.LongClass) then TypeA.Long else
3941
if tr.isRef(defn.ShortClass) then TypeA.Short else
40-
if tr.isRef(defn.BooleanClass) then TypeA.Boolean else
42+
if tr.isRef(defn.BooleanClass) then TypeA.Boolean else
4143
if tr.symbol.isTypeParam then
42-
val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
43-
if ind != -1 then TypeA.M(ind)
44-
else TypeA.Ref
44+
val owner = tr.symbol.owner
45+
if owner.isClass then
46+
val ind = owner.typeParams.indexOf(tr.symbol)
47+
val n = debrujin(sourceSym.enclosingClass, owner)
48+
if ind != -1 then TypeA.K(n, ind) else ???
49+
else
50+
val ind = owner.paramSymss.headOption match
51+
case None => assert(false, i"Got unexpected type ${tp}")
52+
case Some(value) => value.indexWhere(tr.isRef(_))
53+
if ind != -1 then TypeA.M(ind) else ???
4554
else TypeA.Ref
4655
case _ => assert(false)
4756
}
4857

58+
def debrujin(source: Symbol, outer: Symbol)(using Context): Int = trace(i"debrujin: $source, $outer") {
59+
if (source.enclosingClass == outer) then 0
60+
else debrujin(source.owner, outer)+1
61+
}
4962

50-
def toTypeB(tp: Type)(using Context): TypeB = tp match
63+
def toTypeB(tp: Type, sourceSym: Symbol)(using Context): TypeB = trace(i"toTypeB ${tp}"){ tp match
5164
case tpr: TypeParamRef => TypeB.M(tpr.paramNum)
65+
case tr: TypeRef if tr.symbol.isTypeParam =>
66+
val owner = tr.symbol.owner
67+
if owner.isClass then
68+
val ind = owner.typeParams.indexOf(tr.symbol)
69+
val n = debrujin(sourceSym.enclosingClass, owner)
70+
if ind != -1 then TypeB.K(n, ind) else TypeB.None
71+
else
72+
val ind = owner.paramSymss.headOption match
73+
case None => assert(false, i"Got unexpected type ${tp}")
74+
case Some(value) => value.indexWhere(tr.isRef(_))
75+
if ind != -1 then TypeB.M(ind) else TypeB.None
5276
case _ => TypeB.None
77+
}
5378

54-
def toReturnTypeB(tp: Type)(using Context): TypeB = tp match
55-
case tr: TypeRef =>
56-
// println(tr.symbol.owner.paramSymss)
57-
if tr.symbol.isTypeParam then
58-
val ind = tr.symbol.owner.paramSymss.head.indexWhere(tr.isRef(_))
59-
if ind != -1 then TypeB.M(ind)
60-
else TypeB.None
61-
else TypeB.None
79+
def toReturnTypeB(tp: Type, sourceSym: Symbol)(using Context): TypeB = tp match
80+
case tr: TypeRef if tr.symbol.isTypeParam =>
81+
val owner = tr.symbol.owner
82+
if owner.isClass then
83+
val ind = owner.typeParams.indexOf(tr.symbol)
84+
val n = debrujin(sourceSym.enclosingClass, owner)
85+
if ind != -1 then TypeB.K(n, ind) else TypeB.None
86+
else
87+
val ind = owner.paramSymss.headOption match
88+
case None => assert(false, i"Got unexpected type ${tp}")
89+
case Some(value) => value.indexWhere(tr.isRef(_))
90+
if ind != -1 then TypeB.M(ind) else TypeB.None
6291
case _ => TypeB.None
6392

64-
65-
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type =
93+
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = trace(i"transformInfo ${tp}, ${sym}") {
6694
tp match
6795
case pt: PolyType =>
6896
pt.resType match
6997
case mt: MethodType =>
70-
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, mt.paramInfos.map(toTypeB), toTypeB(mt.resType)))
98+
// println(i"sym context: $sym, ${sym.enclosingClass}, ${sym.enclosingClass.owner}")
99+
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, mt.paramInfos.map(p => toTypeB(p, sym)), toTypeB(mt.resType, sym)))
71100
case other =>
72-
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, Nil, toTypeB(other.widenExpr)))
73-
case _ => ()
101+
sym.addAnnotation(ErasedInfo(pt.paramInfos.size, Nil, toTypeB(other.widenExpr, sym)))
102+
case mt: MethodType =>
103+
val params = mt.paramInfos.map(p => toTypeB(p, sym))
104+
val ret = toTypeB(mt.resType, sym)
105+
if (params.exists(_ != TypeB.None) || ret != TypeB.None) then
106+
sym.addAnnotation(ErasedInfo(0, params, ret))
107+
case et: ExprType =>
108+
val ret = toTypeB(et.widenExpr, sym)
109+
if (ret != TypeB.None) then
110+
sym.addAnnotation(ErasedInfo(0, Nil, ret))
111+
()
112+
case other =>
74113
tp
114+
}
75115

76116
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree =
77-
tree.putAttachment(InvokeReturnType, toReturnTypeB(tree.tpe))
117+
tree.putAttachment(InvokeReturnType, toReturnTypeB(tree.tpe, tree.symbol))
78118
tree
79119

80120
override def transformTypeApply(tree: tpd.TypeApply)(using Context): tpd.Tree =
81-
val args = tree.args.map(_.tpe).map(toTypeA)
121+
val args = tree.args.map(_.tpe).map(p => toTypeA(p, tree.symbol))
82122
tree.fun.putAttachment(InstructionTypeArguments, args) // Pattern match args based on their types
83123
tree
84124

125+
// override def transformTypeDef(tree: tpd.TypeDef)(using Context): tpd.Tree =
126+
// println(s"$tree")
127+
// tree
128+
85129
}
86130

87131
object ErasurePreservation {
@@ -98,14 +142,18 @@ enum TypeA:
98142
case Long
99143
case Short
100144
case Boolean
101-
case M(x: Int)
102-
case K(y: Int, x: Int)
145+
case M(paramNum: Int)
146+
case K(
147+
outer: Int,
148+
paramNum: Int)
103149
case Ref
104150

105151
enum TypeB:
106152
case None
107-
case M(x: Int)
108-
case K(y: Int, x: Int)
153+
case M(paramNum: Int)
154+
case K(
155+
outer: Int,
156+
paramNum: Int)
109157
// case class TypeB(tp: Type)
110158

111159
object InstructionTypeArguments extends Property.StickyKey[List[TypeA]]

compiler/src/dotty/tools/dotc/transform/Mixin.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
226226
case _ =>
227227
val Apply(sel @ Select(New(_), nme.CONSTRUCTOR), args) = tree: @unchecked
228228
val (callArgs, initArgs) = if (tree.symbol.owner.is(Trait)) (Nil, args) else (args, Nil)
229-
(superRef(tree.symbol, tree.span).appliedToTermArgs(callArgs), Nil, initArgs)
229+
(superRef(tree.symbol, tree.span).appliedToTermArgs(callArgs).withAttachmentsFrom(sel), Nil, initArgs)
230230
}
231231

232232
val superCallsAndArgs: Map[Symbol, (Tree, List[Tree], List[Tree])] = (

0 commit comments

Comments
 (0)