@@ -23,12 +23,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
23
23
new CleanUpTransformer (unit)
24
24
25
25
class CleanUpTransformer (unit : CompilationUnit ) extends Transformer {
26
- private val newStaticMembers = mutable.Buffer .empty[Tree ]
27
- private val newStaticInits = mutable.Buffer .empty[Tree ]
28
- private val symbolsStoredAsStatic = mutable.Map .empty[String , Symbol ]
29
- private val staticBodies = mutable.Map .empty[(Symbol , Symbol ), Tree ]
30
- private val syntheticClasses = mutable.Map .empty[Symbol , mutable.Set [Tree ]] // package and trees
31
- private val classNames = mutable.Map .empty[Symbol , Set [Name ]]
26
+ private val newStaticMembers = mutable.Buffer .empty[Tree ]
27
+ private val newStaticInits = mutable.Buffer .empty[Tree ]
28
+ private val symbolsStoredAsStatic = mutable.Map .empty[String , Symbol ]
32
29
private def clearStatics () {
33
30
newStaticMembers.clear()
34
31
newStaticInits.clear()
@@ -48,9 +45,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
48
45
result
49
46
}
50
47
private def transformTemplate (tree : Tree ) = {
51
- val t @ Template (parents, self, body) = tree
48
+ val Template (parents, self, body) = tree
52
49
clearStatics()
53
-
54
50
val newBody = transformTrees(body)
55
51
val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody)
56
52
try addStaticInits(templ) // postprocess to include static ctors
@@ -550,80 +546,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
550
546
else tree
551
547
}
552
548
553
- case DefDef (mods, name, tps, vps, tp, rhs) if tree.symbol.hasStaticAnnotation =>
554
- reporter.error(tree.pos, " The @static annotation is not allowed on method definitions." )
555
- super .transform(tree)
556
-
557
- case ValDef (mods, name, tpt, rhs) if tree.symbol.hasStaticAnnotation =>
558
- def transformStaticValDef = {
559
- log(" moving @static valdef field: " + name + " , in: " + tree.symbol.owner)
560
- val sym = tree.symbol
561
- val owner = sym.owner
562
-
563
- val staticBeforeLifting = atPhase(currentRun.erasurePhase) { owner.isStatic }
564
- val isPrivate = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PRIVATE ) }
565
- val isProtected = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PROTECTED ) }
566
- val isLazy = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(LAZY ) }
567
- if (! owner.isModuleClass || ! staticBeforeLifting) {
568
- if (! sym.isSynthetic) {
569
- reporter.error(tree.pos, " Only members of top-level objects and their nested objects can be annotated with @static." )
570
- tree.symbol.removeAnnotation(StaticClass )
571
- }
572
- super .transform(tree)
573
- } else if (isPrivate || isProtected) {
574
- reporter.error(tree.pos, " The @static annotation is only allowed on public members." )
575
- tree.symbol.removeAnnotation(StaticClass )
576
- super .transform(tree)
577
- } else if (isLazy) {
578
- reporter.error(tree.pos, " The @static annotation is not allowed on lazy members." )
579
- tree.symbol.removeAnnotation(StaticClass )
580
- super .transform(tree)
581
- } else if (owner.isModuleClass) {
582
- val linkedClass = owner.companionClass match {
583
- case NoSymbol =>
584
- // create the companion class if it does not exist
585
- val enclosing = owner.owner
586
- val compclass = enclosing.newClass(newTypeName(owner.name.toString))
587
- compclass setInfo ClassInfoType (List (ObjectClass .tpe), newScope, compclass)
588
- enclosing.info.decls enter compclass
589
-
590
- val compclstree = ClassDef (compclass, NoMods , ListOfNil , ListOfNil , List (), tree.pos)
591
-
592
- syntheticClasses.getOrElseUpdate(enclosing, mutable.Set ()) += compclstree
593
-
594
- compclass
595
- case comp => comp
596
- }
597
-
598
- // create a static field in the companion class for this @static field
599
- val stfieldSym = linkedClass.newValue(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL ) setInfo sym.tpe
600
- if (sym.isMutable) stfieldSym.setFlag(MUTABLE )
601
- stfieldSym.addAnnotation(StaticClass )
602
-
603
- val names = classNames.getOrElseUpdate(linkedClass, linkedClass.info.decls.collect {
604
- case sym if sym.name.isTermName => sym.name
605
- } toSet)
606
- if (names(stfieldSym.name)) {
607
- reporter.error(
608
- tree.pos,
609
- " @static annotated field " + tree.symbol.name + " has the same name as a member of class " + linkedClass.name
610
- )
611
- } else {
612
- linkedClass.info.decls enter stfieldSym
613
-
614
- val initializerBody = rhs
615
-
616
- // static field was previously initialized in the companion object itself, like this:
617
- // staticBodies((linkedClass, stfieldSym)) = Select(This(owner), sym.getter(owner))
618
- // instead, we move the initializer to the static ctor of the companion class
619
- // we save the entire ValDef/DefDef to extract the rhs later
620
- staticBodies((linkedClass, stfieldSym)) = tree
621
- }
622
- }
623
- super .transform(tree)
624
- }
625
- transformStaticValDef
626
-
627
549
/* MSIL requires that the stack is empty at the end of a try-block.
628
550
* Hence, we here rewrite all try blocks with a result != {Unit, All} such that they
629
551
* store their result in a local variable. The catch blocks are adjusted as well.
@@ -738,11 +660,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
738
660
if (newStaticInits.isEmpty)
739
661
template
740
662
else {
741
- val ctorBody = newStaticInits.toList flatMap {
742
- case Block (stats, expr) => stats :+ expr
743
- case t => List (t)
744
- }
745
-
746
663
val newCtor = findStaticCtor(template) match {
747
664
// in case there already were static ctors - augment existing ones
748
665
// currently, however, static ctors aren't being generated anywhere else
@@ -751,78 +668,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
751
668
deriveDefDef(ctor) {
752
669
case block @ Block (stats, expr) =>
753
670
// need to add inits to existing block
754
- treeCopy.Block (block, ctorBody ::: stats, expr)
671
+ treeCopy.Block (block, newStaticInits.toList ::: stats, expr)
755
672
case term : TermTree =>
756
673
// need to create a new block with inits and the old term
757
- treeCopy.Block (term, ctorBody , term)
674
+ treeCopy.Block (term, newStaticInits.toList , term)
758
675
}
759
676
case _ =>
760
677
// create new static ctor
761
678
val staticCtorSym = currentClass.newStaticConstructor(template.pos)
762
- val rhs = Block (ctorBody , Literal (Constant (())))
679
+ val rhs = Block (newStaticInits.toList , Literal (Constant (())))
763
680
764
681
localTyper.typedPos(template.pos)(DefDef (staticCtorSym, rhs))
765
682
}
766
683
deriveTemplate(template)(newCtor :: _)
767
684
}
768
685
}
769
686
770
- private def addStaticDeclarations (tree : Template , clazz : Symbol ) {
771
- // add static field initializer statements for each static field in clazz
772
- if (! clazz.isModuleClass) for {
773
- staticSym <- clazz.info.decls
774
- if staticSym.hasStaticAnnotation
775
- } staticSym match {
776
- case stfieldSym if (stfieldSym.isValue && ! stfieldSym.isMethod) || stfieldSym.isVariable =>
777
- log(stfieldSym + " is value: " + stfieldSym.isValue)
778
- val valdef = staticBodies((clazz, stfieldSym))
779
- val ValDef (_, _, _, rhs) = valdef
780
- val fixedrhs = rhs.changeOwner((valdef.symbol, clazz.info.decl(nme.CONSTRUCTOR )))
781
-
782
- val stfieldDef = localTyper.typedPos(tree.pos)(VAL (stfieldSym) === EmptyTree )
783
- val flattenedInit = fixedrhs match {
784
- case Block (stats, expr) => Block (stats, REF (stfieldSym) === expr)
785
- case rhs => REF (stfieldSym) === rhs
786
- }
787
- val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit)
788
-
789
- // add field definition to new defs
790
- newStaticMembers append stfieldDef
791
- newStaticInits append stfieldInit
792
- case _ => // ignore @static on other members
793
- }
794
- }
795
-
796
-
797
-
798
- override def transformStats (stats : List [Tree ], exprOwner : Symbol ): List [Tree ] = {
799
- super .transformStats(stats, exprOwner) ++ {
800
- // flush pending synthetic classes created in this owner
801
- val synthclassdefs = syntheticClasses.get(exprOwner).toList.flatten
802
- syntheticClasses -= exprOwner
803
- synthclassdefs map {
804
- cdef => localTyper.typedPos(cdef.pos)(cdef)
805
- }
806
- } map {
807
- case clsdef @ ClassDef (mods, name, tparams, t @ Template (parent, self, body)) =>
808
- // process all classes in the package again to add static initializers
809
- clearStatics()
810
-
811
- addStaticDeclarations(t, clsdef.symbol)
812
-
813
- val templ = deriveTemplate(t)(_ => transformTrees(newStaticMembers.toList) ::: body)
814
- val ntempl =
815
- try addStaticInits(templ)
816
- finally clearStatics()
817
-
818
- val derived = deriveClassDef(clsdef)(_ => ntempl)
819
- classNames.remove(clsdef.symbol)
820
- derived
821
-
822
- case stat => stat
823
- }
824
- }
825
-
826
687
} // CleanUpTransformer
827
688
828
689
}
0 commit comments