diff options
author | Paul Phillips <paulp@improving.org> | 2009-12-02 22:43:09 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-12-02 22:43:09 +0000 |
commit | f2056ddf4518285920db7554f6f93924f3cc3813 (patch) | |
tree | 35a27e453f7022f90896f54ccff9cc30d5debc94 /src/compiler | |
parent | 7bee4c499d44cc31c401c7f8dc3e22e27e71703d (diff) | |
download | scala-f2056ddf4518285920db7554f6f93924f3cc3813.tar.gz scala-f2056ddf4518285920db7554f6f93924f3cc3813.tar.bz2 scala-f2056ddf4518285920db7554f6f93924f3cc3813.zip |
Implemented scala.runtime.AbstractFunction0-22.
something over 500K off the size of the lib/compiler jars.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Definitions.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 112 |
2 files changed, 62 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))) - } } } |