summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-05-21 14:24:27 +0000
committerPaul Phillips <paulp@improving.org>2009-05-21 14:24:27 +0000
commiteb4eac963d9067bf38aced06021d6ea2d62db48e (patch)
tree915049928ee5deb8c4fc6bdc38247e354f84fec8 /src
parent12a88b5900378777efac43f8e72c1afc6215fd60 (diff)
downloadscala-eb4eac963d9067bf38aced06021d6ea2d62db48e.tar.gz
scala-eb4eac963d9067bf38aced06021d6ea2d62db48e.tar.bz2
scala-eb4eac963d9067bf38aced06021d6ea2d62db48e.zip
Fix and test for #1360 - when passing a sequenc...
Fix and test for #1360 - when passing a sequence to java varargs, call .toArray on it if it is not already an array.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala29
3 files changed, 22 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 9427897040..ca8ad48224 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -111,6 +111,7 @@ trait Definitions {
def Iterable_hasNext = getMember(IterableClass, nme.hasNext)
lazy val IteratorClass: Symbol = getClass2("scala.Iterator", "scala.collection.Iterator")
lazy val SeqClass: Symbol = getClass2("scala.Seq", "scala.collection.Sequence")
+ lazy val TraversableClass: Symbol = getClass("scala.collection.Traversable")
lazy val RandomAccessSeqMutableClass: Symbol = getMember(
getModule2("scala.RandomAccessSeq", "scala.collection.Vector"), nme.Mutable)
def Seq_length = getMember(SeqClass, nme.length)
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 57bc1060a9..bb04630985 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -321,6 +321,7 @@ trait StdNames {
val self = newTermName("self")
val synchronized_ = newTermName("synchronized")
val tail = newTermName("tail")
+ val toArray = newTermName("toArray")
val toList = newTermName("toList")
val toSeq = newTermName("toSeq")
val toString_ = newTermName("toString")
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 5ca3f2e0aa..3caaa7ab23 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -371,7 +371,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
}
- def transformArgs(pos: Position, args: List[Tree], formals: List[Type]) = {
+ def transformArgs(pos: Position, args: List[Tree], formals: List[Type], isJava: Boolean) = {
if (formals.isEmpty) {
assert(args.isEmpty); List()
} else {
@@ -381,15 +381,25 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
def mkArrayValue(ts: List[Tree]) =
atPos(pos)(ArrayValue(TypeTree(elempt), ts) setType formals.last);
+ // when calling into java varargs, make sure it's an array - see bug #1360
+ def forceToArray(arg: Tree) = {
+ val Typed(tree, _) = arg
+ lazy val isTraversable = tree.tpe.baseClasses contains TraversableClass
+ lazy val toArray = tree.tpe member nme.toArray
+
+ if (isJava && isTraversable && toArray != NoSymbol)
+ Apply(gen.mkAttributedSelect(tree, toArray), Nil) setType tree.tpe.memberType(toArray)
+ else
+ tree
+ }
+
if (args.isEmpty)
List(mkArrayValue(args))
else {
- val suffix: Tree = args.last match {
- case Typed(arg, Ident(name)) if name == nme.WILDCARD_STAR.toTypeName =>
- arg /*setType seqType(arg.tpe)*/
- case _ =>
- mkArrayValue(args.drop(formals.length - 1))
- }
+ val suffix: Tree =
+ if (treeInfo isWildcardStarArg args.last) forceToArray(args.last)
+ else mkArrayValue(args drop (formals.length - 1))
+
args.take(formals.length - 1) ::: List(suffix)
}
case _ => args
@@ -510,7 +520,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
if (fn.symbol.name == nme.unapply)
args
else if (fn.symbol.name == nme.unapplySeq)
- transformArgs(tree.pos, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
+ transformArgs(tree.pos, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe), false)
else { assert(false,"internal error: UnApply node has wrong symbol"); null })
copy.UnApply(tree, fn1, args1)
@@ -525,7 +535,8 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
} else {
withNeedLift(true) {
val formals = fn.tpe.paramTypes;
- copy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, args, formals)))
+ val isJava = fn.symbol hasFlag JAVA // in case we need a varargs transformation
+ copy.Apply(tree, transform(fn), transformTrees(transformArgs(tree.pos, args, formals, isJava)))
}
}