Skip to content

Commit f7a4d81

Browse files
committed
Drop modifiers as separate data from MemberDef trees
Typed MemberDef trees now take the modifiers from their symbol's data.
1 parent c9d7eef commit f7a4d81

29 files changed

+299
-424
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.

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

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
1818
}
1919

2020
def isDeclarationOrTypeDef(tree: Tree): Boolean = unsplice(tree) match {
21-
case DefDef(_, _, _, _, _, EmptyTree)
22-
| ValDef(_, _, _, EmptyTree)
23-
| TypeDef(_, _, _) => true
21+
case DefDef(_, _, _, _, EmptyTree)
22+
| ValDef(_, _, EmptyTree)
23+
| TypeDef(_, _) => true
2424
case _ => false
2525
}
2626

2727
/** Is tree legal as a member definition of an interface?
2828
*/
2929
def isPureInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
30-
case EmptyTree | Import(_, _) | TypeDef(_, _, _) => true
31-
case DefDef(_, _, _, _, _, rhs) => rhs.isEmpty
32-
case ValDef(mods, _, _, rhs) => rhs.isEmpty
30+
case EmptyTree | Import(_, _) | TypeDef(_, _) => true
31+
case DefDef(_, _, _, _, rhs) => rhs.isEmpty
32+
case ValDef(_, _, rhs) => rhs.isEmpty
3333
case _ => false
3434
}
3535

@@ -91,7 +91,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
9191

9292
/** If tree is a closure, it's body, otherwise tree itself */
9393
def closureBody(tree: tpd.Tree): tpd.Tree = tree match {
94-
case Block(DefDef(_, nme.ANON_FUN, _, _, _, rhs) :: Nil, Closure(_, _, _)) => rhs
94+
case Block(DefDef(nme.ANON_FUN, _, _, _, rhs) :: Nil, Closure(_, _, _)) => rhs
9595
case _ => tree
9696
}
9797

@@ -162,26 +162,10 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
162162

163163
/** The arguments to the first constructor in `stats`. */
164164
def firstConstructorArgs(stats: List[Tree]): List[Tree] = firstConstructor(stats) match {
165-
case DefDef(_, _, _, args :: _, _, _) => args
165+
case DefDef(_, _, args :: _, _, _) => args
166166
case _ => Nil
167167
}
168168

169-
/** The value definitions marked PRESUPER in this statement sequence */
170-
def preSuperFields(stats: List[Tree]): List[ValDef] =
171-
(stats filter isEarlyValDef).asInstanceOf[List[ValDef]]
172-
173-
def isEarlyDef(tree: Tree) = isEarlyValDef(tree) || isEarlyTypeDef(tree)
174-
175-
def isEarlyValDef(tree: Tree) = unsplice(tree) match {
176-
case ValDef(mods, _, _, _) => mods is Scala2PreSuper
177-
case _ => false
178-
}
179-
180-
def isEarlyTypeDef(tree: Tree) = unsplice(tree) match {
181-
case TypeDef(mods, _, _) => mods is Scala2PreSuper
182-
case _ => false
183-
}
184-
185169
/** Is tpt a vararg type of the form T* ? */
186170
def isRepeatedParamType(tpt: Tree)(implicit ctx: Context) = tpt match {
187171
case tpt: TypeTree => tpt.typeOpt.isRepeatedParam
@@ -263,7 +247,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
263247
/** True iff definition if a val or def with no right-hand-side, or it
264248
* is an abstract typoe declaration
265249
*/
266-
def lacksDefinition(mdef: MemberDef) = mdef match {
250+
def lacksDefinition(mdef: MemberDef)(implicit ctx: Context) = mdef match {
267251
case mdef: ValOrDefDef => mdef.rhs.isEmpty && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
268252
case mdef: TypeDef => mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
269253
case _ => false
@@ -299,12 +283,12 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
299283
*/
300284
private def statPurity(tree: tpd.Tree)(implicit ctx: Context): PurityLevel = unsplice(tree) match {
301285
case EmptyTree
302-
| TypeDef(_, _, _)
286+
| TypeDef(_, _)
303287
| Import(_, _)
304-
| DefDef(_, _, _, _, _, _) =>
288+
| DefDef(_, _, _, _, _) =>
305289
Pure
306-
case ValDef(mods, _, _, rhs) =>
307-
if (mods is Mutable) Impure else exprPurity(rhs)
290+
case vdef @ ValDef(_, _, rhs) =>
291+
if (vdef.mods is Mutable) Impure else exprPurity(rhs)
308292
case _ =>
309293
Impure
310294
}

0 commit comments

Comments
 (0)