summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/UnCurry.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-09-17 11:00:31 +0000
committerMartin Odersky <odersky@gmail.com>2009-09-17 11:00:31 +0000
commit27f573afb47fcc38627df20058fae1cfa0fcb947 (patch)
tree20b3a7d1a1e7a4a4542d4c307bf90a4a2f02ec6b /src/compiler/scala/tools/nsc/transform/UnCurry.scala
parent63089db7fb68d070a2fdbcd3ca893a638eb5137e (diff)
downloadscala-27f573afb47fcc38627df20058fae1cfa0fcb947.tar.gz
scala-27f573afb47fcc38627df20058fae1cfa0fcb947.tar.bz2
scala-27f573afb47fcc38627df20058fae1cfa0fcb947.zip
new starr, with some changes to varargs handling.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala61
1 files changed, 36 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 9f1897353e..e10a8d8365 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -22,7 +22,8 @@ import scala.tools.nsc.util.Position
* - for every argument to a def parameter `x: => T':
* if argument is not a reference to a def parameter:
* convert argument `e' to (expansion of) `() => e'
- * - for every repeated parameter `x: T*' --> x: Seq[T].
+ * - for every repeated Scala parameter `x: T*' --> x: Seq[T].
+ * - for every repeated Java parameter `x: T*' --> x: Array[T].
* - for every argument list that corresponds to a repeated parameter
* (a_1, ..., a_n) => (Seq(a_1, ..., a_n))
* - for every argument list that is an escaped sequence
@@ -67,6 +68,8 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
apply(functionType(List(), arg))
case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) =>
apply(appliedType(SeqClass.typeConstructor, args))
+ case TypeRef(pre, sym, args) if (sym == JavaRepeatedParamClass) =>
+ apply(appliedType(ArrayClass.typeConstructor, args))
case _ =>
expandAlias(mapOver(tp))
}
@@ -89,31 +92,13 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
}
- /** Convert repeated parameters to arrays if they occur as part of a Java method
- */
- private def repeatedToArray(tp: Type): Type = tp match {
- case MethodType(params, rtpe)
- if (!params.isEmpty && params.last.tpe.typeSymbol == RepeatedParamClass) =>
- val arrayParam = params.last.owner.newSyntheticValueParams(List(
- appliedType(ArrayClass.typeConstructor, List(params.last.tpe.typeArgs.head))))
- MethodType(params.init ::: arrayParam, rtpe)
- case PolyType(tparams, rtpe) =>
- val rtpe1 = repeatedToArray(rtpe)
- if (rtpe1 eq rtpe) tp
- else PolyType(tparams, rtpe1)
- case _ =>
- tp
- }
-
/** - return symbol's transformed type,
* - if symbol is a def parameter with transformed type T, return () => T
*
* @MAT: starting with this phase, the info of every symbol will be normalized
*/
def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isType) uncurryType(tp)
- else if (sym.isMethod && sym.hasFlag(JAVA)) uncurry(repeatedToArray(tp))
- else uncurry(tp)
+ if (sym.isType) uncurryType(tp) else uncurry(tp)
/** Traverse tree omitting local method definitions.
* If a `return' is encountered, set `returnFound' to true.
@@ -374,8 +359,10 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
def transformArgs(pos: Position, args: List[Tree], formals: List[Type], isJava: Boolean) = {
val args1 = formals.lastOption match {
- case Some(TypeRef(pre, sym, List(elempt))) if (sym == RepeatedParamClass) =>
+ case Some(lastFormal) if isRepeatedParamType(lastFormal) =>
+
def callMethod(tree: Tree, nme: Name): Tree = {
+ assert(!settings.newArrays.value)
val sym = tree.tpe member nme
assert(sym != NoSymbol)
val arguments =
@@ -389,17 +376,41 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
}
def mkArrayValue(ts: List[Tree]) = {
- val arr = ArrayValue(TypeTree(elempt), ts) setType formals.last
+ val elemTp = lastFormal.typeArgs.head
+ val arr = ArrayValue(TypeTree(elemTp), ts) setType arrayType(elemTp)
if (isJava || inPattern) arr
+ else if (settings.newArrays.value)
+ atPhase(phase.next) {
+ localTyper.typedPos(pos) {
+ val predef = gen.mkAttributedRef(PredefModule)
+ val meth =
+ if ((elemTp <:< AnyRefClass.tpe) || isValueClass(elemTp.typeSymbol))
+ Select(predef, "wrapArray")
+ else
+ TypeApply(Select(predef, "genericWrapArray"), List(TypeTree(elemTp)))
+ Apply(meth, List(arr))
+ }
+ }
else callMethod(arr, nme.toSequence) // println("need to callMethod("+arr+", nme.toSequence)"); arr }
- }
+ } 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
if (isJava && tree.tpe.typeSymbol != ArrayClass &&
- (tree.tpe.typeSymbol isSubClass TraversableClass)) callMethod(tree, nme.toArray)
- else tree
+ (tree.tpe.typeSymbol isSubClass TraversableClass)) {
+ if (settings.newArrays.value) {
+ val toArraySym = tree.tpe member nme.toArray
+ assert(toArraySym != NoSymbol)
+ atPhase(phase.next) {
+ localTyper.typedPos(pos) {
+ Apply(
+ gen.mkAttributedSelect(tree, toArraySym),
+ List(localTyper.getManifestTree(tree.pos, tree.tpe.typeArgs.head, false)))
+ }
+ }
+ } else callMethod(tree, nme.toArray)
+ } else tree
}
if (args.isEmpty)