summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2007-06-27 14:26:47 +0000
committerIulian Dragos <jaguarul@gmail.com>2007-06-27 14:26:47 +0000
commitb4b91dcb58b5804f7ec1513e8f4d1e4534fd8018 (patch)
tree758a2817dd728101980c7ffc3f206d484ad77ba0 /src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
parenta1ec75c2642396a83854510ba7e88d8a302a67fd (diff)
downloadscala-b4b91dcb58b5804f7ec1513e8f4d1e4534fd8018.tar.gz
scala-b4b91dcb58b5804f7ec1513e8f4d1e4534fd8018.tar.bz2
scala-b4b91dcb58b5804f7ec1513e8f4d1e4534fd8018.zip
Merged lazy values branch to trunk.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala29
1 files changed, 25 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index bad97b2d1c..162d291ddd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -566,6 +566,11 @@ abstract class RefChecks extends InfoTransform {
stats1
}
+ /** Implements lazy value accessors:
+ * - for lazy fields inside traits, the rhs is the initializer itself
+ * - for all other lazy values z the accessor is a block of this form:
+ * { z = <rhs>; z } where z can be an identifier or a field.
+ */
def transformStat(tree: Tree, index: int): List[Tree] = tree match {
case ModuleDef(mods, name, impl) =>
val sym = tree.symbol
@@ -622,11 +627,27 @@ abstract class RefChecks extends InfoTransform {
case ValDef(_, _, _, _) =>
val tree1 = transform(tree); // important to do before forward reference check
- if (tree.symbol.isLocal && index <= currentLevel.maxindex) {
- if (settings.debug.value) Console.println(currentLevel.refsym);
- unit.error(currentLevel.refpos, "forward reference extends over definition of " + tree.symbol);
+ val ValDef(_, _, _, rhs) = tree1
+ if (tree.symbol.hasFlag(LAZY)) {
+ assert(tree.symbol.isTerm, tree.symbol)
+ val vsym = tree.symbol
+ val lazyDefSym = vsym.lazyAccessor
+ assert(lazyDefSym != NoSymbol, vsym)
+ val lazyDef = atPos(tree.pos)(
+ DefDef(lazyDefSym, vparamss =>
+ if (tree.symbol.owner.isTrait) rhs // for traits, this is further tranformed in mixins
+ else Block(List(
+ Assign(gen.mkAttributedRef(vsym), rhs)),
+ gen.mkAttributedRef(vsym))))
+ log("Made lazy def: " + lazyDef)
+ typed(ValDef(vsym, EmptyTree)) :: typed(lazyDef) :: Nil
+ } else {
+ if (tree.symbol.isLocal && index <= currentLevel.maxindex && !tree.symbol.hasFlag(LAZY)) {
+ if (settings.debug.value) Console.println(currentLevel.refsym);
+ unit.error(currentLevel.refpos, "forward reference extends over definition of " + tree.symbol);
+ }
+ List(tree1)
}
- List(tree1)
case Import(_, _) =>
List()