diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-11-10 15:00:06 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-11-23 09:53:28 +0100 |
commit | b5be392967d84591d45153408960d0e5b68d82e9 (patch) | |
tree | 3ec3ddb21624043972f461f821ed167f6ddb5e0b /src/compiler/scala/tools/nsc/ast/TreeGen.scala | |
parent | 736613ea8a2fb3eede9bc01346a743c70b44eeaa (diff) | |
download | scala-b5be392967d84591d45153408960d0e5b68d82e9.tar.gz scala-b5be392967d84591d45153408960d0e5b68d82e9.tar.bz2 scala-b5be392967d84591d45153408960d0e5b68d82e9.zip |
Refactor away duplication between -Ydelambdafy:{inline,method}
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/TreeGen.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeGen.scala | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index d4ac21a6b8..4ac6672727 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -256,4 +256,44 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL { val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats mkNew(Nil, noSelfType, stats1, NoPosition, NoPosition) } + + /** + * Create a method based on a Function + * + * Used both to under `-Ydelambdafy:method` create a lifted function and + * under `-Ydelamdafy:inline` to create the apply method on the anonymous + * class. + * + * It creates a method definition with value params cloned from the + * original lambda. Then it calls a supplied function to create + * the body and types the result. Finally + * everything is wrapped up in a DefDef + * + * @param owner The owner for the new method + * @param name name for the new method + * @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 + + val methSym = owner.newMethod(name, fun.pos, FINAL | additionalFlags) + + val paramSyms = map2(formals, fun.vparams) { + (tp, vparam) => methSym.newSyntheticValueParam(tp, vparam.name) + } + + methSym setInfo MethodType(paramSyms, restpe.deconst) + + fun.body.substituteSymbols(funParams, paramSyms) + fun.body changeOwner (fun.symbol -> methSym) + + val methDef = DefDef(methSym, fun.body) + + // 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 + } } |