diff options
author | Paul Phillips <paulp@improving.org> | 2010-11-04 00:07:36 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-11-04 00:07:36 +0000 |
commit | 379af580e2c8cf0ce5309fc0b31702f79e415abe (patch) | |
tree | cf741eb0d27624d6130bb5bc7f403ec7fb05af1d /src/compiler/scala/tools/nsc/transform/UnCurry.scala | |
parent | de012b3a6d04f1e7a9fd6fecd403e0492f6ad7c1 (diff) | |
download | scala-379af580e2c8cf0ce5309fc0b31702f79e415abe.tar.gz scala-379af580e2c8cf0ce5309fc0b31702f79e415abe.tar.bz2 scala-379af580e2c8cf0ce5309fc0b31702f79e415abe.zip |
Determined that half a dozen ways of checking f...
Determined that half a dozen ways of checking for varargs and
by-name-ness in param lists exceeded the legal limit. Also assessed that
names which are only used as type names would be a lot easier to deal
with if we created them as type names up front. Performed the changes
implied by the preceding along with a partial cleanup on TreeInfo which
one can see hasn't had a good look in a long time. (And still hasn't.)
No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/UnCurry.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 125 |
1 files changed, 59 insertions, 66 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 26c1efbf91..63f4c05def 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -180,8 +180,8 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { */ def isByNameRef(tree: Tree): Boolean = tree.isTerm && tree.hasSymbol && - tree.symbol.tpe.typeSymbol == ByNameParamClass && - !byNameArgs.contains(tree) + isByNameParamType(tree.symbol.tpe) && + !byNameArgs(tree) /** Uncurry a type of a tree node. * This function is sensitive to whether or not we are in a pattern -- when in a pattern @@ -385,78 +385,71 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { } def transformArgs(pos: Position, fun: Symbol, args: List[Tree], formals: List[Type]) = { - val isJava = fun hasFlag JAVA - val args1 = formals.lastOption match { - case Some(lastFormal) if isRepeatedParamType(lastFormal) => - - def mkArrayValue(ts: List[Tree], elemtp: Type) = - ArrayValue(TypeTree(elemtp), ts) setType arrayType(elemtp) - - // when calling into scala varargs, make sure it's a sequence. - def arrayToSequence(tree: Tree, elemtp: Type) = { - atPhase(phase.next) { - localTyper.typedPos(pos) { - val pt = arrayType(elemtp) - val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant - if (tree.tpe <:< pt) tree - else gen.mkCastArray(tree, elemtp, pt) - - gen.mkWrapArray(adaptedTree, elemtp) - } + val isJava = fun.isJavaDefined + def transformVarargs(varargsElemType: Type) = { + def mkArrayValue(ts: List[Tree], elemtp: Type) = + ArrayValue(TypeTree(elemtp), ts) setType arrayType(elemtp) + + // when calling into scala varargs, make sure it's a sequence. + def arrayToSequence(tree: Tree, elemtp: Type) = { + atPhase(phase.next) { + localTyper.typedPos(pos) { + val pt = arrayType(elemtp) + val adaptedTree = // might need to cast to Array[elemtp], as arrays are not covariant + if (tree.tpe <:< pt) tree + else gen.mkCastArray(tree, elemtp, pt) + + gen.mkWrapArray(adaptedTree, elemtp) } } + } - // when calling into java varargs, make sure it's an array - see bug #1360 - def sequenceToArray(tree: Tree) = { - val toArraySym = tree.tpe member nme.toArray - assert(toArraySym != NoSymbol) - def getManifest(tp: Type): Tree = { - val manifestOpt = localTyper.findManifest(tp, false) - if (!manifestOpt.tree.isEmpty) manifestOpt.tree - else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) - else localTyper.getManifestTree(tree.pos, tp, false) - } - atPhase(phase.next) { - localTyper.typedPos(pos) { - Apply(gen.mkAttributedSelect(tree, toArraySym), List(getManifest(tree.tpe.typeArgs.head))) - } + // when calling into java varargs, make sure it's an array - see bug #1360 + def sequenceToArray(tree: Tree) = { + val toArraySym = tree.tpe member nme.toArray + assert(toArraySym != NoSymbol) + def getManifest(tp: Type): Tree = { + val manifestOpt = localTyper.findManifest(tp, false) + if (!manifestOpt.tree.isEmpty) manifestOpt.tree + else if (tp.bounds.hi ne tp) getManifest(tp.bounds.hi) + else localTyper.getManifestTree(tree.pos, tp, false) + } + atPhase(phase.next) { + localTyper.typedPos(pos) { + Apply(gen.mkAttributedSelect(tree, toArraySym), List(getManifest(tree.tpe.typeArgs.head))) } } + } - val lastElemType = lastFormal.typeArgs.head - var suffix: Tree = - if (!args.isEmpty && (treeInfo isWildcardStarArg args.last)) { - val Typed(tree, _) = args.last; - if (isJava) - if (tree.tpe.typeSymbol == ArrayClass) tree - else sequenceToArray(tree) - else - if (tree.tpe.typeSymbol isSubClass TraversableClass) tree - else arrayToSequence(tree, lastElemType) - } else { - val tree = mkArrayValue(args drop (formals.length - 1), lastElemType) - if (isJava || inPattern) tree - else arrayToSequence(tree, lastElemType) - } + var suffix: Tree = + if (treeInfo isWildcardStarArgList args) { + val Typed(tree, _) = args.last; + if (isJava) + if (tree.tpe.typeSymbol == ArrayClass) tree + else sequenceToArray(tree) + else + if (tree.tpe.typeSymbol isSubClass TraversableClass) tree // @PP: I suspect this should be SeqClass + else arrayToSequence(tree, varargsElemType) + } else { + val tree = mkArrayValue(args drop (formals.length - 1), varargsElemType) + if (isJava || inPattern) tree + else arrayToSequence(tree, varargsElemType) + } - atPhase(phase.next) { - if (isJava && - suffix.tpe.typeSymbol == ArrayClass && - isValueClass(suffix.tpe.typeArgs.head.typeSymbol) && - { val lastFormal2 = fun.tpe.params.last.tpe - lastFormal2.typeSymbol == ArrayClass && - lastFormal2.typeArgs.head.typeSymbol == ObjectClass - }) - suffix = localTyper.typedPos(pos) { - gen.mkRuntimeCall("toObjectArray", List(suffix)) - } + atPhase(phase.next) { + if (isJava && isPrimitiveArray(suffix.tpe) && isArrayOfSymbol(fun.tpe.params.last.tpe, ObjectClass)) { + suffix = localTyper.typedPos(pos) { + gen.mkRuntimeCall("toObjectArray", List(suffix)) + } } - args.take(formals.length - 1) ::: List(suffix setType lastFormal) - case _ => - args + } + args.take(formals.length - 1) :+ (suffix setType formals.last) } + + val args1 = if (isVarArgTypes(formals)) transformVarargs(formals.last.typeArgs.head) else args + (formals, args1).zipped map { (formal, arg) => - if (formal.typeSymbol != ByNameParamClass) { + if (!isByNameParamType(formal)) { arg } else if (isByNameRef(arg)) { byNameArgs.addEntry(arg) @@ -686,7 +679,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { case Apply(Apply(fn, args), args1) => treeCopy.Apply(tree, fn, args ::: args1) case Ident(name) => - assert(name != nme.WILDCARD_STAR.toTypeName) + assert(name != nme.WILDCARD_STAR) applyUnary() case Select(_, _) | TypeApply(_, _) => applyUnary() @@ -733,7 +726,7 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { traverse(fn) (fn.symbol.paramss.head zip args) foreach { case (param, arg) => - if (param.tpe != null && param.tpe.typeSymbol == ByNameParamClass) + if (param.tpe != null && isByNameParamType(param.tpe)) withEscaping(traverse(arg)) else traverse(arg) |