diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-05 18:33:26 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-05 19:00:40 +0100 |
commit | 78b57e3c5a2ca0c15729e6f6a3e43c718028754e (patch) | |
tree | 0d3fc16be40efa3178c4a28450a39475395c98ee /src | |
parent | cd28a05fa16b5b2cf3569f0ab0a8c9c685e41bf1 (diff) | |
download | dotty-78b57e3c5a2ca0c15729e6f6a3e43c718028754e.tar.gz dotty-78b57e3c5a2ca0c15729e6f6a3e43c718028754e.tar.bz2 dotty-78b57e3c5a2ca0c15729e6f6a3e43c718028754e.zip |
Fixes to lifting
Plus more commenting of Desugar
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 33 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/EtaExpansion.scala | 6 |
2 files changed, 35 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index cd3de4fd4..fc7486efa 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -155,6 +155,7 @@ object desugar { private val synthetic = Modifiers(Synthetic) + /** The expansion of a class definition. See inline comments for what is involved */ def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = { val TypeDef( mods, name, impl @ Template(constr0, parents, self, body)) = cdef @@ -164,12 +165,16 @@ object desugar { case Thicket((meth: DefDef) :: defaults) => (meth, defaults) } + // The original type and value parameters in the constructor already have the flags + // needed to be type members (i.e. param, and possibly also private and local unless + // prefixed by type or val). `tparams` and `vparamss` are the type parameters that + // go in `constr`, the constructor after desugaring. + val tparams = constr1.tparams.map(tparam => cpy.TypeDef(tparam, Modifiers(Param), tparam.name, tparam.rhs, tparam.tparams)) - // ensure parameter list is non-empty val vparamss = - if (constr1.vparamss.isEmpty) { + if (constr1.vparamss.isEmpty) { // ensure parameter list is non-empty if (mods is Case) ctx.error("case class needs to have at least one parameter list", cdef.pos) ListOfNil @@ -180,14 +185,23 @@ object desugar { val constr = cpy.DefDef(constr1, constr1.mods, constr1.name, tparams, vparamss, constr1.tpt, constr1.rhs) + // a reference to the class type, with all parameters given. val classTypeRef = { val tycon = Ident(cdef.name) withPos cdef.pos.startPos val tparams = impl.constr.tparams if (tparams.isEmpty) tycon else AppliedTypeTree(tycon, tparams map refOfDef) } + // new C[Ts](paramss) lazy val creatorExpr = New(classTypeRef, vparamss nestedMap refOfDef) + // Methods to add to a case class C[..](p1: T1, ..., pN: Tn)(moreParams) + // def isDefined = true + // def productArity = N + // def _1 = this.p1 + // ... + // def _N = this.pN + // def copy(p1: T1 = p1, ..., pN: TN = pN)(moreParams) = new C[...](p1, ..., pN)(moreParams) val caseClassMeths = if (mods is Case) { val caseParams = vparamss.head.toArray @@ -213,14 +227,26 @@ object desugar { def anyRef = ref(defn.AnyRefAlias.typeRef) def parentConstr(tpt: Tree) = Select(New(tpt), nme.CONSTRUCTOR) + // The desugared parents: AnyRef, in case parents are Nil. val parents1 = if (parents.isEmpty) parentConstr(anyRef) :: Nil else parents + // The thicket which is the desugared version of the companion object + // synthetic object C extends parentTpt { defs } def companionDefs(parentTpt: Tree, defs: List[Tree]) = moduleDef( ModuleDef( Modifiers(Synthetic), name.toTermName, Template(emptyConstructor, parentConstr(parentTpt) :: Nil, EmptyValDef, defs))).toList + // The companion object defifinitions, if a companion is needed, Nil otherwise. + // companion definitions include: + // 1. If class is a case class case class C[Ts](p1: T1, ..., pN: TN)(moreParams): + // def apply[Ts](p1: T1, ..., pN: TN)(moreParams) = new C[Ts](p1, ..., pN)(moreParams) (unless C is abstract) + // def unapply[Ts]($1: C[Ts]) = $1 + // 2. The default getters of the constructor + // The parent of the companion object of a non-parameterized case class + // (T11, ..., T1N) => ... => (TM1, ..., TMN) => C + // For all other classes, the parent is AnyRef. val companions = if (mods is Case) { val parent = @@ -240,6 +266,9 @@ object desugar { companionDefs(anyRef, defaultGetters) else Nil + // For an implicit class C[Ts](p11: T11, ..., p1N: T1N) ... (pM1: TM1, .., pMN: TMN), the method + // synthetic implicit C[Ts](p11: T11, ..., p1N: T1N) ... (pM1: TM1, ..., pMN: TMN) = + // new C[Ts](p11, ..., p1N) ... (pM1, ..., pMN) = val implicitWrappers = if (mods is Implicit) { if (ctx.owner is Package) diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala index 8781eea4b..cb8c5a43a 100644 --- a/src/dotty/tools/dotc/typer/EtaExpansion.scala +++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala @@ -59,7 +59,7 @@ object EtaExpansion { case MethodType(paramNames, paramTypes) => (args, paramNames, paramTypes).zipped map { (arg, name, tp) => if (tp isRef defn.ByNameParamClass) arg - else liftArg(defs, arg, if (name contains '$') "" else name.toString) + else liftArg(defs, arg, if (name contains '$') "" else name.toString + "$") } case _ => args map (liftArg(defs, _)) @@ -84,9 +84,11 @@ object EtaExpansion { case TypeApply(fn, targs) => cpy.TypeApply(tree, liftApp(defs, fn), targs) case Select(pre, name) if tpd.isIdempotentRef(tree) => - cpy.Select(tree, lift(defs, pre), name) + cpy.Select(tree, liftApp(defs, pre), name) case Block(stats, expr) => liftApp(defs ++= stats, expr) + case New(tpt) => + tree case _ => lift(defs, tree) } |