diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Constructors.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Constructors.scala | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index b97b1e3527..391bce5abb 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -13,7 +13,7 @@ import symtab.Flags._ /** This phase converts classes with parameters into Java-like classes with * fields, which are assigned to from constructors. */ -abstract class Constructors extends Transform with ast.TreeDSL { +abstract class Constructors extends Statics with Transform with ast.TreeDSL { import global._ import definitions._ @@ -199,7 +199,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { detectUsages walk auxConstructorBuf } } - def mustbeKept(sym: Symbol) = !omittables(sym) + def mustBeKept(sym: Symbol) = !omittables(sym) } // OmittablesHelper @@ -458,7 +458,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { } // GuardianOfCtorStmts private class TemplateTransformer(val unit: CompilationUnit, val impl: Template) - extends Transformer + extends StaticsTransformer with DelayedInitHelper with OmittablesHelper with GuardianOfCtorStmts { @@ -607,7 +607,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { // follow the primary constructor val auxConstructorBuf = new ListBuffer[Tree] - // The list of statements that go into constructor after and including the superclass constructor call + // The list of statements that go into the constructor after and including the superclass constructor call val constrStatBuf = new ListBuffer[Tree] // The list of early initializer statements that go into constructor before the superclass constructor call @@ -616,6 +616,9 @@ abstract class Constructors extends Transform with ast.TreeDSL { // The early initialized field definitions of the class (these are the class members) val presupers = treeInfo.preSuperFields(stats) + // The list of statements that go into the class initializer + val classInitStatBuf = new ListBuffer[Tree] + // generate code to copy pre-initialized fields for (stat <- constrBody.stats) { constrStatBuf += stat @@ -644,7 +647,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { else if (stat.symbol.isConstructor) auxConstructorBuf += stat else defBuf += stat } - case ValDef(_, _, _, rhs) => + case ValDef(mods, _, _, rhs) if !mods.hasStaticFlag => // val defs with constant right-hand sides are eliminated. // for all other val defs, an empty valdef goes into the template and // the initializer goes as an assignment into the constructor @@ -659,6 +662,11 @@ abstract class Constructors extends Transform with ast.TreeDSL { } defBuf += deriveValDef(stat)(_ => EmptyTree) } + case ValDef(_, _, _, rhs) => + // Add static initializer statements to classInitStatBuf and remove the rhs from the val def. + classInitStatBuf += mkAssign(stat.symbol, rhs) + defBuf += deriveValDef(stat)(_ => EmptyTree) + case ClassDef(_, _, _, _) => // classes are treated recursively, and left in the template defBuf += new ConstructorTransformer(unit).transform(stat) @@ -670,7 +678,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { populateOmittables() // Initialize all parameters fields that must be kept. - val paramInits = paramAccessors filter mustbeKept map { acc => + val paramInits = paramAccessors filter mustBeKept map { acc => // Check for conflicting symbol amongst parents: see bug #1960. // It would be better to mangle the constructor parameter name since // it can only be used internally, but I think we need more robust name @@ -710,11 +718,13 @@ abstract class Constructors extends Transform with ast.TreeDSL { defBuf ++= auxConstructorBuf // Unlink all fields that can be dropped from class scope - for (sym <- clazz.info.decls ; if !mustbeKept(sym)) + for (sym <- clazz.info.decls ; if !mustBeKept(sym)) clazz.info.decls unlink sym // Eliminate all field definitions that can be dropped from template - val transformed: Template = deriveTemplate(impl)(_ => defBuf.toList filter (stat => mustbeKept(stat.symbol))) + val templateWithoutOmittables: Template = deriveTemplate(impl)(_ => defBuf.toList filter (stat => mustBeKept(stat.symbol))) + // Add the static initializers + val transformed: Template = addStaticInits(templateWithoutOmittables, classInitStatBuf, localTyper) } // TemplateTransformer |