@@ -280,15 +280,13 @@ class ClassfileParser(
280
280
addConstructorTypeParams(denot)
281
281
}
282
282
283
- denot.info = pool.getType(in.nextChar)
283
+ val isVarargs = denot.is(Flags .Method ) && (jflags & JAVA_ACC_VARARGS ) != 0
284
+ denot.info = pool.getType(in.nextChar, isVarargs)
284
285
if (isEnum) denot.info = ConstantType (Constant (sym))
285
286
if (isConstructor) normalizeConstructorParams()
286
- denot.info = translateTempPoly(parseAttributes(sym, denot.info))
287
+ denot.info = translateTempPoly(parseAttributes(sym, denot.info, isVarargs ))
287
288
if (isConstructor) normalizeConstructorInfo()
288
289
289
- if (denot.is(Flags .Method ) && (jflags & JAVA_ACC_VARARGS ) != 0 )
290
- denot.info = arrayToRepeated(denot.info)
291
-
292
290
if (ctx.explicitNulls) denot.info = JavaNullInterop .nullifyMember(denot.symbol, denot.info, isEnum)
293
291
294
292
// seal java enums
@@ -324,7 +322,7 @@ class ClassfileParser(
324
322
case BOOL_TAG => defn.BooleanType
325
323
}
326
324
327
- private def sigToType (sig : SimpleName , owner : Symbol = null )(using Context ): Type = {
325
+ private def sigToType (sig : SimpleName , owner : Symbol = null , isVarargs : Boolean = false )(using Context ): Type = {
328
326
var index = 0
329
327
val end = sig.length
330
328
def accept (ch : Char ): Unit = {
@@ -395,13 +393,42 @@ class ClassfileParser(
395
393
val elemtp = sig2type(tparams, skiptvs)
396
394
defn.ArrayOf (elemtp.translateJavaArrayElementType)
397
395
case '(' =>
398
- // we need a method symbol. given in line 486 by calling getType(methodSym, ..)
396
+ def isMethodEnd (i : Int ) = sig(i) == ')'
397
+ def isArray (i : Int ) = sig(i) == '['
398
+
399
+ /** Is this a repeated parameter type?
400
+ * This is true if we're in a vararg method and this is the last parameter.
401
+ */
402
+ def isRepeatedParam (i : Int ): Boolean =
403
+ if ! isVarargs then return false
404
+ var cur = i
405
+ // Repeated parameters are represented as arrays
406
+ if ! isArray(cur) then return false
407
+ // Handle nested arrays: int[]...
408
+ while isArray(cur) do
409
+ cur += 1
410
+ // Simple check to see if we're the last parameter: there should be no
411
+ // array in the signature until the method end.
412
+ while ! isMethodEnd(cur) do
413
+ if isArray(cur) then return false
414
+ cur += 1
415
+ true
416
+ end isRepeatedParam
417
+
399
418
val paramtypes = new ListBuffer [Type ]()
400
419
var paramnames = new ListBuffer [TermName ]()
401
- while (sig( index) != ')' ) {
420
+ while ! isMethodEnd( index) do
402
421
paramnames += nme.syntheticParamName(paramtypes.length)
403
- paramtypes += objToAny(sig2type(tparams, skiptvs))
404
- }
422
+ paramtypes += {
423
+ if isRepeatedParam(index) then
424
+ index += 1
425
+ val elemType = sig2type(tparams, skiptvs)
426
+ // `ElimRepeated` is responsible for correctly erasing this.
427
+ defn.RepeatedParamType .appliedTo(elemType)
428
+ else
429
+ objToAny(sig2type(tparams, skiptvs))
430
+ }
431
+
405
432
index += 1
406
433
val restype = sig2type(tparams, skiptvs)
407
434
JavaMethodType (paramnames.toList, paramtypes.toList, restype)
@@ -574,7 +601,7 @@ class ClassfileParser(
574
601
None // ignore malformed annotations
575
602
}
576
603
577
- def parseAttributes (sym : Symbol , symtype : Type )(using Context ): Type = {
604
+ def parseAttributes (sym : Symbol , symtype : Type , isVarargs : Boolean = false )(using Context ): Type = {
578
605
var newType = symtype
579
606
580
607
def parseAttribute (): Unit = {
@@ -584,7 +611,7 @@ class ClassfileParser(
584
611
attrName match {
585
612
case tpnme.SignatureATTR =>
586
613
val sig = pool.getExternalName(in.nextChar)
587
- newType = sigToType(sig, sym)
614
+ newType = sigToType(sig, sym, isVarargs )
588
615
if (ctx.debug && ctx.verbose)
589
616
println(" " + sym + " ; signature = " + sig + " type = " + newType)
590
617
case tpnme.SyntheticATTR =>
@@ -1103,8 +1130,8 @@ class ClassfileParser(
1103
1130
c
1104
1131
}
1105
1132
1106
- def getType (index : Int )(using Context ): Type =
1107
- sigToType(getExternalName(index))
1133
+ def getType (index : Int , isVarargs : Boolean = false )(using Context ): Type =
1134
+ sigToType(getExternalName(index), isVarargs = isVarargs )
1108
1135
1109
1136
def getSuperClass (index : Int )(using Context ): Symbol = {
1110
1137
assert(index != 0 , " attempt to parse java.lang.Object from classfile" )
0 commit comments