Skip to content

Commit d5006b1

Browse files
committed
Methods to derive ValDefs and Templates.
It's a lot like the last one. I also found trees being duplicated before being sent to the tree copier. Looks like xerox has gotten a mole in here. Trust no one.
1 parent 4a984f8 commit d5006b1

File tree

15 files changed

+97
-64
lines changed

15 files changed

+97
-64
lines changed

src/compiler/scala/reflect/internal/Trees.scala

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,18 @@ trait Trees extends api.Trees { self: SymbolTable =>
272272
override def traverse(t: Tree) {
273273
if (t != EmptyTree && t.pos == NoPosition) {
274274
t.setPos(pos)
275-
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
275+
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
276+
// @PP: it's pruning whenever it encounters a node with a
277+
// position, which I interpret to mean that (in the author's
278+
// mind at least) either the children of a positioned node will
279+
// already be positioned, or the children of a positioned node
280+
// do not merit positioning.
281+
//
282+
// Whatever the author's rationale, it does seem like a bad idea
283+
// to press on through a positioned node to find unpositioned
284+
// children beneath it and then to assign whatever happens to
285+
// be in `pos` to such nodes. There are supposed to be some
286+
// position invariants which I can't imagine surviving that.
276287
}
277288
}
278289
}

src/compiler/scala/tools/nsc/ast/Trees.scala

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,16 @@ trait Trees extends reflect.internal.Trees { self: Global =>
7979
val (edefs, rest) = body span treeInfo.isEarlyDef
8080
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
8181
val gvdefs = evdefs map {
82-
case vdef @ ValDef(mods, name, tpt, rhs) =>
83-
treeCopy.ValDef(
84-
vdef.duplicate, mods, name,
85-
atPos(focusPos(vdef.pos)) { TypeTree() setOriginal tpt setPos focusPos(tpt.pos) }, // atPos in case
86-
EmptyTree)
87-
}
88-
val lvdefs = evdefs map {
89-
case vdef @ ValDef(mods, name, tpt, rhs) =>
90-
treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
82+
case vdef @ ValDef(_, _, tpt, _) => copyValDef(vdef)(
83+
// !!! I know "atPos in case" wasn't intentionally planted to
84+
// add an air of mystery to this file, but it is the sort of
85+
// comment which only its author could love.
86+
tpt = atPos(focusPos(vdef.pos))(TypeTree() setOriginal tpt setPos focusPos(tpt.pos)), // atPos in case
87+
rhs = EmptyTree
88+
)
9189
}
90+
val lvdefs = evdefs collect { case vdef: ValDef => copyValDef(vdef)(mods = Modifiers(PRESUPER)) }
91+
9292
val constrs = {
9393
if (constrMods hasFlag TRAIT) {
9494
if (body forall treeInfo.isInterfaceMember) List()
@@ -108,13 +108,11 @@ trait Trees extends reflect.internal.Trees { self: Global =>
108108
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
109109
}
110110
}
111-
// println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs)
112111
constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
113-
// vparamss2 are used as field definitions for the class. remove defaults
114-
val vparamss2 = vparamss map (vps => vps map { vd =>
115-
treeCopy.ValDef(vd, vd.mods &~ DEFAULTPARAM, vd.name, vd.tpt, EmptyTree)
116-
})
117-
Template(parents, self, gvdefs ::: vparamss2.flatten ::: constrs ::: etdefs ::: rest)
112+
// Field definitions for the class - remove defaults.
113+
val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree))
114+
115+
Template(parents, self, gvdefs ::: fieldDefs ::: constrs ::: etdefs ::: rest)
118116
}
119117

