summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/TreeGen.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-11-10 15:00:06 +0100
committerJason Zaugg <jzaugg@gmail.com>2013-11-23 09:53:28 +0100
commitb5be392967d84591d45153408960d0e5b68d82e9 (patch)
tree3ec3ddb21624043972f461f821ed167f6ddb5e0b /src/compiler/scala/tools/nsc/ast/TreeGen.scala
parent736613ea8a2fb3eede9bc01346a743c70b44eeaa (diff)
downloadscala-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.scala40
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
+ }
}