summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/LazyVals.scala
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-10-20 13:26:07 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-10-20 13:26:07 +0000
commitadd9be644fd7b2864e4dcdd792980622622c934a (patch)
tree6db3295dcbbcc453ac9f57ae8993ff0e3a68c4b9 /src/compiler/scala/tools/nsc/transform/LazyVals.scala
parentde3e8492e61e02777520e8876e9e1bccb4b0f065 (diff)
downloadscala-add9be644fd7b2864e4dcdd792980622622c934a.tar.gz
scala-add9be644fd7b2864e4dcdd792980622622c934a.tar.bz2
scala-add9be644fd7b2864e4dcdd792980622622c934a.zip
Closes #3670, #3877.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/LazyVals.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala60
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)
}
}