From 60b52b7e13c8bd3580625a7b5ca0071de6a3c833 Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Sat, 5 Oct 2024 13:55:59 +0200 Subject: [PATCH] Add support for clauseInterleaving in JVM generic signatures --- .../dotc/transform/GenericSignatures.scala | 56 ++++++++++--------- tests/run/i21346.check | 3 + tests/run/i21346.scala | 9 +++ 3 files changed, 41 insertions(+), 27 deletions(-) create mode 100644 tests/run/i21346.check create mode 100644 tests/run/i21346.scala diff --git a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala index b5b75450272c..a61de28eec5d 100644 --- a/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala +++ b/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala @@ -19,6 +19,7 @@ import config.Printers.transforms import reporting.trace import java.lang.StringBuilder +import scala.annotation.tailrec import scala.collection.mutable.ListBuffer /** Helper object to generate generic java signatures, as defined in @@ -294,36 +295,13 @@ object GenericSignatures { case ExprType(restpe) => jsig(defn.FunctionType(0).appliedTo(restpe)) - case PolyType(tparams, mtpe: MethodType) => - assert(tparams.nonEmpty) + case mtd: MethodOrPoly => + val (tparams, vparams, rte) = collectMethodParams(mtd) if (toplevel && !sym0.isConstructor) polyParamSig(tparams) - jsig(mtpe) - - // Nullary polymorphic method - case PolyType(tparams, restpe) => - assert(tparams.nonEmpty) - if (toplevel) polyParamSig(tparams) - builder.append("()") - methodResultSig(restpe) - - case mtpe: MethodType => - // erased method parameters do not make it to the bytecode. - def effectiveParamInfoss(t: Type)(using Context): List[List[Type]] = t match { - case t: MethodType if t.hasErasedParams => - t.paramInfos.zip(t.erasedParams).collect{ case (i, false) => i } - :: effectiveParamInfoss(t.resType) - case t: MethodType => t.paramInfos :: effectiveParamInfoss(t.resType) - case _ => Nil - } - val params = effectiveParamInfoss(mtpe).flatten - val restpe = mtpe.finalResultType builder.append('(') - // TODO: Update once we support varargs - params.foreach { tp => - jsig(tp) - } + for vparam <- vparams do jsig(vparam) builder.append(')') - methodResultSig(restpe) + methodResultSig(rte) case tp: AndType => // Only intersections appearing as the upper-bound of a type parameter @@ -475,4 +453,28 @@ object GenericSignatures { } else x } + + private def collectMethodParams(mtd: MethodOrPoly)(using Context): (List[TypeParamInfo], List[Type], Type) = + val tparams = ListBuffer.empty[TypeParamInfo] + val vparams = ListBuffer.empty[Type] + + @tailrec def recur(mtd: MethodOrPoly): Type = mtd match + case mtd: MethodType => mtd.resType match + case ret: MethodOrPoly => + vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot)) + recur(ret) + case tpe => + vparams ++= mtd.paramInfos.filterNot(_.hasAnnotation(defn.ErasedParamAnnot)) + tpe + case PolyType(tps, mtpe: MethodType) => + tparams ++= tps + recur(mtpe) + case PolyType(tps, tpe) => + tparams ++= tps + tpe + end recur + + val rte = recur(mtd) + (tparams.toList, vparams.toList, rte) + end collectMethodParams } diff --git a/tests/run/i21346.check b/tests/run/i21346.check new file mode 100644 index 000000000000..7e175ecd8c62 --- /dev/null +++ b/tests/run/i21346.check @@ -0,0 +1,3 @@ + +(X,Y,Z) +class scala.runtime.Nothing$ diff --git a/tests/run/i21346.scala b/tests/run/i21346.scala new file mode 100644 index 000000000000..2c17be4b6dda --- /dev/null +++ b/tests/run/i21346.scala @@ -0,0 +1,9 @@ + +object Foo: + def foo[X, Y, Z](x: X, y: Y)[A](z: Z) = ??? + +@main def Test = + val mtd = Foo.getClass().getDeclaredMethods().filter(_.getName() == "foo")(0) + println(mtd.getTypeParameters().mkString("<", ";", ">")) + println(mtd.getGenericParameterTypes().mkString("(", ",", ")")) + println(mtd.getGenericReturnType()) \ No newline at end of file