@@ -46,18 +46,38 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
46
46
* before this phase starts processing same tree */
47
47
override def runsAfter = Set (classOf [Mixin ])
48
48
49
- override def transformDefDef (tree : DefDef )(implicit ctx : Context , info : TransformerInfo ): Tree = {
50
- if (! (tree.symbol is Flags .Lazy ) || tree.symbol.owner.is(Flags .Trait )) tree
51
- else {
52
- val isField = tree.symbol.owner.isClass
53
-
54
- if (isField) {
55
- if (tree.symbol.isVolatile || tree.symbol.is(Flags .Module )) transformMemberDefVolatile(tree)
56
- else transformMemberDefNonVolatile(tree)
57
- }
58
- else transformLocalDef(tree)
49
+ override def transformDefDef (tree : tpd.DefDef )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree =
50
+ transformLazyVal(tree)
51
+
52
+
53
+ override def transformValDef (tree : tpd.ValDef )(implicit ctx : Context , info : TransformerInfo ): tpd.Tree = {
54
+ transformLazyVal(tree)
55
+ }
56
+
57
+ def transformLazyVal (tree : ValOrDefDef )(implicit ctx : Context , info : TransformerInfo ): Tree = {
58
+ val sym = tree.symbol
59
+ if (! (sym is Flags .Lazy ) || sym.owner.is(Flags .Trait ) || (sym.isStatic && sym.is(Flags .Module ))) tree
60
+ else {
61
+
62
+ val isField = sym.owner.isClass
63
+
64
+ if (isField) {
65
+ if (sym.isVolatile ||
66
+ (sym.is(Flags .Module ) && ! sym.is(Flags .Synthetic ))) // companion class is synthesized. Should be threadsafe to
67
+ // make inner lazy vals thread safe
68
+ transformMemberDefVolatile(tree)
69
+ else if (sym.is(Flags .Module )) { // synthetic module
70
+ val holderSymbol = ctx.newSymbol(sym.owner, sym.asTerm.name ++ nme.LAZY_LOCAL ,
71
+ Flags .Synthetic , sym.info.widen.resultType).enteredAfter(this )
72
+ val field = ValDef (holderSymbol, tree.rhs.changeOwnerAfter(sym, holderSymbol, this ))
73
+ val getter = DefDef (sym.asTerm, ref(holderSymbol))
74
+ Thicket (field, getter)
75
+ }
76
+ else transformMemberDefNonVolatile(tree)
59
77
}
78
+ else transformLocalDef(tree)
60
79
}
80
+ }
61
81
62
82
63
83
/** Append offset fields to companion objects
@@ -82,7 +102,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
82
102
* with a LazyHolder from
83
103
* dotty.runtime(eg dotty.runtime.LazyInt)
84
104
*/
85
- def transformLocalDef (x : DefDef )(implicit ctx : Context ) = {
105
+ def transformLocalDef (x : ValOrDefDef )(implicit ctx : Context ) = {
86
106
val valueInitter = x.rhs
87
107
val holderName = ctx.freshName(x.name ++ StdNames .nme.LAZY_LOCAL ).toTermName
88
108
val initName = ctx.freshName(x.name ++ StdNames .nme.LAZY_LOCAL_INIT ).toTermName
@@ -172,7 +192,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
172
192
If (cond, init, exp)
173
193
}
174
194
175
- def transformMemberDefNonVolatile (x : DefDef )(implicit ctx : Context ) = {
195
+ def transformMemberDefNonVolatile (x : ValOrDefDef )(implicit ctx : Context ) = {
176
196
val claz = x.symbol.owner.asClass
177
197
val tpe = x.tpe.widen.resultType.widen
178
198
assert(! (x.mods is Flags .Mutable ))
@@ -293,7 +313,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
293
313
DefDef (methodSymbol, Block (resultDef :: retryDef :: flagDef :: cycle :: Nil , ref(resultSymbol)))
294
314
}
295
315
296
- def transformMemberDefVolatile (x : DefDef )(implicit ctx : Context ) = {
316
+ def transformMemberDefVolatile (x : ValOrDefDef )(implicit ctx : Context ) = {
297
317
assert(! (x.mods is Flags .Mutable ))
298
318
299
319
val tpe = x.tpe.widen.resultType.widen
0 commit comments