120118
/** Construct class definition with given class symbol, value parameters,

src/compiler/scala/tools/nsc/javac/JavaParsers.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,10 +653,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
653653
// leaves auxiliary constructors unable to access members of the companion object
654654
// as unqualified identifiers.
655655
def addCompanionObject(statics: List[Tree], cdef: ClassDef): List[Tree] = {
656-
def implWithImport(importStmt: Tree) = {
657-
import cdef.impl._
658-
treeCopy.Template(cdef.impl, parents, self, importStmt :: body)
659-
}
656+
def implWithImport(importStmt: Tree) = deriveTemplate(cdef.impl)(importStmt :: _)
660657
// if there are no statics we can use the original cdef, but we always
661658
// create the companion so import A._ is not an error (see ticket #1700)
662659
val cdefNew =

src/compiler/scala/tools/nsc/transform/Constructors.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
175175
else if (stat.symbol.isConstructor) auxConstructorBuf += stat
176176
else defBuf += stat
177177
}
178-
case ValDef(mods, name, tpt, rhs) =>
178+
case ValDef(_, _, _, rhs) =>
179179
// val defs with constant right-hand sides are eliminated.
180180
// for all other val defs, an empty valdef goes into the template and
181181
// the initializer goes as an assignment into the constructor
@@ -188,7 +188,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
188188
(if (canBeMoved(stat)) constrPrefixBuf else constrStatBuf) += mkAssign(
189189
stat.symbol, rhs1)
190190
}
191-
defBuf += treeCopy.ValDef(stat, mods, name, tpt, EmptyTree)
191+
defBuf += deriveValDef(stat)(_ => EmptyTree)
192192
}
193193
case ClassDef(_, _, _, _) =>
194194
// classes are treated recursively, and left in the template
@@ -560,8 +560,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
560560
clazz.info.decls unlink sym
561561

562562
// Eliminate all field definitions that can be dropped from template
563-
treeCopy.Template(impl, impl.parents, impl.self,
564-
defBuf.toList filter (stat => mustbeKept(stat.symbol)))
563+
deriveTemplate(impl)(_ => defBuf.toList filter (stat => mustbeKept(stat.symbol)))
565564
} // transformClassTemplate
566565

567566
override def transform(tree: Tree): Tree =

src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,10 @@ abstract class ExplicitOuter extends InfoTransform
468468
}
469469
}
470470
super.transform(
471-
treeCopy.Template(tree, parents, self,
472-
if (newDefs.isEmpty) decls else decls ::: newDefs.toList)
471+
deriveTemplate(tree)(decls =>
472+
if (newDefs.isEmpty) decls
473+
else decls ::: newDefs.toList
474+
)
473475
)
474476
case DefDef(_, _, _, vparamss, _, rhs) =>
475477
if (sym.isClassConstructor) {

src/compiler/scala/tools/nsc/transform/LambdaLift.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ abstract class LambdaLift extends InfoTransform {
326326
lifted(MethodType(sym.info.params ::: addParams, sym.info.resultType)))
327327

328328
copyDefDef(tree)(vparamss = List(vparams ++ freeParams))
329-
case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) =>
329+
case ClassDef(mods, name, tparams, impl) =>
330330
// Disabled attempt to to add getters to freeParams
331331
// this does not work yet. Problem is that local symbols need local names
332332
// and references to local symbols need to be transformed into
@@ -338,8 +338,7 @@ abstract class LambdaLift extends InfoTransform {
338338
// DefDef(getter, rhs) setPos tree.pos setType NoType
339339
// }
340340
// val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams
341-
treeCopy.ClassDef(tree, mods, name, tparams,
342-
treeCopy.Template(impl, parents, self, body ::: freeParams))
341+
treeCopy.ClassDef(tree, mods, name, tparams, deriveTemplate(impl)(_ ::: freeParams))
343342
}
344343
case None =>
345344
tree
@@ -481,15 +480,14 @@ abstract class LambdaLift extends InfoTransform {
481480
/** Transform statements and add lifted definitions to them. */
482481
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
483482
def addLifted(stat: Tree): Tree = stat match {
484-
case ClassDef(mods, name, tparams, impl @ Template(parents, self, body)) =>
483+
case ClassDef(mods, name, tparams, impl) =>
485484
val lifted = liftedDefs get stat.symbol match {
486485
case Some(xs) => xs reverseMap addLifted
487486
case _ => log("unexpectedly no lifted defs for " + stat.symbol) ; Nil
488487
}
489-
val result = treeCopy.ClassDef(
490-
stat, mods, name, tparams, treeCopy.Template(impl, parents, self, body ::: lifted))
491-
liftedDefs -= stat.symbol
492-
result
488+
try treeCopy.ClassDef(stat, mods, name, tparams, deriveTemplate(impl)(_ ::: lifted))
489+
finally liftedDefs -= stat.symbol
490+
493491
case DefDef(_, _, _, _, _, Block(Nil, expr)) if !stat.symbol.isConstructor =>
494492
deriveDefDef(stat)(_ => expr)
495493
case _ =>

src/compiler/scala/tools/nsc/transform/LazyVals.scala

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
9393
deriveDefDef(tree)(_ => if (LocalLazyValFinder.find(res)) typed(addBitmapDefs(sym, res)) else res)
9494
}
9595

