diff options
author | Martin Odersky <odersky@gmail.com> | 2014-12-21 12:38:16 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-12-21 12:38:33 +0100 |
commit | f98ce3f42a77802fc98eb0f12636efc1f25c2d1b (patch) | |
tree | 451c5d72a40acfa4ee5c75f8ebcf033964d3e887 /src/dotty | |
parent | 3648ea82d5150d0685bbde3991abcfe007c38987 (diff) | |
download | dotty-f98ce3f42a77802fc98eb0f12636efc1f25c2d1b.tar.gz dotty-f98ce3f42a77802fc98eb0f12636efc1f25c2d1b.tar.bz2 dotty-f98ce3f42a77802fc98eb0f12636efc1f25c2d1b.zip |
Fix passing : _* arguments to Java methods
Arguments of the form (xs: _*) which are passed to
Java methods need to be converted to arrays, not sequences.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/runtime/Arrays.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/StdNames.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ElimRepeated.scala | 32 |
3 files changed, 39 insertions, 5 deletions
diff --git a/src/dotty/runtime/Arrays.scala b/src/dotty/runtime/Arrays.scala index e7f819df8..5767991e5 100644 --- a/src/dotty/runtime/Arrays.scala +++ b/src/dotty/runtime/Arrays.scala @@ -2,7 +2,7 @@ package dotty.runtime import scala.reflect.ClassTag -/** All but the first operation should be short-circuited and implemented specially by +/** All but the first two operations should be short-circuited and implemented specially by * the backend. */ object Arrays { @@ -12,7 +12,14 @@ object Arrays { */ def newGenericArray[T](length: Int)(implicit tag: ClassTag[T]): Array[T] = tag.newArray(length) - + + /** Convert a sequence to a Java array with element type given by `clazz`. */ + def seqToArray[T](xs: Seq[T], clazz: Class[_]): Array[T] = { + val arr = java.lang.reflect.Array.newInstance(clazz, xs.length).asInstanceOf[Array[T]] + xs.copyToArray(arr) + arr + } + /** Create an array of type T. T must be of form Array[E], with * E being a reference type. */ diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index 04bcf616d..4e3fa27ec 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -468,6 +468,7 @@ object StdNames { val selectTerm: N = "selectTerm" val selectType: N = "selectType" val self: N = "self" + val seqToArray: N = "seqToArray" val setAccessible: N = "setAccessible" val setAnnotations: N = "setAnnotations" val setSymbol: N = "setSymbol" diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index ff56ae872..28131e1e9 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -3,12 +3,14 @@ package transform import core._ import Names._ +import StdNames.nme import Types._ import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer} -import ast.Trees.flatten +import ast.Trees._ import Flags._ import Contexts.Context import Symbols._ +import Constants._ import Denotations._, SymDenotations._ import Decorators.StringInterpolators import dotty.tools.dotc.ast.tpd @@ -56,9 +58,33 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = transformTypeOfTree(tree) - override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = - transformTypeOfTree(tree) // should also transform the tree if argument needs adaptation + override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = { + val args1 = tree.args.map { + case arg: Typed if isWildcardStarArg(arg) => + if (tree.fun.symbol.is(JavaDefined) && arg.expr.tpe.derivesFrom(defn.SeqClass)) + seqToArray(arg.expr) + else arg.expr + case arg => arg + } + transformTypeOfTree(cpy.Apply(tree)(tree.fun, args1)) + } + /** Convert sequence argument to Java array */ + private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match { + case SeqLiteral(elems) => + JavaSeqLiteral(elems) + case _ => + val elemType = tree.tpe.firstBaseArgInfo(defn.SeqClass) + var elemClass = elemType.classSymbol + if (defn.PhantomClasses contains elemClass) elemClass = defn.ObjectClass + ref(defn.DottyArraysModule) + .select(nme.seqToArray) + .appliedToType(elemType) + .appliedTo(tree, Literal(Constant(elemClass.typeRef))) + .ensureConforms(defn.ArrayType(elemType)) + // Because of phantomclasses, the Java array's type might not conform to the resturn type + } + override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = transformTypeOfTree(tree) |