Skip to content

Commit 7978a5f

Browse files
committed
Merge pull request #220 from dotty-staging/refactor/DefTrees
Refactor/def trees
2 parents 8d44da5 + cd2f99c commit 7978a5f

32 files changed

+433
-556
lines changed

src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 64 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ object desugar {
8888
* def x_=($1: <TypeTree()>): Unit = ()
8989
*/
9090
def valDef(vdef: ValDef)(implicit ctx: Context): Tree = {
91-
val ValDef(mods, name, tpt, rhs) = vdef
91+
val ValDef(name, tpt, rhs) = vdef
92+
val mods = vdef.mods
9293
def setterNeeded =
9394
(mods is Mutable) && ctx.owner.isClass && (!(mods is PrivateLocal) || (ctx.owner is Trait))
9495
if (setterNeeded) {
@@ -99,8 +100,12 @@ object desugar {
99100
val setterParam = makeSyntheticParameter(tpt = (new SetterParamTree).watching(vdef))
100101
val setterRhs = if (vdef.rhs.isEmpty) EmptyTree else unitLiteral
101102
val setter = cpy.DefDef(vdef)(
102-
(mods | Accessor) &~ CaseAccessor, name.setterName, Nil, (setterParam :: Nil) :: Nil,
103-
TypeTree(defn.UnitType), setterRhs) // rhs gets filled in later, when field is generated and getter has parameters
103+
name = name.setterName,
104+
tparams = Nil,
105+
vparamss = (setterParam :: Nil) :: Nil,
106+
tpt = TypeTree(defn.UnitType),
107+
rhs = setterRhs
108+
).withMods((mods | Accessor) &~ CaseAccessor) // rhs gets filled in later, when field is generated and getter has parameters
104109
Thicket(vdef, setter)
105110
}
106111
else vdef
@@ -121,15 +126,15 @@ object desugar {
121126
* def f$default$2(x: Int) = x + "m"
122127
*/
123128
def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false)(implicit ctx: Context): Tree = {
124-
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = meth
129+
val DefDef(name, tparams, vparamss, tpt, rhs) = meth
130+
val mods = meth.mods
125131
val epbuf = new ListBuffer[ValDef]
126132
val tparams1 = tparams mapConserve {
127-
case tparam @ TypeDef(_, _, ContextBounds(tbounds, cxbounds)) =>
133+
case tparam @ TypeDef(_, ContextBounds(tbounds, cxbounds)) =>
128134
for (cxbound <- cxbounds) {
129135
val paramFlags: FlagSet = if (isPrimaryConstructor) PrivateLocalParamAccessor else Param
130136
val epname = (nme.EVIDENCE_PARAM_PREFIX.toString + epbuf.length).toTermName
131-
epbuf +=
132-
ValDef(Modifiers(paramFlags | Implicit), epname, cxbound, EmptyTree)
137+
epbuf += ValDef(epname, cxbound, EmptyTree).withFlags(paramFlags | Implicit)
133138
}
134139
cpy.TypeDef(tparam)(rhs = tbounds)
135140
case tparam =>
@@ -165,12 +170,12 @@ object desugar {
165170
case (vparam :: vparams) :: vparamss1 =>
166171
def defaultGetter: DefDef =
167172
DefDef(
168-
mods = vparam.mods & AccessFlags,
169173
name = meth.name.defaultGetterName(n),
170174
tparams = meth.tparams map toDefParam,
171175
vparamss = takeUpTo(normalizedVparamss, n),
172176
tpt = TypeTree(),
173-
rhs = vparam.rhs)
177+
rhs = vparam.rhs
178+
).withMods(vparam.mods & AccessFlags)
174179
val rest = defaultGetters(vparams :: vparamss1, n + 1)
175180
if (vparam.rhs.isEmpty) rest else defaultGetter :: rest
176181
case Nil :: vparamss1 =>
@@ -182,9 +187,8 @@ object desugar {
182187
val defGetters = defaultGetters(vparamss, 0)
183188
if (defGetters.isEmpty) meth1
184189
else {
185-
val meth2 = cpy.DefDef(meth1)(
186-
mods = meth1.mods | DefaultParameterized,
187-
vparamss = normalizedVparamss)
190+
val meth2 = cpy.DefDef(meth1)(vparamss = normalizedVparamss)
191+
.withMods(meth1.mods | DefaultParameterized)
188192
Thicket(meth2 :: defGetters)
189193
}
190194
}
@@ -197,30 +201,26 @@ object desugar {
197201
*/
198202
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
199203
if (tdef.mods is PrivateLocalParam) {
200-
val tparam = cpy.TypeDef(tdef)(
201-
mods = tdef.mods &~ PrivateLocal | ExpandedName,
202-
name = tdef.name.expandedName(ctx.owner))
203-
val alias = cpy.TypeDef(tdef)(
204-
mods = Modifiers(PrivateLocalParamAccessor | Synthetic | tdef.mods.flags & VarianceFlags),
205-
rhs = refOfDef(tparam),
206-
tparams = Nil)
204+
val tparam = cpy.TypeDef(tdef)(name = tdef.name.expandedName(ctx.owner))
205+
.withMods(tdef.mods &~ PrivateLocal | ExpandedName)
206+
val alias = cpy.TypeDef(tdef)(rhs = refOfDef(tparam), tparams = Nil)
207+
.withFlags(PrivateLocalParamAccessor | Synthetic | tdef.mods.flags & VarianceFlags)
207208
Thicket(tparam, alias)
208209
}
209210
else tdef
210211
}
211212

212213
private val synthetic = Modifiers(Synthetic)
213214

214-
private def toDefParam(tparam: TypeDef) =
215-
cpy.TypeDef(tparam)(mods = Modifiers(Param))
216-
217-
private def toDefParam(vparam: ValDef) =
218-
cpy.ValDef(vparam)(mods = Modifiers(Param | vparam.mods.flags & Implicit))
215+
private def toDefParam(tparam: TypeDef): TypeDef =
216+
tparam.withFlags(Param)
217+
private def toDefParam(vparam: ValDef): ValDef =
218+
vparam.withFlags(Param | vparam.rawMods.flags & Implicit)
219219

220220
/** The expansion of a class definition. See inline comments for what is involved */
221221
def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = {
222-
val TypeDef(
223-
mods, name, impl @ Template(constr0, parents, self, body)) = cdef
222+
val TypeDef(name, impl @ Template(constr0, parents, self, body)) = cdef
223+
val mods = cdef.mods
224224

225225
val (constr1, defaultGetters) = defDef(constr0, isPrimaryConstructor = true) match {
226226
case meth: DefDef => (meth, Nil)
@@ -285,7 +285,7 @@ object desugar {
285285
val caseClassMeths =
286286
if (mods is Case) {
287287
def syntheticProperty(name: TermName, rhs: Tree) =
288-
DefDef(synthetic, name, Nil, Nil, TypeTree(), rhs)
288+
DefDef(name, Nil, Nil, TypeTree(), rhs).withMods(synthetic)
289289
val isDefinedMeth = syntheticProperty(nme.isDefined, Literal(Constant(true)))
290290
val caseParams = constrVparamss.head.toArray
291291
val productElemMeths = for (i <- 0 until arity) yield
@@ -299,7 +299,8 @@ object desugar {
299299
cpy.ValDef(vparam)(rhs = copyDefault(vparam)))
300300
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
301301
cpy.ValDef(vparam)(rhs = EmptyTree))
302-
DefDef(synthetic, nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr) :: Nil
302+
DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
303+
.withMods(synthetic) :: Nil
303304
}
304305
copyMeths ::: isDefinedMeth :: productElemMeths.toList
305306
}
@@ -322,8 +323,8 @@ object desugar {
322323
def companionDefs(parentTpt: Tree, defs: List[Tree]) =
323324
moduleDef(
324325
ModuleDef(
325-
Modifiers(Synthetic), name.toTermName,
326-
Template(emptyConstructor, parentTpt :: Nil, EmptyValDef, defs)))
326+
name.toTermName, Template(emptyConstructor, parentTpt :: Nil, EmptyValDef, defs))
327+
.withMods(synthetic))
327328
.withPos(cdef.pos).toList
328329

329330
// The companion object defifinitions, if a companion is needed, Nil otherwise.
@@ -344,13 +345,13 @@ object desugar {
344345
val applyMeths =
345346
if (mods is Abstract) Nil
346347
else
347-
DefDef(
348-
synthetic | (constr1.mods.flags & DefaultParameterized), nme.apply,
349-
derivedTparams, derivedVparamss, TypeTree(), creatorExpr) :: Nil
348+
DefDef(nme.apply, derivedTparams, derivedVparamss, TypeTree(), creatorExpr)
349+
.withMods(synthetic | (constr1.mods.flags & DefaultParameterized)) :: Nil
350350
val unapplyMeth = {
351351
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
352352
val unapplyRHS = if (arity == 0) Literal(Constant(true)) else Ident(unapplyParam.name)
353-
DefDef(synthetic, nme.unapply, derivedTparams, (unapplyParam :: Nil) :: Nil, TypeTree(), unapplyRHS)
353+
DefDef(nme.unapply, derivedTparams, (unapplyParam :: Nil) :: Nil, TypeTree(), unapplyRHS)
354+
.withMods(synthetic)
354355
}
355356
companionDefs(parent, applyMeths ::: unapplyMeth :: defaultGetters)
356357
}
@@ -370,27 +371,23 @@ object desugar {
370371

371372
// implicit wrapper is typechecked in same scope as constructor, so
372373
// we can reuse the constructor parameters; no derived params are needed.
373-
DefDef(Modifiers(Synthetic | Implicit), name.toTermName,
374-
constrTparams, constrVparamss, classTypeRef, creatorExpr) :: Nil
374+
DefDef(name.toTermName, constrTparams, constrVparamss, classTypeRef, creatorExpr)
375+
.withFlags(Synthetic | Implicit) :: Nil
375376
}
376377
else Nil
377378

378379
val self1 = {
379380
val selfType = if (self.tpt.isEmpty) classTypeRef else self.tpt
380381
if (self.isEmpty) self
381-
else cpy.ValDef(self)(mods = self.mods | SelfName, tpt = selfType)
382+
else cpy.ValDef(self)(tpt = selfType).withMods(self.mods | SelfName)
382383
}
383384

384385
val cdef1 = {
385386
val originalTparams = constr1.tparams.toIterator
386387
val originalVparams = constr1.vparamss.toIterator.flatten
387-
val tparamAccessors = derivedTparams map { tdef =>
388-
cpy.TypeDef(tdef)(mods = originalTparams.next.mods)
389-
}
388+
val tparamAccessors = derivedTparams.map(_.withMods(originalTparams.next.mods))
390389
val caseAccessor = if (mods is Case) CaseAccessor else EmptyFlags
391-
val vparamAccessors = derivedVparamss.flatten map { vdef =>
392-
cpy.ValDef(vdef)(mods = originalVparams.next.mods | caseAccessor)
393-
}
390+
val vparamAccessors = derivedVparamss.flatten.map(_.withMods(originalVparams.next.mods | caseAccessor))
394391
cpy.TypeDef(cdef)(
395392
rhs = cpy.Template(impl)(constr, parents1, self1,
396393
tparamAccessors ::: vparamAccessors ::: normalizedBody ::: caseClassMeths),
@@ -415,19 +412,25 @@ object desugar {
415412
* <module> final class name$ extends parents { self: name.type => body }
416413
*/
417414
def moduleDef(mdef: ModuleDef)(implicit ctx: Context): Tree = {
418-
val ModuleDef(mods, name, tmpl) = mdef
415+
val ModuleDef(name, tmpl) = mdef
416+
val mods = mdef.mods
419417
if (mods is Package)
420-
PackageDef(Ident(name), cpy.ModuleDef(mdef)(mods &~ Package, nme.PACKAGE, tmpl) :: Nil)
418+
PackageDef(Ident(name), cpy.ModuleDef(mdef)(nme.PACKAGE, tmpl).withMods(mods &~ Package) :: Nil)
421419
else {
422420
val clsName = name.moduleClassName
423421
val clsRef = Ident(clsName)
424-
val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, New(clsRef, Nil)) withPos mdef.pos
425-
val ValDef(selfMods, selfName, selfTpt, selfRhs) = tmpl.self
422+
val modul = ValDef(name, clsRef, New(clsRef, Nil))
423+
.withMods(mods | ModuleCreationFlags)
424+
.withPos(mdef.pos)
425+
val ValDef(selfName, selfTpt, selfRhs) = tmpl.self
426+
val selfMods = tmpl.self.mods
426427
if (!selfTpt.isEmpty) ctx.error("object definition may not have a self type", tmpl.self.pos)
427-
val clsSelf = ValDef(selfMods, selfName, SingletonTypeTree(Ident(name)), selfRhs)
428+
val clsSelf = ValDef(selfName, SingletonTypeTree(Ident(name)), selfRhs)
429+
.withMods(selfMods)
428430
.withPos(tmpl.self.pos orElse tmpl.pos.startPos)
429431
val clsTmpl = cpy.Template(tmpl)(self = clsSelf, body = tmpl.body)
430-
val cls = TypeDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, clsTmpl)
432+
val cls = TypeDef(clsName, clsTmpl)
433+
.withMods(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags)
431434
Thicket(modul, classDef(cls))
432435
}
433436
}
@@ -459,7 +462,7 @@ object desugar {
459462
*/
460463
def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree)(implicit ctx: Context): Tree = pat match {
461464
case VarPattern(named, tpt) =>
462-
derivedValDef(mods, named, tpt, rhs)
465+
derivedValDef(named, tpt, rhs, mods)
463466
case _ =>
464467
val rhsUnchecked = makeAnnotated(defn.UncheckedAnnot, rhs)
465468
val vars = getVariables(pat)
@@ -476,15 +479,15 @@ object desugar {
476479
case Nil =>
477480
matchExpr
478481
case (named, tpt) :: Nil =>
479-
derivedValDef(mods, named, tpt, matchExpr)
482+
derivedValDef(named, tpt, matchExpr, mods)
480483
case _ =>
481484
val tmpName = ctx.freshName().toTermName
482-
val patMods = Modifiers(PrivateLocal | Synthetic | (mods.flags & Lazy))
483-
val firstDef = ValDef(patMods, tmpName, TypeTree(), matchExpr)
485+
val patFlags = PrivateLocal | Synthetic | (mods.flags & Lazy)
486+
val firstDef = ValDef(tmpName, TypeTree(), matchExpr).withFlags(patFlags)
484487
def selector(n: Int) = Select(Ident(tmpName), nme.selectorName(n))
485488
val restDefs =
486489
for (((named, tpt), n) <- vars.zipWithIndex)
487-
yield derivedValDef(mods, named, tpt, selector(n))
490+
yield derivedValDef(named, tpt, selector(n), mods)
488491
flatTree(firstDef :: restDefs)
489492
}
490493
}
@@ -527,7 +530,7 @@ object desugar {
527530
*/
528531
def makeClosure(params: List[ValDef], body: Tree, tpt: Tree = TypeTree()) =
529532
Block(
530-
DefDef(Modifiers(Synthetic), nme.ANON_FUN, Nil, params :: Nil, tpt, body),
533+
DefDef(nme.ANON_FUN, Nil, params :: Nil, tpt, body).withMods(synthetic),
531534
Closure(Nil, Ident(nme.ANON_FUN), EmptyTree))
532535

533536
/** Expand partial function
@@ -546,16 +549,16 @@ object desugar {
546549
def makeAnnotated(cls: Symbol, tree: Tree)(implicit ctx: Context) =
547550
Annotated(TypedSplice(tpd.New(cls.typeRef, Nil)), tree)
548551

549-
private def derivedValDef(mods: Modifiers, named: NameTree, tpt: Tree, rhs: Tree) =
550-
ValDef(mods, named.name.asTermName, tpt, rhs).withPos(named.pos)
552+
private def derivedValDef(named: NameTree, tpt: Tree, rhs: Tree, mods: Modifiers) =
553+
ValDef(named.name.asTermName, tpt, rhs).withMods(mods).withPos(named.pos)
551554

552555
/** Main desugaring method */
553556
def apply(tree: Tree)(implicit ctx: Context): Tree = {
554557

555558
/** { label def lname(): Unit = rhs; call }
556559
*/
557560
def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
558-
val ldef = DefDef(Modifiers(Label), lname, Nil, ListOfNil, TypeTree(defn.UnitType), rhs)
561+
val ldef = DefDef(lname, Nil, ListOfNil, TypeTree(defn.UnitType), rhs).withFlags(Label)
559562
Block(ldef, call)
560563
}
561564

@@ -576,7 +579,7 @@ object desugar {
576579
} else {
577580
val x = ctx.freshName().toTermName
578581
Block(
579-
ValDef(Modifiers(Synthetic), x, TypeTree(), left),
582+
ValDef(x, TypeTree(), left).withMods(synthetic),
580583
Apply(Select(right, op), Ident(x)))
581584
}
582585
}
@@ -637,7 +640,7 @@ object desugar {
637640
*/
638641
def makeLambda(pat: Tree, body: Tree): Tree = pat match {
639642
case VarPattern(named, tpt) =>
640-
Function(derivedValDef(Modifiers(Param), named, tpt, EmptyTree) :: Nil, body)
643+
Function(derivedValDef(named, tpt, EmptyTree, Modifiers(Param)) :: Nil, body)
641644
case _ =>
642645
makeCaseLambda(CaseDef(pat, EmptyTree, body) :: Nil)
643646
}
@@ -841,7 +844,7 @@ object desugar {
841844
def refinedTypeToClass(tree: RefinedTypeTree)(implicit ctx: Context): TypeDef = {
842845
val parent = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else tree.tpt
843846
val impl = Template(emptyConstructor, parent :: Nil, EmptyValDef, tree.refinements)
844-
TypeDef(Modifiers(Trait), tpnme.REFINE_CLASS, impl)
847+
TypeDef(tpnme.REFINE_CLASS, impl).withFlags(Trait)
845848
}
846849

847850
/** If tree is a variable pattern, return its name and type, otherwise return None.

0 commit comments

Comments
 (0)