diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 112 | ||||
-rw-r--r-- | src/library/scala/runtime/AbstractFunction.scala | 33 |
3 files changed, 95 insertions, 59 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index c32a6fffd8..d10c896bc1 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -270,6 +270,7 @@ trait Definitions { lazy val TupleClass = mkArityArray("Tuple", MaxTupleArity) lazy val ProductClass = mkArityArray("Product", MaxProductArity) lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0) + lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0) def tupleField(n: Int, j: Int) = getMember(TupleClass(n), "_" + j) def isTupleType(tp: Type): Boolean = cond(tp.normalize) { @@ -323,6 +324,14 @@ trait Definitions { typeRef(sym.typeConstructor.prefix, sym, formals ::: List(restpe)) } else NoType + def abstractFunctionForFunctionType(tp: Type) = tp.normalize match { + case tr @ TypeRef(_, _, args) if isFunctionType(tr) => + val sym = AbstractFunctionClass(args.length - 1) + typeRef(sym.typeConstructor.prefix, sym, args) + case _ => + NoType + } + def isFunctionType(tp: Type): Boolean = tp.normalize match { case TypeRef(_, sym, args) => (args.length > 0) && (args.length - 1 <= MaxFunctionArity) && diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 5409a0fe45..27be488150 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -318,68 +318,63 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { */ def transformFunction(fun: Function): Tree = { val fun1 = deEta(fun) + def owner = fun.symbol.owner + def targs = fun.tpe.typeArgs + def isPartial = fun.tpe.typeSymbol == PartialFunctionClass + if (fun1 ne fun) fun1 else { - val anonClass = fun.symbol.owner.newAnonymousFunctionClass(fun.pos) - .setFlag(FINAL | SYNTHETIC | inConstructorFlag) - val formals = fun.tpe.typeArgs.init - val restpe = fun.tpe.typeArgs.last - anonClass setInfo ClassInfoType( - List(ObjectClass.tpe, fun.tpe, ScalaObjectClass.tpe), new Scope, anonClass); - val applyMethod = anonClass.newMethod(fun.pos, nme.apply).setFlag(FINAL) - applyMethod.setInfo(MethodType(applyMethod.newSyntheticValueParams(formals), restpe)) - anonClass.info.decls enter applyMethod; - for (vparam <- fun.vparams) vparam.symbol.owner = applyMethod; - new ChangeOwnerTraverser(fun.symbol, applyMethod).traverse(fun.body); - def applyMethodDef(body: Tree) = - DefDef(Modifiers(FINAL), nme.apply, List(), List(fun.vparams), TypeTree(restpe), body) - .setSymbol(applyMethod) -/* - def toStringMethodDefs = fun match { - case etaExpansion(_, fn, _) if (fn.hasSymbol) => - List( - DefDef(Modifiers(FINAL | OVERRIDE), nme.toString_, List(), List(List()), TypeTree(StringClass.tpe), - Literal(fn.symbol.name))) - case _ => - List() + val (formals, restpe) = (targs.init, targs.last) + val anonClass = owner newAnonymousFunctionClass fun.pos setFlag (FINAL | SYNTHETIC | inConstructorFlag) + def parents = + if (isFunctionType(fun.tpe)) List(abstractFunctionForFunctionType(fun.tpe)) + else List(ObjectClass.tpe, fun.tpe) + + anonClass setInfo ClassInfoType(parents, new Scope, anonClass) + val applyMethod = anonClass.newMethod(fun.pos, nme.apply) setFlag FINAL + applyMethod setInfo MethodType(applyMethod newSyntheticValueParams formals, restpe) + anonClass.info.decls enter applyMethod + + fun.vparams foreach (_.symbol.owner = applyMethod) + new ChangeOwnerTraverser(fun.symbol, applyMethod) traverse fun.body + + def mkUnchecked(tree: Tree) = { + def newUnchecked(expr: Tree) = Annotated(New(gen.scalaDot(UncheckedClass.name), List(Nil)), expr) + tree match { + case Match(selector, cases) => atPos(tree.pos) { Match(newUnchecked(selector), cases) } + case _ => tree + } } -*/ - def mkUnchecked(tree: Tree) = tree match { - case Match(selector, cases) => - atPos(tree.pos) { - Match( - Annotated(New(TypeTree(UncheckedClass.tpe), List(List())), selector), - cases) - } - case _ => - tree + + def applyMethodDef() = { + val body = if (isPartial) mkUnchecked(fun.body) else fun.body + DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(restpe), body) setSymbol applyMethod } - val members = { - if (fun.tpe.typeSymbol == PartialFunctionClass) { - val isDefinedAtMethod = anonClass.newMethod(fun.pos, nme.isDefinedAt).setFlag(FINAL) - isDefinedAtMethod.setInfo(MethodType(isDefinedAtMethod.newSyntheticValueParams(formals), - BooleanClass.tpe)) - anonClass.info.decls enter isDefinedAtMethod - def idbody(idparam: Symbol) = fun.body match { - case Match(selector, cases) => - val substParam = new TreeSymSubstituter(List(fun.vparams.head.symbol), List(idparam)) - def transformCase(cdef: CaseDef): CaseDef = - substParam( - resetLocalAttrs( - CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true)))) - if (cases exists treeInfo.isDefaultCase) Literal(true) - else - Match( - substParam(resetLocalAttrs(selector.duplicate)), - (cases map transformCase) ::: - List(CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false)))) - } - List(applyMethodDef(mkUnchecked(fun.body)), - DefDef(isDefinedAtMethod, mkUnchecked(idbody(isDefinedAtMethod.paramss.head.head)))) - } else { - List(applyMethodDef(fun.body)) - } - } /* ::: toStringMethodDefs */ + def isDefinedAtMethodDef() = { + val m = anonClass.newMethod(fun.pos, nme.isDefinedAt) setFlag FINAL + m setInfo MethodType(m newSyntheticValueParams formals, BooleanClass.tpe) + anonClass.info.decls enter m + + val Match(selector, cases) = fun.body + val vparam = fun.vparams.head.symbol + val idparam = m.paramss.head.head + val substParam = new TreeSymSubstituter(List(vparam), List(idparam)) + def substTree[T <: Tree](t: T): T = substParam(resetLocalAttrs(t)) + + def transformCase(cdef: CaseDef): CaseDef = + substTree(CaseDef(cdef.pat.duplicate, cdef.guard.duplicate, Literal(true))) + def defaultCase = CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false)) + + DefDef(m, mkUnchecked( + if (cases exists treeInfo.isDefaultCase) Literal(true) + else Match(substTree(selector.duplicate), (cases map transformCase) ::: List(defaultCase)) + )) + } + + val members = + if (isPartial) List(applyMethodDef, isDefinedAtMethodDef) + else List(applyMethodDef) + localTyper.typed { atPos(fun.pos) { Block( @@ -387,7 +382,6 @@ abstract class UnCurry extends InfoTransform with TypingTransformers { Typed( New(TypeTree(anonClass.tpe), List(List())), TypeTree(fun.tpe))) - } } } diff --git a/src/library/scala/runtime/AbstractFunction.scala b/src/library/scala/runtime/AbstractFunction.scala new file mode 100644 index 0000000000..b378ee942a --- /dev/null +++ b/src/library/scala/runtime/AbstractFunction.scala @@ -0,0 +1,33 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala.runtime + +abstract class AbstractFunction0[+R] extends Function0[R] { } +abstract class AbstractFunction1[-T1, +R] extends Function1[T1, R] { } +abstract class AbstractFunction2[-T1, -T2, +R] extends Function2[T1, T2, R] { } +abstract class AbstractFunction3[-T1, -T2, -T3, +R] extends Function3[T1, T2, T3, R] { } +abstract class AbstractFunction4[-T1, -T2, -T3, -T4, +R] extends Function4[T1, T2, T3, T4, R] { } +abstract class AbstractFunction5[-T1, -T2, -T3, -T4, -T5, +R] extends Function5[T1, T2, T3, T4, T5, R] { } +abstract class AbstractFunction6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function6[T1, T2, T3, T4, T5, T6, R] { } +abstract class AbstractFunction7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function7[T1, T2, T3, T4, T5, T6, T7, R] { } +abstract class AbstractFunction8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] { } +abstract class AbstractFunction9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] { } +abstract class AbstractFunction10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] { } +abstract class AbstractFunction11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] { } +abstract class AbstractFunction12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] { } +abstract class AbstractFunction13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] { } +abstract class AbstractFunction14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] { } +abstract class AbstractFunction15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] { } +abstract class AbstractFunction16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] { } +abstract class AbstractFunction17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] { } +abstract class AbstractFunction18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] { } +abstract class AbstractFunction19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] { } +abstract class AbstractFunction20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] { } +abstract class AbstractFunction21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] { } +abstract class AbstractFunction22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] { } |