summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/TreeGen.scala
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-02-05 13:33:39 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-26 22:49:10 -0700
commitad90614c391328bdc9d13795d26f339f67e7f4d5 (patch)
tree57b130ab18b2d607422e0a6c77d92af19ddae6a4 /src/compiler/scala/tools/nsc/ast/TreeGen.scala
parent0d89ab1fe4adfe7165a2e3812d76dbb586c79798 (diff)
downloadscala-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.scala46
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)))
+ }
}
}