Skip to content

Commit

Permalink
Add support for clauseInterleaving in JVM generic signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed Oct 5, 2024
1 parent ebbd685 commit c91e16f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 27 deletions.
56 changes: 29 additions & 27 deletions compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
3 changes: 3 additions & 0 deletions tests/run/i21346.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<X;Y;Z;A>
(X,Y,Z)
class scala.runtime.Nothing$
10 changes: 10 additions & 0 deletions tests/run/i21346.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// scalajs: --skip

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())

0 comments on commit c91e16f

Please sign in to comment.