diff options
author | Hubert Plociniczak <hubert.plociniczak@epfl.ch> | 2010-10-20 13:26:07 +0000 |
---|---|---|
committer | Hubert Plociniczak <hubert.plociniczak@epfl.ch> | 2010-10-20 13:26:07 +0000 |
commit | add9be644fd7b2864e4dcdd792980622622c934a (patch) | |
tree | 6db3295dcbbcc453ac9f57ae8993ff0e3a68c4b9 /src | |
parent | de3e8492e61e02777520e8876e9e1bccb4b0f065 (diff) | |
download | scala-add9be644fd7b2864e4dcdd792980622622c934a.tar.gz scala-add9be644fd7b2864e4dcdd792980622622c934a.tar.bz2 scala-add9be644fd7b2864e4dcdd792980622622c934a.zip |
Closes #3670, #3877.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LazyVals.scala | 60 |
1 files changed, 55 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala index 98b98b06ac..02da067619 100644 --- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala +++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala @@ -16,6 +16,28 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD def newTransformer(unit: CompilationUnit): Transformer = new LazyValues(unit) + object LocalLazyValFinder extends Traverser { + var result: Boolean = _ + + def find(t: Tree) = {result = false; traverse(t); result} + def find(ts: List[Tree]) = {result = false; traverseTrees(ts); result} + + override def traverse(t: Tree) { + if (!result) + t match { + case v@ValDef(_, _, _, _) if v.symbol.isLazy => + result = true + + case ClassDef(_, _, _, _) | DefDef(_, _, _, _, _, _) | ModuleDef(_, _, _) => + + case LabelDef(name, _, _) if nme.isLoopHeaderLabel(name) => + + case _ => + super.traverse(t) + } + } + } + /** * Transform local lazy accessors to check for the initialized bit. */ @@ -46,14 +68,15 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD val enclosingDummyOrMethod = if (sym.enclMethod == NoSymbol) sym.owner else sym.enclMethod val idx = lazyVals(enclosingDummyOrMethod) + lazyVals(enclosingDummyOrMethod) = idx + 1 val rhs1 = mkLazyDef(enclosingDummyOrMethod, super.transform(rhs), idx) - lazyVals(sym.owner) = idx + 1 sym.resetFlag(LAZY | ACCESSOR) rhs1 } else super.transform(rhs) + treeCopy.DefDef(tree, mods, name, tparams, vparams, tpt, - typed(addBitmapDefs(sym, res))) + if (LocalLazyValFinder.find(res)) typed(addBitmapDefs(sym, res)) else res) } case Template(parents, self, body) => atOwner(currentOwner) { @@ -61,9 +84,13 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD var added = false val stats = for (stat <- body1) yield stat match { - case Block(_, _) if !added => - added = true - typed(addBitmapDefs(sym, stat)) + case Block(_, _) | Apply(_, _) | If(_, _, _) if !added => + // Avoid adding bitmaps when they are fully overshadowed by those + // that are added inside loops + if (LocalLazyValFinder.find(stat)) { + added = true + typed(addBitmapDefs(sym, stat)) + } else stat case ValDef(mods, name, tpt, rhs) => typed(treeCopy.ValDef(stat, mods, name, tpt, addBitmapDefs(stat.symbol, rhs))) case _ => @@ -72,6 +99,29 @@ abstract class LazyVals extends Transform with TypingTransformers with ast.TreeD treeCopy.Template(tree, parents, self, stats) } + case ValDef(mods, name, tpt, rhs0) if (!sym.owner.isModule && !sym.owner.isClass) => + val rhs = super.transform(rhs0) + treeCopy.ValDef(tree, mods, name, tpt, + if (LocalLazyValFinder.find(rhs)) typed(addBitmapDefs(sym, rhs)) else rhs) + + 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)) + else + l + + case l@LabelDef(name0, params0, block@Block(stats0, _)) + 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)) + else + l + case _ => super.transform(tree) } } |