aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/ElimRepeated.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/ElimRepeated.scala')
-rw-r--r--src/dotty/tools/dotc/transform/ElimRepeated.scala45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala
index a362aee07..c78c012c3 100644
--- a/src/dotty/tools/dotc/transform/ElimRepeated.scala
+++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala
@@ -32,10 +32,8 @@ class ElimRepeated extends TreeTransform with InfoTransformer { thisTransformer
case tp @ MethodType(paramNames, paramTypes) =>
val resultType1 = elimRepeated(tp.resultType)
val paramTypes1 =
- if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam) {
- paramTypes.init :+
- paramTypes.last.translateParameterized(defn.RepeatedParamClass, defn.SeqClass)
- }
+ if (paramTypes.nonEmpty && paramTypes.last.isRepeatedParam)
+ paramTypes.init :+ paramTypes.last.underlyingIfRepeated(tp.isJava)
else paramTypes
tp.derivedMethodType(paramNames, paramTypes1, resultType1)
case tp: PolyType =>
@@ -58,4 +56,43 @@ class ElimRepeated extends TreeTransform with InfoTransformer { thisTransformer
override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
transformTypeOfTree(tree)
+
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ assert(ctx.phase == thisTransformer)
+ def overridesJava = {
+ val overridden = tree.symbol.allOverriddenSymbols
+ overridden.hasNext && overridden.forall(_ is JavaDefined)
+ }
+ if (tree.symbol.info.isVarArgsMethod && overridesJava)
+ addVarArgsBridge(tree)(ctx.withPhase(thisTransformer.next))
+ else
+ tree
+ }
+
+ /** add varargs bridge method
+ */
+ private def addVarArgsBridge(ddef: DefDef)(implicit ctx: Context): Tree = {
+ val original = ddef.symbol.asTerm
+ val bridge = original.copy(
+ flags = ddef.symbol.flags &~ Private | Artifact,
+ info = toJavaVarArgs(ddef.symbol.info)).enteredAfter(thisTransformer).asTerm
+ val bridgeDef = polyDefDef(bridge, trefs => vrefss => {
+ val (vrefs :+ varArgRef) :: vrefss1 = vrefss
+ val elemtp = varArgRef.tpe.widen.argTypes.head
+ ref(original.termRef)
+ .appliedToTypes(trefs)
+ .appliedToArgs(vrefs :+ TreeGen.wrapArray(varArgRef, elemtp))
+ .appliedToArgss(vrefss1)
+ })
+ Thicket(ddef, bridgeDef)
+ }
+
+ private def toJavaVarArgs(tp: Type)(implicit ctx: Context): Type = tp match {
+ case tp: PolyType =>
+ tp.derivedPolyType(tp.paramNames, tp.paramBounds, toJavaVarArgs(tp.resultType))
+ case tp: MethodType =>
+ val inits :+ last = tp.paramTypes
+ val last1 = last.underlyingIfRepeated(isJava = true)
+ tp.derivedMethodType(tp.paramNames, inits :+ last1, tp.resultType)
+ }
}