96-
case Template(parents, self, body) => atOwner(currentOwner) {
96+
case Template(_, _, body) => atOwner(currentOwner) {
9797
val body1 = super.transformTrees(body)
9898
var added = false
9999
val stats =
@@ -105,8 +105,8 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
105105
added = true
106106
typed(addBitmapDefs(sym, stat))
107107
} else stat
108-
case ValDef(mods, name, tpt, rhs) =>
109-
typed(treeCopy.ValDef(stat, mods, name, tpt, addBitmapDefs(stat.symbol, rhs)))
108+
case ValDef(_, _, _, _) =>
109+
typed(deriveValDef(stat)(addBitmapDefs(stat.symbol, _)))
110110
case _ =>
111111
stat
112112
}
@@ -121,13 +121,14 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD
121121
})
122122
toAdd0
123123
} else List()
124-
treeCopy.Template(tree, parents, self, innerClassBitmaps ++ stats)
124+
deriveTemplate(tree)(_ => innerClassBitmaps ++ stats)
125125
}
126126

127-
case ValDef(mods, name, tpt, rhs0) if (!sym.owner.isModule && !sym.owner.isClass) =>
128-
val rhs = super.transform(rhs0)
129-
treeCopy.ValDef(tree, mods, name, tpt,
130-
if (LocalLazyValFinder.find(rhs)) typed(addBitmapDefs(sym, rhs)) else rhs)
127+
case ValDef(_, _, _, _) if !sym.owner.isModule && !sym.owner.isClass =>
128+
deriveValDef(tree) { rhs0 =>
129+
val rhs = super.transform(rhs0)
130+
if (LocalLazyValFinder.find(rhs)) typed(addBitmapDefs(sym, rhs)) else rhs
131+
}
131132

132133
case l@LabelDef(name0, params0, ifp0@If(_, _, _)) if name0.startsWith(nme.WHILE_PREFIX) =>
133134
val ifp1 = super.transform(ifp0)

src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,21 +1480,22 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
14801480
localTyper.typed(deriveDefDef(tree)(rhs => rhs))
14811481
}
14821482

1483-
case ValDef(mods, name, tpt, rhs) if symbol.hasFlag(SPECIALIZED) && !symbol.isParamAccessor =>
1483+
case ValDef(_, _, _, _) if symbol.hasFlag(SPECIALIZED) && !symbol.isParamAccessor =>
14841484
assert(body.isDefinedAt(symbol.alias), body)
1485-
val tree1 = treeCopy.ValDef(tree, mods, name, tpt, body(symbol.alias).duplicate)
1485+
val tree1 = deriveValDef(tree)(_ => body(symbol.alias).duplicate)
14861486
debuglog("now typing: " + tree1 + " in " + tree.symbol.owner.fullName)
1487+
14871488
val d = new Duplicator
1488-
val ValDef(mods1, name1, tpt1, rhs1) = d.retyped(
1489+
val newValDef = d.retyped(
14891490
localTyper.context1.asInstanceOf[d.Context],
14901491
tree1,
14911492
symbol.alias.enclClass,
14921493
symbol.enclClass,
14931494
typeEnv(symbol.alias) ++ typeEnv(tree.symbol)
14941495
)
1495-
val t = treeCopy.ValDef(tree1, mods1, name1, tpt1, transform(rhs1))
1496-
log("valdef " + tree + " -> " + t)
1497-
t
1496+
logResult("valdef " + tree + " -> ") {
1497+
deriveValDef(newValDef)(transform)
1498+
}
14981499

14991500
// val tree1 =
15001501
// treeCopy.ValDef(tree, mods, name, tpt,

src/compiler/scala/tools/nsc/transform/UnCurry.scala

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -620,13 +620,11 @@ abstract class UnCurry extends InfoTransform
620620
* In particular, this case will add:
621621
* - synthetic Java varargs forwarders for repeated parameters
622622
*/
623-
case Template(parents, self, body) =>
623+
case Template(_, _, _) =>
624624
localTyper = typer.atOwner(tree, currentClass)
625-
val tmpl = if (!forMSIL || forMSIL) {
626-
treeCopy.Template(tree, parents, self, transformTrees(newMembers.toList) ::: body)
627-
} else super.transform(tree).asInstanceOf[Template]
628-
newMembers.clear
629-
tmpl
625+
try deriveTemplate(tree)(transformTrees(newMembers.toList) ::: _)
626+
finally newMembers.clear()
627+
630628
case dd @ DefDef(_, _, _, vparamss0, _, rhs0) =>
631629
val flatdd = copyDefDef(dd)(
632630
vparamss = List(vparamss0.flatten),

src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ trait MethodSynthesis {
376376
override def keepClean = !mods.isParamAccessor
377377
override def derivedTree = (
378378
if (mods.isDeferred) EmptyTree
379-
else treeCopy.ValDef(tree, mods | flagsExtra, name, tree.tpt, tree.rhs)
379+
else copyValDef(tree)(mods = mods | flagsExtra, name = this.name)
380380
)
381381
}
382382
case class Param(tree: ValDef) extends DerivedFromValDef {

0 commit comments

Comments
 (0)