@@ -488,7 +488,17 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
488
488
}
489
489
490
490
def primaryConstrParams = _primaryConstrParams
491
- def usesSpecializedField = intoConstructor.usesSpecializedField
491
+
492
+ /*
493
+ * `usesSpecializedField` makes a difference in deciding whether constructor-statements
494
+ * should be guarded in a `guardSpecializedFieldInit` class, ie in a class that's the generic super-class of
495
+ * one or more specialized sub-classes.
496
+ *
497
+ * Given that `usesSpecializedField` isn't read for any other purpose than the one described above,
498
+ * we skip setting `usesSpecializedField` in case the current class isn't `guardSpecializedFieldInit` to start with.
499
+ * That way, trips to a map in `specializeTypes` are saved.
500
+ */
501
+ var usesSpecializedField : Boolean = false
492
502
493
503
// The constructor parameter corresponding to an accessor
494
504
def parameter (acc : Symbol ): Symbol = parameterNamed(acc.unexp
8000
andedName.getterName)
@@ -505,27 +515,16 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
505
515
}
506
516
507
517
// A transformer for expressions that go into the constructor
508
- object intoConstructor extends Transformer {
509
- /*
510
- * `usesSpecializedField` makes a difference in deciding whether constructor-statements
511
- * should be guarded in a `guardSpecializedFieldInit` class, ie in a class that's the generic super-class of
512
- * one or more specialized sub-classes.
513
- *
514
- * Given that `usesSpecializedField` isn't read for any other purpose than the one described above,
515
- * we skip setting `usesSpecializedField` in case the current class isn't `guardSpecializedFieldInit` to start with.
516
- * That way, trips to a map in `specializeTypes` are saved.
517
- */
518
- var usesSpecializedField : Boolean = false
519
-
518
+ class IntoConstructor (omittable : Set [Symbol ]) extends Transformer {
520
519
private def isParamRef (sym : Symbol ) = sym.isParamAccessor && sym.owner == clazz
521
520
522
521
// Terminology: a stationary location is never written after being read.
523
- private def isStationaryParamRef (sym : Symbol ) = (
522
+ private def isStationaryParamRef (sym : Symbol ) = {
524
523
isParamRef(sym) &&
525
524
! (sym.isGetter && sym.accessed.isVariable) &&
526
525
! sym.isSetter &&
527
- ! sym.isVariable
528
- )
526
+ ( ! sym.isVariable || omittable(sym))
527
+ }
529
528
530
529
/*
531
530
* whether `sym` denotes a param-accessor (ie in a class a PARAMACCESSOR field, or in a trait a method with same flag)
@@ -612,8 +611,8 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
612
611
613
612
val defs = defBuf.toList
614
613
val auxConstructors = auxConstructorBuf.toList
615
- val constructorPrefix = constrPrefixBuf.toList
616
- val constructorStats = constrStatBuf.toList
614
+ var constructorPrefix = constrPrefixBuf.toList
615
+ var constructorStats = constrStatBuf.toList
617
616
val classInitStats = classInitStatBuf.toList
618
617
619
618
private def triage () = {
@@ -651,8 +650,7 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
651
650
def moveEffectToCtor (mods : Modifiers , rhs : Tree , assignSym : Symbol ): Unit = {
652
651
val initializingRhs =
653
652
if ((assignSym eq NoSymbol ) || statSym.isLazy) EmptyTree // not memoized, or effect delayed (for lazy val)
654
- else if (! mods.hasStaticFlag) intoConstructor(statSym, primaryConstrSym)(rhs)
655
- else rhs
653
+ else rhs.updateAttachment(SymAtt (statSym))
656
654
657
655
if (initializingRhs ne EmptyTree ) {
658
656
val initPhase =
@@ -704,10 +702,24 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
704
702
705
703
// all other statements go into the constructor
706
704
case _ =>
707
- constrStatBuf += intoConstructor( impl.symbol, primaryConstrSym)(stat )
705
+ constrStatBuf += stat.updateAttachment( SymAtt ( impl.symbol) )
708
706
}
709
707
}
710
708
}
709
+
710
+ case class SymAtt (sym : Symbol )
711
+
712
+
8000
def rewriteFieldAccesses (omittable : Set [Symbol ]): Unit = {
713
+ val trans = new IntoConstructor (omittable)
714
+ val into = (tree : Tree ) => tree.getAndRemoveAttachment[SymAtt ] match {
715
+ case Some (statSym) =>
716
+ trans(statSym.sym, primaryConstr.symbol)(tree)
717
+ case _ =>
718
+ tree
719
+ }
720
+ constructorPrefix = constructorPrefix.mapConserve(into)
721
+ constructorStats = constructorStats.mapConserve(into)
722
+ }
711
723
}
712
724
713
725
def transformed = {
@@ -718,6 +730,8 @@ abstract class Constructors extends Statics with Transform with TypingTransforme
718
730
if (isDelayedInitSubclass) Set .empty
719
731
else computeOmittableAccessors(clazz, defs, auxConstructors, constructorStats)
720
732
733
+ triage.rewriteFieldAccesses(omittableAccessor)
734
+
721
735
// TODO: this should omit fields for non-memoized (constant-typed, unit-typed vals need no storage --
722
736
// all the action is in the getter)
723
737
def omittableSym (sym : Symbol ) = omittableAccessor(sym)
0 commit comments