diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-02-05 13:33:39 -0800 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2016-03-26 22:49:10 -0700 |
commit | ad90614c391328bdc9d13795d26f339f67e7f4d5 (patch) | |
tree | 57b130ab18b2d607422e0a6c77d92af19ddae6a4 /src/compiler/scala/tools/nsc/ast/TreeGen.scala | |
parent | 0d89ab1fe4adfe7165a2e3812d76dbb586c79798 (diff) | |
download | scala-ad90614c391328bdc9d13795d26f339f67e7f4d5.tar.gz scala-ad90614c391328bdc9d13795d26f339f67e7f4d5.tar.bz2 scala-ad90614c391328bdc9d13795d26f339f67e7f4d5.zip |
Refactoring. Sweep Sammy's backyard.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/TreeGen.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 7edac76b91..7b0216a6d7 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -278,26 +278,44 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { * @param additionalFlags flags to be put on the method in addition to FINAL */ def mkMethodFromFunction(localTyper: analyzer.Typer) - (fun: Function, owner: Symbol, name: TermName, additionalFlags: FlagSet = NoFlags) = { - val funParams = fun.vparams map (_.symbol) - val formals :+ restpe = fun.tpe.typeArgs + (owner: Symbol, fun: Function, name: TermName = nme.apply, additionalFlags: FlagSet = NoFlags) = { + val funParamSyms = fun.vparams.map(_.symbol) val methSym = owner.newMethod(name, fun.pos, FINAL | additionalFlags) + val methParamSyms = funParamSyms.map { param => methSym.newSyntheticValueParam(param.tpe, param.name.toTermName) } - val paramSyms = map2(formals, fun.vparams) { - (tp, vparam) => methSym.newSyntheticValueParam(tp, vparam.name) - } + val body = fun.body + body substituteSymbols (funParamSyms, methParamSyms) + body changeOwner ((fun.symbol, methSym)) - methSym setInfo MethodType(paramSyms, restpe.deconst) + // Have to repack the type to avoid mismatches when existentials + // appear in the result - see SI-4869. + val resTp = localTyper.packedType(body, methSym).deconst + methSym setInfo MethodType(methParamSyms, fun.tpe.typeArgs.last.deconst) // TODO: use `resTp` -- preserving wrong status quo because refactoring-only - fun.body.substituteSymbols(funParams, paramSyms) - fun.body changeOwner (fun.symbol -> methSym) + newDefDef(methSym, body)(tpt = TypeTree(resTp)) + } - val methDef = DefDef(methSym, fun.body) + def functionClassType(fun: Function): Type = + abstractFunctionType(fun.vparams.map(_.symbol.tpe), fun.tpe.typeArgs.last.deconst) // TODO: use `fun.body.tpe.deconst` -- preserving wrong status quo because refactoring-only - // Have to repack the type to avoid mismatches when existentials - // appear in the result - see SI-4869. - methDef.tpt setType localTyper.packedType(fun.body, methSym).deconst - methDef + def expandFunction(localTyper: analyzer.Typer)(fun: Function, inConstructorFlag: Long): Tree = { + val parents = addSerializable(functionClassType(fun)) + val anonClass = fun.symbol.owner newAnonymousFunctionClass(fun.pos, inConstructorFlag) addAnnotation SerialVersionUIDAnnotation + + // The original owner is used in the backend for the EnclosingMethod attribute. If fun is + // nested in a value-class method, its owner was already changed to the extension method. + // Saving the original owner allows getting the source structure from the class symbol. + defineOriginalOwner(anonClass, fun.symbol.originalOwner) + anonClass setInfo ClassInfoType(parents, newScope, anonClass) + + val applyMethodDef = mkMethodFromFunction(localTyper)(anonClass, fun) + anonClass.info.decls enter applyMethodDef.symbol + + localTyper.typedPos(fun.pos) { + Block( + ClassDef(anonClass, NoMods, ListOfNil, List(applyMethodDef), fun.pos), + Typed(New(anonClass.tpe), TypeTree(fun.tpe))) + } } } |