diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-23 09:21:12 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-23 09:21:16 -0800 |
commit | 382a16e948b146c6e32a4c9e7f01fb2624717e57 (patch) | |
tree | 3b3685e72b6d645adf5df14abeffe5384194e329 /src | |
parent | 329d99829d4e51d0847000439de595de7b565686 (diff) | |
download | scala-382a16e948b146c6e32a4c9e7f01fb2624717e57.tar.gz scala-382a16e948b146c6e32a4c9e7f01fb2624717e57.tar.bz2 scala-382a16e948b146c6e32a4c9e7f01fb2624717e57.zip |
One more to derive trees.
ClassDefs, CaseDefs, and LabelDefs. Dotting eyes,
crossing tees. Point of diminishing returns is reached,
declare victory and withdraw.
Diffstat (limited to 'src')
16 files changed, 99 insertions, 66 deletions
diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala index 94672097c4..e3fb1a9cad 100644 --- a/src/compiler/scala/reflect/internal/util/Collections.scala +++ b/src/compiler/scala/reflect/internal/util/Collections.scala @@ -65,6 +65,16 @@ trait Collections { lb.toList } + final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) { + var index = 0 + var ys = xs + while (!ys.isEmpty) { + f(ys.head, index) + ys = ys.tail + index += 1 + } + } + final def mapWithIndex[A, B](xs: List[A])(f: (A, Int) => B): List[B] = { val lb = new ListBuffer[B] var index = 0 diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index e3a59058a3..8e445a62db 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -1423,15 +1423,14 @@ self => def implicitClosure(start: Int, location: Int): Tree = { val param0 = convertToParam { atPos(in.offset) { - var paramexpr: Tree = Ident(ident()) - if (in.token == COLON) { - in.nextToken() - paramexpr = Typed(paramexpr, typeOrInfixType(location)) + Ident(ident()) match { + case expr if in.token == COLON => + in.nextToken() ; Typed(expr, typeOrInfixType(location)) + case expr => expr } - paramexpr } } - val param = treeCopy.ValDef(param0, param0.mods | Flags.IMPLICIT, param0.name, param0.tpt, param0.rhs) + val param = copyValDef(param0)(mods = param0.mods | Flags.IMPLICIT) atPos(start, in.offset) { accept(ARROW) Function(List(param), if (location != InBlock) expr() else block()) @@ -2689,8 +2688,8 @@ self => val (self, body) = templateBody(true) if (in.token == WITH && self.isEmpty) { val earlyDefs: List[Tree] = body flatMap { - case vdef @ ValDef(mods, name, tpt, rhs) if !mods.isDeferred => - List(treeCopy.ValDef(vdef, mods | Flags.PRESUPER, name, tpt, rhs)) + case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred => + List(copyValDef(vdef)(mods = mods | Flags.PRESUPER)) case tdef @ TypeDef(mods, name, tparams, rhs) => List(treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs)) case stat if !stat.isEmpty => diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala index c06bd2e097..69de0dfa90 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala @@ -105,11 +105,9 @@ abstract class ReachingDefinitions { def genAndKill(b: BasicBlock): (ListSet[Definition], ListSet[Local]) = { var genSet = ListSet[Definition]() var killSet = ListSet[Local]() - for ((i, idx) <- b.toList.zipWithIndex) i match { - case STORE_LOCAL(local) => - killSet = killSet + local - genSet = updateReachingDefinition(b, idx, genSet) - case _ => () + for ((STORE_LOCAL(local), idx) <- b.toList.zipWithIndex) { + killSet = killSet + local + genSet = updateReachingDefinition(b, idx, genSet) } (genSet, killSet) } diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 5fc7329955..95c371fa8b 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -225,9 +225,9 @@ abstract class DeadCodeElimination extends SubComponent { m foreachBlock { bb => assert(bb.closed, "Open block in computeCompensations") - for ((i, idx) <- bb.toList.zipWithIndex) { + foreachWithIndex(bb.toList) { (i, idx) => if (!useful(bb)(idx)) { - for ((consumedType, depth) <- i.consumedTypes.reverse.zipWithIndex) { + foreachWithIndex(i.consumedTypes.reverse) { (consumedType, depth) => log("Finding definitions of: " + i + "\n\t" + consumedType + " at depth: " + depth) val defs = rdef.findDefs(bb, idx, 1, depth) for (d <- defs) { diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala index 62f6c90fba..4d94ed68fc 100644 --- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala +++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala @@ -658,7 +658,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners { // create the companion so import A._ is not an error (see ticket #1700) val cdefNew = if (statics.isEmpty) cdef - else treeCopy.ClassDef(cdef, cdef.mods, cdef.name, cdef.tparams, implWithImport(importCompanionObject(cdef))) + else deriveClassDef(cdef)(_ => implWithImport(importCompanionObject(cdef))) List(makeCompanionObject(cdefNew, statics), cdefNew) } diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index d5a413337b..7029f599b8 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -316,9 +316,9 @@ abstract class AddInterfaces extends InfoTransform { override def transform(tree: Tree): Tree = { val sym = tree.symbol val tree1 = tree match { - case ClassDef(mods, name, tparams, impl) if (sym.needsImplClass) => + case ClassDef(mods, _, _, impl) if sym.needsImplClass => implClass(sym).initialize // to force lateDEFERRED flags - treeCopy.ClassDef(tree, mods | INTERFACE, name, tparams, ifaceTemplate(impl)) + copyClassDef(tree)(mods = mods | INTERFACE, impl = ifaceTemplate(impl)) case DefDef(_,_,_,_,_,_) if sym.isClassConstructor && sym.isPrimaryConstructor && sym.owner != ArrayClass => deriveDefDef(tree)(addMixinConstructorCalls(_, sym.owner)) // (3) case Template(parents, self, body) => diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 4521ce9982..2c024fe6fa 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -47,7 +47,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { val Template(parents, self, body) = tree clearStatics() val newBody = transformTrees(body) - val templ = treeCopy.Template(tree, parents, self, transformTrees(newStaticMembers.toList) ::: newBody) + val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody) try addStaticInits(templ) // postprocess to include static ctors finally clearStatics() } @@ -686,7 +686,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL { localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs)) } - treeCopy.Template(template, template.parents, template.self, newCtor :: template.body) + deriveTemplate(template)(newCtor :: _) } } diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index bbcf93114c..ab8468b863 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -565,8 +565,8 @@ abstract class Constructors extends Transform with ast.TreeDSL { override def transform(tree: Tree): Tree = tree match { - case ClassDef(mods, name, tparams, impl) if !tree.symbol.isInterface && !isValueClass(tree.symbol) => - treeCopy.ClassDef(tree, mods, name, tparams, transformClassTemplate(impl)) + case ClassDef(_,_,_,_) if !tree.symbol.isInterface && !isValueClass(tree.symbol) => + deriveClassDef(tree)(transformClassTemplate) case _ => super.transform(tree) } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index c1ddd21e9d..5c4d39dc5c 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -421,9 +421,9 @@ abstract class Erasure extends AddInterfaces /** Box `tree` of unboxed type */ private def box(tree: Tree): Tree = tree match { - case LabelDef(name, params, rhs) => - val rhs1 = box(rhs) - treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe + case LabelDef(_, _, _) => + val ldef = deriveLabelDef(tree)(box) + ldef setType ldef.rhs.tpe case _ => typedPos(tree.pos)(tree.tpe.typeSymbol match { case UnitClass => @@ -460,9 +460,9 @@ abstract class Erasure extends AddInterfaces println("unbox shorten: "+tree) // this never seems to kick in during build and test; therefore disabled. adaptToType(unboxed, pt) */ - case LabelDef(name, params, rhs) => - val rhs1 = unbox(rhs, pt) - treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe + case LabelDef(_, _, _) => + val ldef = deriveLabelDef(tree)(unbox(_, pt)) + ldef setType ldef.rhs.tpe case _ => typedPos(tree.pos)(pt.typeSymbol match { case UnitClass => @@ -604,8 +604,8 @@ abstract class Erasure extends AddInterfaces throw ex } def adaptCase(cdef: CaseDef): CaseDef = { - val body1 = adaptToType(cdef.body, tree1.tpe) - treeCopy.CaseDef(cdef, cdef.pat, cdef.guard, body1) setType body1.tpe + val newCdef = deriveCaseDef(cdef)(adaptToType(_, tree1.tpe)) + newCdef setType newCdef.body.tpe } def adaptBranch(branch: Tree): Tree = if (branch == EmptyTree) branch else adaptToType(branch, tree1.tpe); @@ -846,9 +846,9 @@ abstract class Erasure extends AddInterfaces */ private val preTransformer = new TypingTransformer(unit) { def preErase(tree: Tree): Tree = tree match { - case ClassDef(mods, name, tparams, impl) => + case ClassDef(_,_,_,_) => debuglog("defs of " + tree.symbol + " = " + tree.symbol.info.decls) - treeCopy.ClassDef(tree, mods, name, List(), impl) + copyClassDef(tree)(tparams = Nil) case DefDef(_,_,_,_,_,_) => copyDefDef(tree)(tparams = Nil) case TypeDef(_, _, _, _) => diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 50a75f896b..11cd5adf59 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -326,7 +326,7 @@ abstract class LambdaLift extends InfoTransform { lifted(MethodType(sym.info.params ::: addParams, sym.info.resultType))) copyDefDef(tree)(vparamss = List(vparams ++ freeParams)) - case ClassDef(mods, name, tparams, impl) => + case ClassDef(_, _, _, _) => // Disabled attempt to to add getters to freeParams // this does not work yet. Problem is that local symbols need local names // and references to local symbols need to be transformed into @@ -338,7 +338,7 @@ abstract class LambdaLift extends InfoTransform { // DefDef(getter, rhs) setPos tree.pos setType NoType // } // val newDefs = if (sym.isTrait) freeParams ::: (ps map paramGetter) else freeParams - treeCopy.ClassDef(tree, mods, name, tparams, deriveTemplate(impl)(_ ::: freeParams)) + deriveClassDef(tree)(impl => deriveTemplate(impl)(_ ::: freeParams)) } case None => tree @@ -480,12 +480,12 @@ abstract class LambdaLift extends InfoTransform { /** Transform statements and add lifted definitions to them. */ override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = { def addLifted(stat: Tree): Tree = stat match { - case ClassDef(mods, name, tparams, impl) => + case ClassDef(_, _, _, _) => val lifted = liftedDefs get stat.symbol match { case Some(xs) => xs reverseMap addLifted case _ => log("unexpectedly no lifted defs for " + stat.symbol) ; Nil } - try treeCopy.ClassDef(stat, mods, name, tparams, deriveTemplate(impl)(_ ::: lifted)) + try deriveClassDef(stat)(impl => deriveTemplate(impl)(_ ::: lifted)) finally liftedDefs -= stat.symbol case DefDef(_, _, _, _, _, Block(Nil, expr)) if !stat.symbol.isConstructor => diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 28bb2f3501..0e873f80ab 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -133,18 +133,17 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD case l@LabelDef(name0, params0, ifp0@If(_, _, _)) if name0.startsWith(nme.WHILE_PREFIX) => val ifp1 = super.transform(ifp0) val If(cond0, thenp0, elsep0) = ifp1 + if (LocalLazyValFinder.find(thenp0)) - treeCopy.LabelDef(l, name0, params0, - treeCopy.If(ifp1, cond0, typed(addBitmapDefs(sym.owner, thenp0)), elsep0)) + deriveLabelDef(l)(_ => treeCopy.If(ifp1, cond0, typed(addBitmapDefs(sym.owner, thenp0)), elsep0)) else l - case l@LabelDef(name0, params0, block@Block(stats0, _)) + case l@LabelDef(name0, params0, block@Block(stats0, expr)) if name0.startsWith(nme.WHILE_PREFIX) || name0.startsWith(nme.DO_WHILE_PREFIX) => val stats1 = super.transformTrees(stats0) if (LocalLazyValFinder.find(stats1)) - treeCopy.LabelDef(l, name0, params0, - treeCopy.Block(block, typed(addBitmapDefs(sym.owner, stats1.head))::stats1.tail, block.expr)) + deriveLabelDef(l)(_ => treeCopy.Block(block, typed(addBitmapDefs(sym.owner, stats1.head))::stats1.tail, expr)) else l @@ -169,9 +168,9 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD def isMatch(params: List[Ident]) = (params.tail corresponds methSym.tpe.params)(_.tpe == _.tpe) if (bmps.isEmpty) rhs else rhs match { - case Block(assign, l @ LabelDef(name, params, rhs1)) + case Block(assign, l @ LabelDef(name, params, _)) if name.toString == ("_" + methSym.name) && isMatch(params) => - Block(assign, treeCopy.LabelDef(l, name, params, typed(prependStats(bmps, rhs1)))) + Block(assign, deriveLabelDef(l)(rhs => typed(prependStats(bmps, rhs)))) case _ => prependStats(bmps, rhs) } diff --git a/src/compiler/scala/tools/nsc/transform/TailCalls.scala b/src/compiler/scala/tools/nsc/transform/TailCalls.scala index 93fcd27191..d55c8b3eb5 100644 --- a/src/compiler/scala/tools/nsc/transform/TailCalls.scala +++ b/src/compiler/scala/tools/nsc/transform/TailCalls.scala @@ -262,11 +262,7 @@ abstract class TailCalls extends Transform { ) case CaseDef(pat, guard, body) => - treeCopy.CaseDef(tree, - pat, - guard, - transform(body) - ) + deriveCaseDef(tree)(transform) case If(cond, thenp, elsep) => treeCopy.If(tree, diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala index 179bea0035..b6a7a52a05 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala @@ -256,7 +256,7 @@ abstract class Duplicators extends Analyzer { case ldef @ LabelDef(name, params, rhs) => // log("label def: " + ldef) ldef.tpe = null - val params1 = params map { p => Ident(updateSym(p.symbol)) } + val params1 = params map (p => Ident(updateSym(p.symbol))) super.typed(treeCopy.LabelDef(tree, name, params1, rhs), mode, pt) case Bind(name, _) => diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 3a3c244d1c..44a3abf1b2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -37,21 +37,17 @@ trait NamesDefaults { self: Analyzer => } def isNamed(arg: Tree) = nameOf(arg).isDefined - /** @param pos maps indicies from old to new */ + /** @param pos maps indices from old to new */ def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { val res = new Array[T](args.length) - // (hopefully) faster than zipWithIndex - (0 /: args) { case (index, arg) => res(pos(index)) = arg; index + 1 } + foreachWithIndex(args)((arg, index) => res(pos(index)) = arg) res.toList } - /** @param pos maps indicies from new to old (!) */ + /** @param pos maps indices from new to old (!) */ def reorderArgsInv[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = { val argsArray = args.toArray - val res = new mutable.ListBuffer[T] - for (i <- 0 until argsArray.length) - res += argsArray(pos(i)) - res.toList + argsArray.indices map (i => argsArray(pos(i))) toList } /** returns `true` if every element is equal to its index */ @@ -507,7 +503,7 @@ trait NamesDefaults { self: Analyzer => /** * Removes name assignments from args. Additionally, returns an array mapping - * argument indicies from call-site-order to definition-site-order. + * argument indices from call-site-order to definition-site-order. * * Verifies that names are not specified twice, positional args don't appear * after named ones. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 25e6de462e..223a7408b6 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1861,8 +1861,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { val restpe = ldef.symbol.tpe.resultType val rhs1 = typed(ldef.rhs, restpe) ldef.params foreach (param => param.tpe = param.symbol.tpe) - treeCopy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType restpe - } else { + deriveLabelDef(ldef)(_ => rhs1) setType restpe + } + else { val initpe = ldef.symbol.tpe.resultType val rhs1 = typed(ldef.rhs) val restpe = rhs1.tpe @@ -1875,7 +1876,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { context.owner.newLabel(ldef.name, ldef.pos) setInfo MethodType(List(), restpe)) val rhs2 = typed(resetAllAttrs(ldef.rhs), restpe) ldef.params foreach (param => param.tpe = param.symbol.tpe) - treeCopy.LabelDef(ldef, ldef.name, ldef.params, rhs2) setSymbol sym2 setType restpe + deriveLabelDef(ldef)(_ => rhs2) setSymbol sym2 setType restpe } } } @@ -4112,7 +4113,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { } def adaptCase(cdef: CaseDef, tpe: Type): CaseDef = - treeCopy.CaseDef(cdef, cdef.pat, cdef.guard, adapt(cdef.body, mode, tpe)) + deriveCaseDef(cdef)(adapt(_, mode, tpe)) // begin typed1 val sym: Symbol = tree.symbol diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala index 7d3477a227..bf427df09a 100644 --- a/src/library/scala/reflect/api/Trees.scala +++ b/src/library/scala/reflect/api/Trees.scala @@ -681,10 +681,10 @@ trait Trees { self: Universe => sys.error("Not a DefDef: " + t + "/" + t.getClass) } def copyValDef(tree: Tree)( - mods: Modifiers = null, - name: Name = null, - tpt: Tree = null, - rhs: Tree = null + mods: Modifiers = null, + name: Name = null, + tpt: Tree = null, + rhs: Tree = null ): ValDef = tree match { case ValDef(mods0, name0, tpt0, rhs0) => treeCopy.ValDef(tree, @@ -696,6 +696,22 @@ trait Trees { self: Universe => case t => sys.error("Not a ValDef: " + t + "/" + t.getClass) } + def copyClassDef(tree: Tree)( + mods: Modifiers = null, + name: Name = null, + tparams: List[TypeDef] = null, + impl: Template = null + ): ClassDef = tree match { + case ClassDef(mods0, name0, tparams0, impl0) => + treeCopy.ClassDef(tree, + if (mods eq null) mods0 else mods, + if (name eq null) name0 else name, + if (tparams eq null) tparams0 else tparams, + if (impl eq null) impl0 else impl + ) + case t => + sys.error("Not a ClassDef: " + t + "/" + t.getClass) + } def deriveDefDef(ddef: Tree)(applyToRhs: Tree => Tree): DefDef = ddef match { case DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) => @@ -715,6 +731,24 @@ trait Trees { self: Universe => case t => sys.error("Not a Template: " + t + "/" + t.getClass) } + def deriveClassDef(cdef: Tree)(applyToImpl: Template => Template): ClassDef = cdef match { + case ClassDef(mods0, name0, tparams0, impl0) => + treeCopy.ClassDef(cdef, mods0, name0, tparams0, applyToImpl(impl0)) + case t => + sys.error("Not a ClassDef: " + t + "/" + t.getClass) + } + def deriveCaseDef(cdef: Tree)(applyToBody: Tree => Tree): CaseDef = cdef match { + case CaseDef(pat0, guard0, body0) => + treeCopy.CaseDef(cdef, pat0, guard0, applyToBody(body0)) + case t => + sys.error("Not a CaseDef: " + t + "/" + t.getClass) + } + def deriveLabelDef(ldef: Tree)(applyToRhs: Tree => Tree): LabelDef = ldef match { + case LabelDef(name0, params0, rhs0) => + treeCopy.LabelDef(ldef, name0, params0, applyToRhs(rhs0)) + case t => + sys.error("Not a LabelDef: " + t + "/" + t.getClass) + } class Traverser { protected var currentOwner: Symbol = definitions.RootClass |