Skip to content

Commit 5acaad6

Browse files
committed
Merge pull request #317 from dotty-staging/fix/java-varargs
Fix/java varargs
2 parents 4e1f4a7 + f98ce3f commit 5acaad6

File tree

7 files changed

+71
-29
lines changed

7 files changed

+71
-29
lines changed

src/dotty/runtime/Arrays.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package dotty.runtime
22

33
import scala.reflect.ClassTag
44

5-
/** All but the first operation should be short-circuited and implemented specially by
5+
/** All but the first two operations should be short-circuited and implemented specially by
66
* the backend.
77
*/
88
object Arrays {
@@ -12,7 +12,14 @@ object Arrays {
1212
*/
1313
def newGenericArray[T](length: Int)(implicit tag: ClassTag[T]): Array[T] =
1414
tag.newArray(length)
15-
15+
16+
/** Convert a sequence to a Java array with element type given by `clazz`. */
17+
def seqToArray[T](xs: Seq[T], clazz: Class[_]): Array[T] = {
18+
val arr = java.lang.reflect.Array.newInstance(clazz, xs.length).asInstanceOf[Array[T]]
19+
xs.copyToArray(arr)
20+
arr
21+
}
22+
1623
/** Create an array of type T. T must be of form Array[E], with
1724
* E being a reference type.
1825
*/

src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ object StdNames {
468468
val selectTerm: N = "selectTerm"
469469
val selectType: N = "selectType"
470470
val self: N = "self"
471+
val seqToArray: N = "seqToArray"
471472
val setAccessible: N = "setAccessible"
472473
val setAnnotations: N = "setAnnotations"
473474
val setSymbol: N = "setSymbol"

src/dotty/tools/dotc/printing/PlainPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ class PlainPrinter(_ctx: Context) extends Printer {
368368

369369
def toText(const: Constant): Text = const.tag match {
370370
case StringTag => "\"" + escapedString(const.value.toString) + "\""
371-
case ClazzTag => "classOf[" ~ toText(const.tpe) ~ "]"
371+
case ClazzTag => "classOf[" ~ toText(const.tpe.firstBaseArgInfo(defn.ClassClass)) ~ "]"
372372
case CharTag => s"'${escapedChar(const.charValue)}'"
373373
case LongTag => const.longValue.toString + "L"
374374
case EnumTag => const.symbolValue.name.toString

src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ package transform
33

44
import core._
55
import Names._
6+
import StdNames.nme
67
import Types._
78
import dotty.tools.dotc.transform.TreeTransforms.{AnnotationTransformer, TransformerInfo, MiniPhaseTransform, TreeTransformer}
8-
import ast.Trees.flatten
9+
import ast.Trees._
910
import Flags._
1011
import Contexts.Context
1112
import Symbols._
13+
import Constants._
1214
import Denotations._, SymDenotations._
1315
import Decorators.StringInterpolators
1416
import dotty.tools.dotc.ast.tpd
@@ -56,9 +58,33 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer with Annotati
5658
override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
5759
transformTypeOfTree(tree)
5860

59-
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
60-
transformTypeOfTree(tree) // should also transform the tree if argument needs adaptation
61+
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
62+
val args1 = tree.args.map {
63+
case arg: Typed if isWildcardStarArg(arg) =>
64+
if (tree.fun.symbol.is(JavaDefined) && arg.expr.tpe.derivesFrom(defn.SeqClass))
65+
seqToArray(arg.expr)
66+
else arg.expr
67+
case arg => arg
68+
}
69+
transformTypeOfTree(cpy.Apply(tree)(tree.fun, args1))
70+
}
6171

72+
/** Convert sequence argument to Java array */
73+
private def seqToArray(tree: Tree)(implicit ctx: Context): Tree = tree match {
74+
case SeqLiteral(elems) =>
75+
JavaSeqLiteral(elems)
76+
case _ =>
77+
val elemType = tree.tpe.firstBaseArgInfo(defn.SeqClass)
78+
var elemClass = elemType.classSymbol
79+
if (defn.PhantomClasses contains elemClass) elemClass = defn.ObjectClass
80+
ref(defn.DottyArraysModule)
81+
.select(nme.seqToArray)
82+
.appliedToType(elemType)
83+
.appliedTo(tree, Literal(Constant(elemClass.typeRef)))
84+
.ensureConforms(defn.ArrayType(elemType))
85+
// Because of phantomclasses, the Java array's type might not conform to the resturn type
86+
}
87+
6288
override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
6389
transformTypeOfTree(tree)
6490

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ class Namer { typer: Typer =>
656656
(paramSymss :\ restpe1) { (params, restpe) =>
657657
val make =
658658
if (params.nonEmpty && (params.head is Implicit)) ImplicitMethodType
659+
else if (ddef.mods.is(JavaDefined)) JavaMethodType
659660
else MethodType
660661
make.fromSymbols(params, restpe)
661662
}

tests/pending/pos/arrays2.scala

Lines changed: 0 additions & 23 deletions
This file was deleted.

tests/pos/arrays2.scala

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
case class C();
2+
3+
object arrays2 {
4+
5+
def main(args: Array[String]): Unit = {
6+
val a: Array[Array[C]] = new Array[Array[C]](2);
7+
a(0) = new Array[C](2);
8+
a(0)(0) = new C();
9+
}
10+
}
11+
12+
// #2422
13+
object arrays4 {
14+
val args = Array[String]("World")
15+
"Hello %1$s".format(args: _*)
16+
}
17+
18+
// #2461
19+
object arrays3 {
20+
import scala.collection.JavaConversions._
21+
def apply[X](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*)
22+
23+
def apply1[X <: String](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*)
24+
def apply2[X <: AnyVal](xs : X*) : java.util.List[X] = java.util.Arrays.asList(xs: _*)
25+
def apply3(xs : Int*) : java.util.List[Int] = java.util.Arrays.asList(xs: _*)
26+
def apply4(xs : Unit*) : java.util.List[Unit] = java.util.Arrays.asList(xs: _*)
27+
def apply5(xs : Null*) : java.util.List[Null] = java.util.Arrays.asList(xs: _*)
28+
def apply6(xs : Nothing*) : java.util.List[Nothing] = java.util.Arrays.asList(xs: _*)
29+
}
30+

0 commit comments

Comments
 (0)