Skip to content

Commit 60b52b7

Browse files
committed
Add support for clauseInterleaving in JVM generic signatures
1 parent ebbd685 commit 60b52b7

File tree

3 files changed

+41
-27
lines changed

3 files changed

+41
-27
lines changed

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

+29-27
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import config.Printers.transforms
1919
import reporting.trace
2020
import java.lang.StringBuilder
2121

22+
import scala.annotation.tailrec
2223
import scala.collection.mutable.ListBuffer
2324

2425
/** Helper object to generate generic java signatures, as defined in
@@ -294,36 +295,13 @@ object GenericSignatures {
294295
case ExprType(restpe) =>
295296
jsig(defn.FunctionType(0).appliedTo(restpe))
296297

297-
case PolyType(tparams, mtpe: MethodType) =>
298-
assert(tparams.nonEmpty)
298+
case mtd: MethodOrPoly =>
299+
val (tparams, vparams, rte) = collectMethodParams(mtd)
299300
if (toplevel && !sym0.isConstructor) polyParamSig(tparams)
300-
jsig(mtpe)
301-
302-
// Nullary polymorphic method
303-
case PolyType(tparams, restpe) =>
304-
assert(tparams.nonEmpty)
305-
if (toplevel) polyParamSig(tparams)
306-
builder.append("()")
307-
methodResultSig(restpe)
308-
309-
case mtpe: MethodType =>
310-
// erased method parameters do not make it to the bytecode.
311-
def effectiveParamInfoss(t: Type)(using Context): List[List[Type]] = t match {
312-
case t: MethodType if t.hasErasedParams =>
313-
t.paramInfos.zip(t.erasedParams).collect{ case (i, false) => i }
314-
:: effectiveParamInfoss(t.resType)
315-
case t: MethodType => t.paramInfos :: effectiveParamInfoss(t.resType)
316-
case _ => Nil
317-
}
318-
val params = effectiveParamInfoss(mtpe).flatten
319-
val restpe = mtpe.finalResultType
320301
builder.append('(')
321-
// TODO: Update once we support varargs
322-
params.foreach { tp =>
323-
jsig(tp)
324-
}
302+
for vparam <- vparams do jsig(vparam)
325303
builder.append(')')
326-
methodResultSig(restpe)
304+
methodResultSig(rte)
327305

328306
case tp: AndType =>
329307
// Only intersections appearing as the upper-bound of a type parameter
@@ -475,4 +453,28 @@ object GenericSignatures {
475453
}
476454
else x
477455
}
456+
457+
private def collectMethodParams(mtd: MethodOrPoly)(using Context): (List[TypeParamInfo], List[Type], Type) =
458+
val tparams = ListBuffer.empty[TypeParamInfo]
459+
val vparams = ListBuffer.empty[Type]
460+
461+
@tailrec def recur(mtd: MethodOrPoly): Type = mtd match
462+
case mtd: MethodType => mtd.resType match
463+
case ret: MethodOrPoly =>
464+
vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot))
465+
recur(ret)
466+
case tpe =>
467+
vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot))
468+
tpe
469+
case PolyType(tps, mtpe: MethodType) =>
470+
tparams ++= tps
471+
recur(mtpe)
472+
case PolyType(tps, tpe) =>
473+
tparams ++= tps
474+
tpe
475+
end recur
476+
477+
val rte = recur(mtd)
478+
(tparams.toList, vparams.toList, rte)
479+
end collectMethodParams
478480
}

tests/run/i21346.check

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<X;Y;Z;A>
2+
(X,Y,Z)
3+
class scala.runtime.Nothing$

tests/run/i21346.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
object Foo:
3+
def foo[X, Y, Z](x: X, y: Y)[A](z: Z) = ???
4+
5+
@main def Test =
6+
val mtd = Foo.getClass().getDeclaredMethods().filter(_.getName() == "foo")(0)
7+
println(mtd.getTypeParameters().mkString("<", ";", ">"))
8+
println(mtd.getGenericParameterTypes().mkString("(", ",", ")"))
9+
println(mtd.getGenericReturnType())

0 commit comments

Comments
 (0)