diff options
Diffstat (limited to 'src/dotty/tools/dotc/transform/ElimRepeated.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimRepeated.scala | 45 |
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) + } } |