@@ -95,12 +95,15 @@ object Objects:
95
95
96
96
sealed abstract class Value :
97
97
def show (using Context ): String
98
+ def widen (height : Int )(using Context ): Value =
99
+ if height == 0 then Cold else this
98
100
99
101
/** ValueElement are elements that can be contained in a RefSet */
100
102
sealed abstract class ValueElement extends Value
101
103
102
104
sealed trait ThisValue extends Value :
103
- def widenThisV (height : Int )(using Context ) : ThisValue = this
105
+ override def widen (height : Int )(using Context ) : ThisValue =
106
+ if height == 0 then Cold else this
104
107
105
108
/**
106
109
* A reference caches the values for outers and immutable fields.
@@ -166,11 +169,14 @@ object Objects:
166
169
def widenedCopy (outer : Value , args : List [Value ], env : Env .Data ): OfClass =
167
170
new OfClass (klass, outer, ctor, args, env)(this .valsMap, this .varsMap, this .outersMap)
168
171
169
- override def widenThisV (height : Int )(using Context ): ThisValue =
170
- val outer2 = outer.widen(height - 1 )
171
- val args2 = args.map(_.widen(height - 1 ))
172
- val env2 = env.widen(height - 1 )
173
- widenedCopy(outer2, args2, env2)
172
+ override def widen (height : Int )(using Context ): ThisValue =
173
+ if height == 0 then
174
+ Cold
175
+ else
176
+ val outer2 = outer.widen(height - 1 )
177
+ val args2 = args.map(_.widen(height - 1 ))
178
+ val env2 = env.widen(height - 1 )
179
+ widenedCopy(outer2, args2, env2)
174
180
175
181
def show (using Context ) =
176
182
val valFields = vals.map(_.show + " -> " + _.show)
@@ -211,6 +217,9 @@ object Objects:
211
217
case class Fun (code : Tree , thisV : ThisValue , klass : ClassSymbol , env : Env .Data ) extends ValueElement :
212
218
def show (using Context ) = " Fun(" + code.show + " , " + thisV.show + " , " + klass.show + " )"
213
219
220
+ override def widen (height : Int )(using Context ): Value =
221
+ Fun (code, thisV.widen(height), klass, env.widen(height))
222
+
214
223
/**
215
224
* Represents a set of values
216
225
*
@@ -219,11 +228,17 @@ object Objects:
219
228
case class RefSet (refs : ListSet [ValueElement ]) extends Value :
220
229
def show (using Context ) = refs.map(_.show).mkString(" [" , " ," , " ]" )
221
230
231
+ override def widen (height : Int )(using Context ): Value =
232
+ if height == 0 then
233
+ Cold
234
+ else
235
+ refs.map(ref => ref.widen(height)).join
236
+
222
237
/** A cold alias which should not be used during initialization.
223
238
*
224
239
* Cold is not ValueElement since RefSet containing Cold is equivalent to Cold
225
240
*/
226
- case object Cold extends Value with ThisValue :
241
+ case object Cold extends ThisValue :
227
242
def show (using Context ) = " Cold"
228
243
229
244
val Bottom = RefSet (ListSet .empty)
@@ -435,7 +450,7 @@ object Objects:
435
450
ref.outer match
436
451
case outer : ThisValue =>
437
452
resolveEnv(meth, outer, ref.env)
438
- case _ => // This is the case for top-level classes and local classes
453
+ case _ => // This is the case for top-level
439
454
None
440
455
case _ =>
441
456
None
@@ -576,7 +591,7 @@ object Objects:
576
591
case (RefSet (refs), b : ValueElement ) => RefSet (refs + b)
577
592
case (a : ValueElement , b : ValueElement ) => RefSet (ListSet (a, b))
578
593
579
- def widen (height : Int )(using Context ): Value =
594
+ /* def widen(height: Int)(using Context): Value =
580
595
if height == 0 then Cold
581
596
else
582
597
a match
@@ -591,7 +606,7 @@ object Objects:
591
606
case ref : Ref =>
592
607
ref.widenThisV(height)
593
608
594
- case _ => a
609
+ case _ => a */
595
610
596
611
extension (values : Iterable [Value ])
597
612
def join : Value = if values.isEmpty then Bottom else values.reduce { (v1, v2) => v1.join(v2) }
@@ -859,11 +874,15 @@ object Objects:
859
874
else
860
875
// Widen the outer to finitize the domain. Arguments already widened in `evalArgs`.
861
876
val (outerWidened, envWidened) =
862
- if klass.owner.isClass then // For top-level classes, klass.owner is the enclosing package, which is a class
863
- (outer.widen(1 ), Env .NoEnv )
864
- else
865
- // klass.enclosingMethod returns its primary constructor
866
- Env .resolveEnv(klass.owner.enclosingMethod, outer.asInstanceOf [ThisValue ], summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
877
+ value match
878
+ case _ : Bottom .type => // For top-level classes
879
+ (Bottom , Env .NoEnv )
880
+ case thisV : ThisValue =>
881
+ if klass.owner.isClass then // For top-level classes, klass.owner is the enclosing package, which is a class
882
+ (thisV.widen(1 ), Env .NoEnv )
883
+ else
884
+ // klass.enclosingMethod returns its primary constructor
885
+ Env .resolveEnv(klass.owner.enclosingMethod, thisV, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
867
886
868
887
val instance = OfClass (klass, outerWidened, ctor, args.map(_.value), envWidened)
869
888
callConstructor(instance, ctor, args)
0 commit comments