diff options
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 |