aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-12-21 12:38:16 +0100
committerMartin Odersky <odersky@gmail.com>2014-12-21 12:38:33 +0100
commitf98ce3f42a77802fc98eb0f12636efc1f25c2d1b (patch)
tree451c5d72a40acfa4ee5c75f8ebcf033964d3e887 /src/dotty
parent3648ea82d5150d0685bbde3991abcfe007c38987 (diff)
downloaddotty-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.scala11
-rw-r--r--src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--src/dotty/tools/dotc/transform/ElimRepeated.scala32
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)