@@ -45,6 +45,13 @@ class CollectNullableFields extends MiniPhase {
4545
4646 override def phaseName = CollectNullableFields .name
4747
48+ /** Running after `ElimByName` to see by names as nullable types.
49+ *
50+ * We don't necessary need to run after `Getters`, but the implementation
51+ * could be simplified if we were to run before.
52+ */
53+ override def runsAfter = Set (Getters .name, ElimByName .name)
54+
4855 private [this ] sealed trait FieldInfo
4956 private [this ] case object NotNullable extends FieldInfo
5057 private [this ] case class Nullable (by : Symbol ) extends FieldInfo
@@ -53,21 +60,20 @@ class CollectNullableFields extends MiniPhase {
5360 private [this ] var nullability : IdentityHashMap [Symbol , FieldInfo ] = _
5461
5562 override def prepareForUnit (tree : Tree )(implicit ctx : Context ) = {
56- nullability = new IdentityHashMap
63+ if (nullability == null ) nullability = new IdentityHashMap
5764 ctx
5865 }
5966
6067 private def recordUse (tree : Tree )(implicit ctx : Context ): Tree = {
61- val sym = tree.symbol
68+ def isField (sym : Symbol ) =
69+ sym.isField || sym.isGetter // running after phase Getters
6270
63- def isNullableType (tpe : Type ) =
64- tpe.isInstanceOf [ExprType ] ||
65- tpe.widenDealias.typeSymbol.isNullableClass
71+ val sym = tree.symbol
6672 val isNullablePrivateField =
67- sym. isField &&
73+ isField(sym) &&
6874 sym.is(Private , butNot = Lazy ) &&
6975 ! sym.owner.is(Trait ) &&
70- isNullableType( sym.info)
76+ sym.info.widenDealias.typeSymbol.isNullableClass
7177
7278 if (isNullablePrivateField)
7379 nullability.get(sym) match {
@@ -76,8 +82,8 @@ class CollectNullableFields extends MiniPhase {
7682 case null => // not in the map
7783 val from = ctx.owner
7884 val isNullable =
79- from.is(Lazy ) && from. isField && // used in lazy field initializer
80- from.owner.eq(sym.owner) // lazy val and field in the same class
85+ from.is(Lazy ) && isField(from) && // used in lazy field initializer
86+ from.owner.eq(sym.owner) // lazy val and field defined in the same class
8187 val info = if (isNullable) Nullable (from) else NotNullable
8288 nullability.put(sym, info)
8389 case _ =>
@@ -96,16 +102,16 @@ class CollectNullableFields extends MiniPhase {
96102 recordUse(tree)
97103
98104 /** Map lazy values to the fields they should null after initialization. */
99- def lazyValNullables (implicit ctx : Context ): Map [Symbol , List [Symbol ]] = {
100- val result = new mutable. HashMap [Symbol , mutable.ListBuffer [Symbol ]]
105+ def lazyValNullables (implicit ctx : Context ): IdentityHashMap [Symbol , mutable. ListBuffer [Symbol ]] = {
106+ val result = new IdentityHashMap [Symbol , mutable.ListBuffer [Symbol ]]
101107
102108 nullability.forEach {
103109 case (sym, Nullable (from)) =>
104- val bldr = result.getOrElseUpdate (from, new mutable.ListBuffer )
110+ val bldr = result.computeIfAbsent (from, _ => new mutable.ListBuffer )
105111 bldr += sym
106112 case _ =>
107113 }
108114
109- result.mapValues(_.toList).toMap
115+ result
110116 }
111117}
0 commit comments