From 00fd4ac859c2b375e16f36708da01df285cd3b3c Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 1 Sep 2015 15:30:58 -0700 Subject: Constructors: further clarify which defs are added & when Move conditions and template derivation back to the call sites of `staticConstructor` (formerly `addStaticInits`). --- .../scala/tools/nsc/transform/CleanUp.scala | 4 +- .../scala/tools/nsc/transform/Constructors.scala | 6 ++- .../scala/tools/nsc/transform/Statics.scala | 54 ++++++++-------------- 3 files changed, 27 insertions(+), 37 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala index 7ccbd5303c..1d98b5da31 100644 --- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala +++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala @@ -49,7 +49,9 @@ abstract class CleanUp extends Statics with Transform with ast.TreeDSL { clearStatics() val newBody = transformTrees(body) val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody) - try addStaticInits(templ, newStaticInits.toList, localTyper) // postprocess to include static ctors + try + if (newStaticInits.isEmpty) templ + else deriveTemplate(templ)(body => staticConstructor(body, localTyper, templ.pos)(newStaticInits.toList) :: body) finally clearStatics() } private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix) diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index 24e5c12b12..2ec8f027fb 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -723,7 +723,11 @@ abstract class Constructors extends Statics with Transform with ast.TreeDSL { val prunedStats = (defs filterNot omittableStat) ::: delayedHookDefs ::: constructors // Add the static initializers - addStaticInits(deriveTemplate(impl)(_ => prunedStats), classInitStats, localTyper) + if (classInitStats.isEmpty) deriveTemplate(impl)(_ => prunedStats) + else { + val staticCtor = staticConstructor(prunedStats, localTyper, impl.pos)(classInitStats) + deriveTemplate(impl)(_ => staticCtor :: prunedStats) + } } } // TemplateTransformer } diff --git a/src/compiler/scala/tools/nsc/transform/Statics.scala b/src/compiler/scala/tools/nsc/transform/Statics.scala index 23a9c1b434..6a872b2484 100644 --- a/src/compiler/scala/tools/nsc/transform/Statics.scala +++ b/src/compiler/scala/tools/nsc/transform/Statics.scala @@ -1,49 +1,33 @@ package scala.tools.nsc package transform -import collection.mutable.Buffer - abstract class Statics extends Transform with ast.TreeDSL { import global._ class StaticsTransformer extends Transformer { - - /** finds the static ctor DefDef tree within the template if it exists. */ - def findStaticCtor(template: Template): Option[Tree] = - template.body find { - case defdef @ DefDef(_, nme.CONSTRUCTOR, _, _, _, _) => defdef.symbol.hasStaticFlag - case _ => false - } - /** changes the template for the class so that it contains a static constructor with symbol fields inits, * augments an existing static ctor if one already existed. */ - def addStaticInits(template: Template, newStaticInits: List[Tree], localTyper: analyzer.Typer): Template = { - if (newStaticInits.isEmpty) - template - else { - val newCtor = findStaticCtor(template) match { - // in case there already were static ctors - augment existing ones - // currently, however, static ctors aren't being generated anywhere else - case Some(ctor @ DefDef(_,_,_,_,_,_)) => - // modify existing static ctor - deriveDefDef(ctor) { - case block @ Block(stats, expr) => - // need to add inits to existing block - treeCopy.Block(block, newStaticInits ::: stats, expr) - case term: TermTree => - // need to create a new block with inits and the old term - treeCopy.Block(term, newStaticInits, term) - } - case _ => - // create new static ctor - val staticCtorSym = currentClass.newStaticConstructor(template.pos) - val rhs = Block(newStaticInits, Literal(Constant(()))) + def staticConstructor(body: List[Tree], localTyper: analyzer.Typer, pos: Position)(newStaticInits: List[Tree]): Tree = + body.collectFirst { + // If there already was a static ctor - augment existing one + // currently, however, static ctors aren't being generated anywhere else (!!!) + case ctor@DefDef(_, nme.CONSTRUCTOR, _, _, _, _) if ctor.symbol.hasStaticFlag => + // modify existing static ctor + deriveDefDef(ctor) { + case block@Block(stats, expr) => + // need to add inits to existing block + treeCopy.Block(block, newStaticInits ::: stats, expr) + case term: TermTree => + // need to create a new block with inits and the old term + treeCopy.Block(term, newStaticInits, term) + } + } getOrElse { + // create new static ctor + val staticCtorSym = currentClass.newStaticConstructor(pos) + val rhs = Block(newStaticInits, Literal(Constant(()))) - localTyper.typedPos(template.pos)(DefDef(staticCtorSym, rhs)) - } - deriveTemplate(template)(newCtor :: _) + localTyper.typedPos(pos)(DefDef(staticCtorSym, rhs)) } - } } } -- cgit v1.2.3