@@ -84,23 +84,22 @@ class Objects(using Context @constructorOnly):
84
84
/** Syntax for the data structure abstraction used in abstract domain:
85
85
*
86
86
* ve ::= ObjectRef(class) // global object
87
- * | OfClass(class, ownerObject, ctor) // instance of a class
87
+ * | OfClass(class, ownerObject, ctor, regions) // instance of a class
88
88
* | OfArray(ownerObject, regions) // represents values of native array class in Array.scala
89
- * | Fun(code, env) // value elements that can be contained in ValueSet
89
+ * | Fun(code, LocalEnv) // value elements that can be contained in ValueSet
90
90
* | SafeValue // values on which method calls and field accesses won't cause warnings. Int, String, etc.
91
91
* | UnknownValue // values whose source are unknown at compile time
92
- * | Package // represets a package
93
92
* vs ::= ValueSet(ve) // set of abstract values
94
- * Bottom ::= ValueSet(Empty)
95
- * val ::= ve | vs
93
+ * Bottom ::= ValueSet(Empty) // unreachable code
94
+ * val ::= ve | vs | Package
96
95
* Ref ::= ObjectRef | OfClass | OfArray // values that represent a reference to some (global or instance) object
97
- * ThisValue ::= Ref | vs // possible values for 'this'
96
+ * ThisValue ::= Ref | Set(Ref) // possible values for 'this'
98
97
* LocalEnv(meth, ownerObject) // represents environments for methods or functions
99
98
* Scope ::= Ref | LocalEnv
100
99
* ScopeSet ::= Set(Scope)
101
100
*
102
101
* valsMap = sym -> val // maps variables to their values
103
- * outersMap = classSym -> ScopeSEt // maps the possible outer scopes for a corresponding (parent) class
102
+ * outersMap = sym -> ScopeSet // maps the possible outer scopes for a corresponding (parent) class
104
103
* heap.MutableData = Scope -> (valsMap, outersMap) // heap is mutable
105
104
*
106
105
* regions ::= List(sourcePosition)
@@ -116,42 +115,34 @@ class Objects(using Context @constructorOnly):
116
115
* A reference caches the values for outers and immutable fields.
117
116
*/
118
117
sealed abstract class Scope (using trace : Trace ):
119
- // protected val vals: mutable.Map[Symbol, Value] = valsMap
120
- // protected val vars: mutable.Map[Symbol, Heap.Addr] = varsMap
121
- // protected val outers: mutable.Map[ClassSymbol, Value] = outersMap
122
-
123
118
def isObjectRef : Boolean = this .isInstanceOf [ObjectRef ]
124
119
125
120
def getTrace : Trace = trace
126
121
127
122
def isRef = this .isInstanceOf [Ref ]
128
123
129
- def isEnv = this .isInstanceOf [Env .Data ]
124
+ def isEnv = this .isInstanceOf [Env .LocalEnv ]
125
+
126
+ def asRef : Ref = this .asInstanceOf [Ref ]
130
127
131
- def meth : Symbol
128
+ def asEnv : Env . LocalEnv = this . asInstanceOf [ Env . LocalEnv ]
132
129
133
130
def owner : ClassSymbol
134
131
135
132
def level : Int
136
133
137
134
def show (using Context ): String
138
135
136
+ def outer (using Heap .MutableData ): ScopeSet
137
+
139
138
def valValue (sym : Symbol )(using Heap .MutableData ): Value = Heap .readVal(this , sym)
140
139
141
140
def varValue (sym : Symbol )(using Heap .MutableData ): Value = Heap .readVal(this , sym)
142
141
143
- // def varAddr(sym: Symbol): Heap.Addr = vars(sym)
144
-
145
- def outerValue (sym : Symbol )(using Heap .MutableData ): ScopeSet = Heap .readOuter(this , sym)
146
-
147
- def outer (using Heap .MutableData ): ScopeSet = this .outerValue(meth)
148
-
149
142
def hasVal (sym : Symbol )(using Heap .MutableData ): Boolean = Heap .containsVal(this , sym)
150
143
151
144
def hasVar (sym : Symbol )(using Heap .MutableData ): Boolean = Heap .containsVal(this , sym)
152
145
153
- def hasOuter (cls : ClassSymbol )(using Heap .MutableData ): Boolean = Heap .containsOuter(this , cls)
154
-
155
146
def initVal (field : Symbol , value : Value )(using Context , Heap .MutableData ) = log(" Initialize " + field.show + " = " + value + " for " + this , printer) {
156
147
assert(! field.is(Flags .Mutable ), " Field is mutable: " + field.show)
157
148
Heap .writeJoinVal(this , field, value)
@@ -168,22 +159,25 @@ class Objects(using Context @constructorOnly):
168
159
169
160
sealed abstract class Ref (using Trace ) extends Scope with ValueElement :
170
161
def klass : ClassSymbol
171
- final override def outer (using Heap .MutableData ): ScopeSet = this .outerValue(klass)
172
162
173
- /** A reference to a static object */
174
- case class ObjectRef (
175
- klass : ClassSymbol
176
- )(using context : Context , @ constructorOnly heap : Heap .MutableData , trace : Trace ) extends Ref :
177
- initOuter(klass, Env .NoEnv )
163
+ def outerValue (sym : Symbol )(using Heap .MutableData ): ScopeSet = Heap .readOuter(this , sym)
178
164
179
- def meth = klass.primaryConstructor
165
+ def outer ( using Heap . MutableData ) : ScopeSet = this .outerValue(klass)
180
166
167
+ /** A reference to a static object */
168
+ case class ObjectRef private (klass : ClassSymbol )(using Trace ) extends Ref :
181
169
def owner = klass
182
170
183
171
def level = 1
184
172
185
173
def show (using Context ) = " ObjectRef(" + klass.show + " )"
186
174
175
+ object ObjectRef :
176
+ def apply (klass : ClassSymbol )(using Context , Heap .MutableData , Trace ): ObjectRef =
177
+ val obj = new ObjectRef (klass)
178
+ obj.initOuter(klass, Env .NoEnv )
179
+ obj
180
+
187
181
/**
188
182
* Represents values that are instances of the specified class.
189
183
*
@@ -192,10 +186,8 @@ class Objects(using Context @constructorOnly):
192
186
case class OfClass private (
193
187
klass : ClassSymbol , owner : ClassSymbol , ctor : Symbol , level : Int , regions : Regions .Data )(using Trace )
194
188
extends Ref :
195
- def meth = klass.primaryConstructor
196
-
197
189
def show (using Context ) =
198
- " OfClass(" + klass.show + " , meth = " + meth .show + " , owner = " + owner + " )"
190
+ " OfClass(" + klass.show + " , ctor = " + ctor .show + " , owner = " + owner + " )"
199
191
200
192
object OfClass :
201
193
def apply (
@@ -219,18 +211,25 @@ class Objects(using Context @constructorOnly):
219
211
*
220
212
* @param owner The static object whose initialization creates the array.
221
213
*/
222
- case class OfArray (owner : ClassSymbol , regions : Regions .Data )(using Context , Trace , Heap .MutableData ) extends Ref :
223
- def meth = defn.ArrayConstructor
224
- def klass : ClassSymbol = defn.ArrayClass
214
+ case class OfArray private (owner : ClassSymbol , regions : Regions .Data )(using Trace ) extends Ref :
215
+ val elementSymbol = defn.ArrayConstructor
225
216
226
- val contentSymbol = defn.ArrayConstructor
227
- initVal(meth, Bottom )
217
+ def klass : ClassSymbol = defn.ArrayClass
228
218
229
219
def level = 1
230
- def outerScope = Env . NoEnv
220
+
231
221
def show (using Context ) = " OfArray(owner = " + owner.show + " )"
232
- def content (using Heap .MutableData ) = valValue(meth)
233
- def updateContent (value : Value )(using Heap .MutableData ) = Heap .writeJoinVal(this , meth, value)
222
+
223
+ def readElement (using Heap .MutableData ) = valValue(elementSymbol)
224
+
225
+ def writeElement (value : Value )(using Heap .MutableData ) = Heap .writeJoinVal(this , elementSymbol, value)
226
+
227
+ object OfArray :
228
+ def apply (owner : ClassSymbol , regions : Regions .Data )(using Context , Trace , Heap .MutableData ): OfArray =
229
+ val arr = new OfArray (owner, regions)
230
+ arr.initVal(arr.elementSymbol, Bottom )
231
+ arr.initOuter(arr.klass, Env .NoEnv )
232
+ arr
234
233
235
234
/**
236
235
* Represents a lambda expression
@@ -277,8 +276,6 @@ class Objects(using Context @constructorOnly):
277
276
new SafeValue (typeSymbol.get)
278
277
279
278
/** Represents values unknown to the checker, such as values loaded without source
280
- * UnknownValue is not ValueElement since RefSet containing UnknownValue
281
- * is equivalent to UnknownValue
282
279
*/
283
280
case object UnknownValue extends ValueElement :
284
281
def show (using Context ): String = " UnknownValue"
@@ -291,11 +288,18 @@ class Objects(using Context @constructorOnly):
291
288
case class ValueSet (values : Set [ValueElement ]) extends Value :
292
289
def show (using Context ) = values.map(_.show).mkString(" [" , " ," , " ]" )
293
290
291
+ def isRefSet = values.forall(_.isInstanceOf [Ref ])
292
+
293
+ def toScopeSet : ScopeSet = ScopeSet (values.asInstanceOf [Set [Scope ]])
294
+
294
295
case class ScopeSet (scopes : Set [Scope ]):
295
296
assert(scopes.forall(_.isRef) || scopes.forall(_.isEnv), " All scopes should have the same type!" )
296
297
def level : Int = if scopes.isEmpty then 0 else scopes.head.level
298
+
297
299
def show (using Context ) = scopes.map(_.show).mkString(" [" , " ," , " ]" )
298
300
301
+ def toValueSet : ValueSet = ValueSet (scopes.asInstanceOf [Set [ValueElement ]])
302
+
299
303
case class Package (packageModuleClass : ClassSymbol ) extends Value :
300
304
def show (using Context ): String = " Package(" + packageModuleClass.show + " )"
301
305
@@ -390,20 +394,19 @@ class Objects(using Context @constructorOnly):
390
394
391
395
/** Environment for parameters */
392
396
object Env :
393
- sealed abstract class Data (using Trace ) extends Scope :
394
- def level : Int
395
-
396
397
/** Local environments can be deeply nested, therefore we need `outer`.
397
398
*
398
399
* For local variables in rhs of class field definitions, the `meth` is the primary constructor.
399
400
*/
400
- private case class LocalEnv (meth : Symbol , owner : ClassSymbol , level : Int )(using Trace ) extends Data :
401
+ case class LocalEnv (meth : Symbol , owner : ClassSymbol , level : Int )(using Trace ) extends Scope :
401
402
if (level > 3 )
402
403
report.warning(" [Internal error] Deeply nested environment, level = " + level + " , " + meth.show + " in " + meth.enclosingClass.show, meth.defTree)
403
404
404
405
def show (using Context ) =
405
406
" meth: " + meth.show + " \n " +
406
407
" owner: " + owner.show
408
+
409
+ def outer (using Heap .MutableData ): ScopeSet = Heap .readOuter(this , meth)
407
410
end LocalEnv
408
411
409
412
val NoEnv = ScopeSet (Set .empty)
@@ -413,7 +416,7 @@ class Objects(using Context @constructorOnly):
413
416
* The owner for the local environment for field initializers is the primary constructor of the
414
417
* enclosing class.
415
418
*/
416
- def emptyEnv (meth : Symbol )(using Context , State .Data , Heap .MutableData , Trace ): Data =
419
+ def emptyEnv (meth : Symbol )(using Context , State .Data , Heap .MutableData , Trace ): LocalEnv =
417
420
_of(Map .empty, meth, NoEnv )
418
421
419
422
def valValue (x : Symbol )(using scope : Scope , ctx : Context , trace : Trace , heap : Heap .MutableData ): Value =
@@ -423,20 +426,8 @@ class Objects(using Context @constructorOnly):
423
426
report.warning(" [Internal error] Value not found " + x.show + " \n scope = " + scope.show + " . " + Trace .show, Trace .position)
424
427
Bottom
425
428
426
- def getVal (x : Symbol )(using scope : Scope , ctx : Context , heap : Heap .MutableData ): Option [Value ] =
427
- if scope.hasVal(x) then
428
- Some (scope.valValue(x))
429
- else
430
- None
431
-
432
- def getVar (x : Symbol )(using scope : Scope , ctx : Context , heap : Heap .MutableData ): Option [Value ] =
433
- if scope.hasVar(x) then
434
- Some (scope.varValue(x))
435
- else
436
- None
437
-
438
429
private [Env ] def _of (argMap : Map [Symbol , Value ], meth : Symbol , outerSet : ScopeSet )
439
- (using State .Data , Heap .MutableData , Trace ): Data =
430
+ (using State .Data , Heap .MutableData , Trace ): LocalEnv =
440
431
val env = LocalEnv (meth, State .currentObject, outerSet.level + 1 )
441
432
argMap.foreach(env.initVal(_, _))
442
433
env.initOuter(meth, outerSet)
@@ -454,7 +445,7 @@ class Objects(using Context @constructorOnly):
454
445
if bySymbol then
455
446
scopeSet.scopes.filter(_.hasVal(target))
456
447
else
457
- scopeSet.scopes.filter(_ .meth == target)
448
+ scopeSet.scopes.filter(s => s.isEnv && s.asEnv .meth == target)
458
449
459
450
assert(filter.isEmpty || filter.size == scopeSet.scopes.size, " Either all scopes or no scopes contain " + target)
460
451
if (! filter.isEmpty) then
@@ -475,13 +466,13 @@ class Objects(using Context @constructorOnly):
475
466
476
467
477
468
def ofDefDef (ddef : DefDef , args : List [Value ], outer : ScopeSet )
478
- (using State .Data , Heap .MutableData , Trace ): Data =
469
+ (using State .Data , Heap .MutableData , Trace ): LocalEnv =
479
470
val params = ddef.termParamss.flatten.map(_.symbol)
480
471
assert(args.size == params.size, " arguments = " + args.size + " , params = " + params.size)
481
472
// assert(ddef.symbol.owner.isClass ^ (outer != NoEnv), "ddef.owner = " + ddef.symbol.owner.show + ", outer = " + outer + ", " + ddef.source)
482
473
_of(params.zip(args).toMap, ddef.symbol, outer)
483
474
484
- def ofByName (byNameParam : Symbol , outer : Scope )(using State .Data , Heap .MutableData , Trace ): Data =
475
+ def ofByName (byNameParam : Symbol , outer : Scope )(using State .Data , Heap .MutableData , Trace ): LocalEnv =
485
476
assert(byNameParam.is(Flags .Param ) && byNameParam.info.isInstanceOf [ExprType ]);
486
477
_of(Map .empty, byNameParam, ScopeSet (Set (outer)))
487
478
@@ -491,15 +482,15 @@ class Objects(using Context @constructorOnly):
491
482
case localEnv : LocalEnv =>
492
483
localEnv.initVal(x, value)
493
484
case ref : Ref =>
494
- ref.initVal(x, value) // possible for match statement in class body. Report warning?
485
+ ref.initVal(x, value) // TODO: This is possible for match statement in class body. Report warning?
495
486
496
487
def setLocalVar (x : Symbol , value : Value )(using scope : Scope , ctx : Context , heap : Heap .MutableData ): Unit =
497
488
assert(x.is(Flags .Mutable , butNot = Flags .Param ), " Only local mutable variable allowed" )
498
489
scope match
499
490
case localEnv : LocalEnv =>
500
491
localEnv.initVar(x, value)
501
492
case ref : Ref =>
502
- ref.initVar(x, value) // possible for match statement in class body. Report warning?
493
+ ref.initVar(x, value) // TODO: This is possible for match statement in class body. Report warning?
503
494
504
495
/**
505
496
* Resolve the environment by searching for a given symbol.
@@ -541,20 +532,18 @@ class Objects(using Context @constructorOnly):
541
532
resolveEnvRecur(enclosing, thisV, ScopeSet (Set (scope)), bySymbol = false )
542
533
}
543
534
544
- def withEnv [T ](env : Data )(fn : Data ?=> T ): T = fn(using env)
535
+ def withEnv [T ](env : LocalEnv )(fn : LocalEnv ?=> T ): T = fn(using env)
545
536
end Env
546
537
547
538
/** Abstract heap for mutable fields
548
539
*/
549
540
object Heap :
550
541
private case class ScopeBody (
551
- paramsMap : Map [Symbol , Value ],
552
542
valsMap : Map [Symbol , Value ],
553
543
outersMap : Map [Symbol , ScopeSet ]
554
544
)
555
545
556
546
private def emptyScopeBody (): ScopeBody = ScopeBody (
557
- paramsMap = Map .empty,
558
547
valsMap = Map .empty,
559
548
outersMap = Map .empty
560
549
)
@@ -569,20 +558,6 @@ class Objects(using Context @constructorOnly):
569
558
570
559
/** Store the heap as a mutable field to avoid threading it through the program. */
571
560
class MutableData (private [Heap ] var heap : Data ):
572
- private [Heap ] def writeJoinParam (scope : Scope , param : Symbol , value : Value ): Unit =
573
- heap.get(scope) match
574
- case None =>
575
- heap = heap.updated(scope, Heap .emptyScopeBody())
576
- writeJoinParam(scope, param, value)
577
-
578
- case Some (current) =>
579
- val newParamsMap = current.paramsMap.join(param, value)
580
- heap = heap.updated(scope, new ScopeBody (
581
- paramsMap = newParamsMap,
582
- valsMap = current.valsMap,
583
- outersMap = current.outersMap
584
- ))
585
-
586
561
private [Heap ] def writeJoinVal (scope : Scope , valSymbol : Symbol , value : Value ): Unit =
587
562
heap.get(scope) match
588
563
case None =>
@@ -592,7 +567,6 @@ class Objects(using Context @constructorOnly):
592
567
case Some (current) =>
593
568
val newValsMap = current.valsMap.join(valSymbol, value)
594
569
heap = heap.updated(scope, new ScopeBody (
595
- paramsMap = current.paramsMap,
596
570
valsMap = newValsMap,
597
571
outersMap = current.outersMap
598
572
))
@@ -606,7 +580,6 @@ class Objects(using Context @constructorOnly):
606
580
case Some (current) =>
607
581
val newOutersMap = current.outersMap.join(outerSymbol, outerScope)
608
582
heap = heap.updated(scope, new ScopeBody (
609
- paramsMap = current.paramsMap,
610
583
valsMap = current.valsMap,
611
584
outersMap = newOutersMap
612
585
))
@@ -617,12 +590,6 @@ class Objects(using Context @constructorOnly):
617
590
def contains (scope : Scope )(using mutable : MutableData ): Boolean =
618
591
mutable.heap.contains(scope)
619
592
620
- def containsParam (scope : Scope , param : Symbol )(using mutable : MutableData ): Boolean =
621
- if mutable.heap.contains(scope) then
622
- mutable.heap(scope).paramsMap.contains(param)
623
- else
624
- false
625
-
626
593
def containsVal (scope : Scope , value : Symbol )(using mutable : MutableData ): Boolean =
627
594
if mutable.heap.contains(scope) then
628
595
mutable.heap(scope).valsMap.contains(value)
@@ -635,18 +602,12 @@ class Objects(using Context @constructorOnly):
635
602
else
636
603
false
637
604
638
- def readParam (scope : Scope , param : Symbol )(using mutable : MutableData ): Value =
639
- mutable.heap(scope).paramsMap(param)
640
-
641
605
def readVal (scope : Scope , value : Symbol )(using mutable : MutableData ): Value =
642
606
mutable.heap(scope).valsMap(value)
643
607
644
608
def readOuter (scope : Scope , outer : Symbol )(using mutable : MutableData ): ScopeSet =
645
609
mutable.heap(scope).outersMap(outer)
646
610
647
- def writeJoinParam (scope : Scope , param : Symbol , value : Value )(using mutable : MutableData ): Unit =
648
- mutable.writeJoinParam(scope, param, value)
649
-
650
611
def writeJoinVal (scope : Scope , valSymbol : Symbol , value : Value )(using mutable : MutableData ): Unit =
651
612
mutable.writeJoinVal(scope, valSymbol, value)
652
613
@@ -663,7 +624,7 @@ class Objects(using Context @constructorOnly):
663
624
case class Res (value : Value , heap : Heap .Data )
664
625
665
626
class Data extends Cache [Config , Res ]:
666
- def get (thisV : Value , expr : Tree )(using Heap .MutableData , Env . Data ): Option [Value ] =
627
+ def get (thisV : Value , expr : Tree )(using Heap .MutableData , Scope ): Option [Value ] =
667
628
val config = Config (thisV, summon[Scope ], Heap .getHeapData())
668
629
super .get(config, expr).map(_.value)
669
630
@@ -880,7 +841,7 @@ class Objects(using Context @constructorOnly):
880
841
881
842
if target == defn.Array_apply || target == defn.Array_clone then
882
843
if arr.owner == State .currentObject then
883
- arr.content
844
+ arr.readElement
884
845
else
885
846
errorReadOtherStaticObject(State .currentObject, arr)
886
847
Bottom
@@ -889,7 +850,7 @@ class Objects(using Context @constructorOnly):
889
850
if arr.owner != State .currentObject then
890
851
errorMutateOtherStaticObject(State .currentObject, arr)
891
852
else
892
- arr.updateContent (args.tail.head.value)
853
+ arr.writeElement (args.tail.head.value)
893
854
Bottom
894
855
else
895
856
// Array.length is OK
@@ -910,7 +871,7 @@ class Objects(using Context @constructorOnly):
910
871
if target.isOneOf(Flags .Method ) then
911
872
if target.owner == defn.ArrayModuleClass && target.name == nme.apply then
912
873
val arr = OfArray (State .currentObject, summon[Regions .Data ])
913
- arr.updateContent (args.map(_.value).join)
874
+ arr.writeElement (args.map(_.value).join)
914
875
arr
915
876
else if target.equals(defn.Predef_classOf ) then
916
877
// Predef.classOf is a stub method in tasty and is replaced in backend
@@ -1151,7 +1112,7 @@ class Objects(using Context @constructorOnly):
1151
1112
* @param ctor The symbol of the target constructor.
1152
1113
* @param args The arguments passsed to the constructor.
1153
1114
*/
1154
- def instantiate (outer : Value , klass : ClassSymbol , ctor : Symbol , args : List [ArgInfo ], typeArgs : List [ Type ] ): Contextual [Value ] = log(" instantiating " + klass.show + " , outer = " + outer + " , args = " + args.map(_.value.show), printer, (_ : Value ).show) {
1115
+ def instantiate (outer : Value , klass : ClassSymbol , ctor : Symbol , args : List [ArgInfo ]): Contextual [Value ] = log(" instantiating " + klass.show + " , outer = " + outer + " , args = " + args.map(_.value.show), printer, (_ : Value ).show) {
1155
1116
outer.filterClass(klass.owner) match
1156
1117
case _ : Fun | _ : OfArray | SafeValue (_) =>
1157
1118
report.warning(" [Internal error] unexpected outer in instantiating a class, outer = " + outer.show + " , class = " + klass.show + " , " + Trace .show, Trace .position)
@@ -1175,24 +1136,24 @@ class Objects(using Context @constructorOnly):
1175
1136
outer match
1176
1137
case Package (_) => // For top-level classes
1177
1138
Env .NoEnv
1178
- case thisV : ThisValue =>
1139
+ case outer : ThisValue =>
1179
1140
if klass.owner.is(Flags .Package ) then
1180
1141
report.warning(" [Internal error] top-level class should have `Package` as outer, class = " + klass.show + " , outer = " + outer.show + " , " + Trace .show, Trace .position)
1181
1142
Env .NoEnv
1182
1143
else
1183
1144
val enclosingMethod = klass.owner.enclosingMethod
1184
- val outerCls = thisV .asInstanceOf [Ref ].klass
1145
+ val outerCls = outer .asInstanceOf [Ref ].klass
1185
1146
// When `klass` is directly nested in `outerCls`, `outerCls`.enclosingMethod returns its primary constructor
1186
1147
if enclosingMethod == outerCls.primaryConstructor then
1187
- ScopeSet (Set (thisV .asInstanceOf [Ref ]))
1148
+ ScopeSet (Set (outer .asInstanceOf [Ref ]))
1188
1149
else
1189
- Env .resolveEnvByMethod(klass.owner.enclosingMethod, thisV , summon[Scope ]).getOrElse(UnknownValue -> Env .NoEnv )._2
1150
+ Env .resolveEnvByMethod(klass.owner.enclosingMethod, outer , summon[Scope ]).getOrElse(UnknownValue -> Env .NoEnv )._2
1190
1151
1191
1152
val instance = OfClass (klass, envWidened, ctor)
1192
1153
callConstructor(instance, ctor, args)
1193
1154
1194
1155
case ValueSet (values) =>
1195
- values.map(ref => instantiate(ref, klass, ctor, args, typeArgs )).join
1156
+ values.map(ref => instantiate(ref, klass, ctor, args)).join
1196
1157
}
1197
1158
1198
1159
/** Handle local variable definition, `val x = e` or `var x = e`.
@@ -1296,10 +1257,10 @@ class Objects(using Context @constructorOnly):
1296
1257
}
1297
1258
1298
1259
1299
- def checkClasses (classes : List [ClassSymbol ])(using Context ) =
1260
+ def checkClasses (classes : List [ClassSymbol ])(using Context ): Unit =
1300
1261
given State .Data = new State .Data
1301
1262
given Trace = Trace .empty
1302
- given Heap .MutableData = Heap .empty
1263
+ given Heap .MutableData = Heap .empty // TODO: do garbage collection on the heap
1303
1264
1304
1265
for
1305
1266
classSym <- classes if classSym.isStaticObject
@@ -1360,12 +1321,9 @@ class Objects(using Context @constructorOnly):
1360
1321
val args = evalArgs(argss.flatten, thisV, klass)
1361
1322
1362
1323
val cls = tref.classSymbol.asClass
1363
- val typeArgs = tpt.tpe match
1364
- case AppliedType (_, args) => args
1365
- case _ => Nil
1366
1324
withTrace(trace2) {
1367
1325
val outer = outerValue(tref, thisV, klass)
1368
- instantiate(outer, cls, ctor, args, typeArgs )
1326
+ instantiate(outer, cls, ctor, args)
1369
1327
}
1370
1328
1371
1329
case TypeCast (elem, tpe) =>
@@ -1516,7 +1474,7 @@ class Objects(using Context @constructorOnly):
1516
1474
val module = defn.getWrapVarargsArrayModule.moduleClass.asClass
1517
1475
val args = evalArgs(elems.map(Arg .apply), thisV, klass)
1518
1476
val arr = OfArray (State .currentObject, summon[Regions .Data ])
1519
- arr.updateContent (args.map(_.value).join)
1477
+ arr.writeElement (args.map(_.value).join)
1520
1478
call(ObjectRef (module), meth, List (ArgInfo (arr, summon[Trace ], EmptyTree )), module.typeRef, NoType )
1521
1479
1522
1480
case Inlined (call, bindings, expansion) =>
@@ -1871,8 +1829,8 @@ class Objects(using Context @constructorOnly):
1871
1829
val res = outerValue(tref, thisV, klass)
1872
1830
res match {
1873
1831
case ref : Ref => thisV.initOuter(cls, ScopeSet (Set (ref)))
1874
- case ValueSet (values) if values.forall(_. isInstanceOf [ Ref ]) =>
1875
- thisV.initOuter(cls, ScopeSet (values.map(_. asInstanceOf [ Ref ])) )
1832
+ case vs : ValueSet if vs.isRefSet =>
1833
+ thisV.initOuter(cls, vs.toScopeSet )
1876
1834
case _ : Package =>
1877
1835
thisV.initOuter(cls, Env .NoEnv )
1878
1836
case _ =>
@@ -1993,7 +1951,7 @@ class Objects(using Context @constructorOnly):
1993
1951
val klass = head.asInstanceOf [Ref ].klass
1994
1952
assert(scopeSet.scopes.forall(_.asInstanceOf [Ref ].klass == klass), " Multiple possible outer class?" )
1995
1953
if klass == target then
1996
- ValueSet ( scopeSet.scopes.map(_. asInstanceOf [ Ref ]))
1954
+ scopeSet.toValueSet
1997
1955
else
1998
1956
recur(scopeSet.scopes.map(_.outer).join)
1999
1957
else
@@ -2013,8 +1971,8 @@ class Objects(using Context @constructorOnly):
2013
1971
case Bottom => Bottom
2014
1972
case ref : Ref =>
2015
1973
recur(ScopeSet (Set (ref)))
2016
- case ValueSet (values) if values.forall(_. isInstanceOf [ Ref ]) =>
2017
- recur(ScopeSet (values.map(_. asInstanceOf [ Ref ])) )
1974
+ case vs : ValueSet if vs.isRefSet =>
1975
+ recur(vs.toScopeSet )
2018
1976
case _ =>
2019
1977
report.warning(" [Internal error] unexpected thisV = " + thisV + " , target = " + target.show + " , klass = " + klass.show + Trace .show, Trace .position)
2020
1978
Bottom
@@ -2033,9 +1991,7 @@ class Objects(using Context @constructorOnly):
2033
1991
resolveThis(enclosing, thisV, klass, elideObjectAccess = cls.isStatic)
2034
1992
else
2035
1993
if cls.isAllOf(Flags .JavaInterface ) then Bottom
2036
- else
2037
- val res = evalType(tref.prefix, thisV, klass, elideObjectAccess = cls.isStatic)
2038
- res
1994
+ else evalType(tref.prefix, thisV, klass, elideObjectAccess = cls.isStatic)
2039
1995
2040
1996
def printTraceWhenMultiple (trace : Trace )(using Context ): String =
2041
1997
if trace.toVector.size > 1 then
0 commit comments