From eb4eac963d9067bf38aced06021d6ea2d62db48e Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 21 May 2009 14:24:27 +0000 Subject: 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. --- .../scala/tools/nsc/symtab/Definitions.scala | 1 + src/compiler/scala/tools/nsc/symtab/StdNames.scala | 1 + .../scala/tools/nsc/transform/UnCurry.scala | 29 +++++++++++++++------- 3 files changed, 22 insertions(+), 9 deletions(-) (limited to 'src') 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))) } } -- cgit v1.2.3