@@ -410,7 +410,6 @@ class Objects(using Context @constructorOnly):
410
410
new LocalEnv (argMap, meth, outer)(valsMap = mutable.Map .empty, varsMap = mutable.Map .empty)
411
411
412
412
def ofDefDef (ddef : DefDef , args : List [Value ], outer : Data )(using Context ): Data =
413
- // println(ddef.show)
414
413
val params = ddef.termParamss.flatten.map(_.symbol)
415
414
assert(args.size == params.size, " arguments = " + args.size + " , params = " + params.size)
416
415
assert(ddef.symbol.owner.isClass ^ (outer != NoEnv ), " ddef.owner = " + ddef.symbol.owner.show + " , outer = " + outer + " , " + ddef.source)
@@ -439,47 +438,54 @@ class Objects(using Context @constructorOnly):
439
438
throw new RuntimeException (" Incorrect local environment for initializing " + x.show)
440
439
441
440
/**
442
- * Resolve the environment owned by the given method .
441
+ * Resolve the environment by searching for a given symbol .
443
442
*
444
- * The method could be located in outer scope with intermixed classes between its definition
445
- * site and usage site.
443
+ * Searches for the environment that owns `target`, starting from `env` as the innermost.
446
444
*
447
445
* Due to widening, the corresponding environment might not exist. As a result reading the local
448
446
* variable will return `Cold` and it's forbidden to write to the local variable.
449
447
*
450
- * @param meth The method which owns the environment
448
+ * @param target The symbol to search for.
451
449
* @param thisV The value for `this` of the enclosing class where the local variable is referenced.
452
450
* @param env The local environment where the local variable is referenced.
453
451
*
454
- * @return the environment and value for `this` owned by the given method.
452
+ * @return the environment that owns the `target` and value for `this` owned by the given method.
455
453
*/
456
- def _resolveEnvByValue (target : Symbol , thisV : ThisValue , env : Data )(using Context ): Option [(ThisValue , Data )] = log(" Resolving env for " + target.show + " , this = " + thisV.show + " , env = " + env.show, printer) {
454
+ def resolveEnvByValue (target : Symbol , thisV : ThisValue , env : Data )(using Context ): Option [(ThisValue , Data )] = log(" Resolving env by value for " + target.show + " , this = " + thisV.show + " , env = " + env.show, printer) {
457
455
env match
458
456
case localEnv : LocalEnv =>
459
457
if localEnv.getVal(target).isDefined then Some (thisV -> localEnv)
460
458
else if localEnv.getVar(target).isDefined then Some (thisV -> localEnv)
461
- else _resolveEnvByValue (target, thisV, localEnv.outer)
459
+ else resolveEnvByValue (target, thisV, localEnv.outer)
462
460
case NoEnv =>
463
461
thisV match
464
462
case ref : OfClass =>
465
463
ref.outer match
466
464
case outer : ThisValue =>
467
- _resolveEnvByValue (target, outer, ref.env)
465
+ resolveEnvByValue (target, outer, ref.env)
468
466
case _ =>
469
467
// TODO: properly handle the case where ref.outer is ValueSet
470
468
None
471
469
case _ =>
472
470
None
473
471
}
474
472
475
- def resolveEnvByValue (target : Symbol , thisV : ThisValue , env : Data )(using Context ): Option [(ThisValue , Data )] =
476
- // println("the target: " + target.show + "its owner: " + target.owner.show + " the env: " + env.show)
477
- val e = _resolveEnvByValue(target, thisV, env)
478
- if e.isDefined then println(e.get._2.show)
479
- else println(" NONE" )
480
- e
481
-
482
- def resolveEnvByOwner (meth : Symbol , thisV : ThisValue , env : Data )(using Context ): Option [(ThisValue , Data )] = log(" Resolving env for " + meth.show + " , this = " + thisV.show + " , env = " + env.show, printer) {
473
+ /**
474
+ * Resolve the environment owned by the given method.
475
+ *
476
+ * The method could be located in outer scope with intermixed classes between its definition
477
+ * site and usage site.
478
+ *
479
+ * Due to widening, the corresponding environment might not exist. As a result reading the local
480
+ * variable will return `Cold` and it's forbidden to write to the local variable.
481
+ *
482
+ * @param meth The method which owns the environment
483
+ * @param thisV The value for `this` of the enclosing class where the local variable is referenced.
484
+ * @param env The local environment where the local variable is referenced.
485
+ *
486
+ * @return the environment and value for `this` owned by the given method.
487
+ */
488
+ def resolveEnvByOwner (meth : Symbol , thisV : ThisValue , env : Data )(using Context ): Option [(ThisValue , Data )] = log(" Resolving env by owner for " + meth.show + " , this = " + thisV.show + " , env = " + env.show, printer) {
483
489
env match
484
490
case localEnv : LocalEnv =>
485
491
if localEnv.meth == meth then Some (thisV -> env)
@@ -752,7 +758,6 @@ class Objects(using Context @constructorOnly):
752
758
if meth.owner.isClass then
753
759
(ref, Env .NoEnv )
754
760
else
755
- // println("1: " + meth.show + " env : " + summon[Env.Data].show)
756
761
Env .resolveEnvByOwner(meth.owner.enclosingMethod, ref, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
757
762
758
763
val env2 = Env .ofDefDef(ddef, args.map(_.value), outerEnv)
@@ -991,7 +996,6 @@ class Objects(using Context @constructorOnly):
991
996
(thisV.widenRefOrCold(1 ), Env .NoEnv )
992
997
else
993
998
// klass.enclosingMethod returns its primary constructor
994
- // println("callsite 2: " + klass.show + " env : " + summon[Env.Data].show)
995
999
Env .resolveEnvByOwner(klass.owner.enclosingMethod, thisV, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
996
1000
997
1001
val instance = OfClass (klass, outerWidened, ctor, args.map(_.value), envWidened)
@@ -1022,7 +1026,8 @@ class Objects(using Context @constructorOnly):
1022
1026
*/
1023
1027
def readLocal (thisV : ThisValue , sym : Symbol ): Contextual [Value ] = log(" reading local " + sym.show, printer, (_ : Value ).show) {
1024
1028
def isByNameParam (sym : Symbol ) = sym.is(Flags .Param ) && sym.info.isInstanceOf [ExprType ]
1025
- // println("callsite 3: " + sym.show + " env : " + summon[Env.Data].show)
1029
+ // Can't use enclosingMethod here because values defined in a by-name closure will have the wrong enclosingMethod,
1030
+ // since our phase is before elimByName.
1026
1031
Env .resolveEnvByValue(sym, thisV, summon[Env .Data ]) match
1027
1032
case Some (thisV -> env) =>
1028
1033
if sym.is(Flags .Mutable ) then
@@ -1078,7 +1083,8 @@ class Objects(using Context @constructorOnly):
1078
1083
*/
1079
1084
def writeLocal (thisV : ThisValue , sym : Symbol , value : Value ): Contextual [Value ] = log(" write local " + sym.show + " with " + value.show, printer, (_ : Value ).show) {
1080
1085
assert(sym.is(Flags .Mutable ), " Writing to immutable variable " + sym.show)
1081
- // println("callsite 4: " + sym.show + " env : " + summon[Env.Data].show)
1086
+ // Can't use enclosingMethod here because values defined in a by-name closure will have the wrong enclosingMethod,
1087
+ // since our phase is before elimByName.
1082
1088
Env .resolveEnvByValue(sym, thisV, summon[Env .Data ]) match
1083
1089
case Some (thisV -> env) =>
1084
1090
given Env .Data = env
@@ -1215,7 +1221,6 @@ class Objects(using Context @constructorOnly):
1215
1221
withTrace(trace2) { call(receiver, ref.symbol, args, receiver = qual.tpe, superType = NoType ) }
1216
1222
1217
1223
case id : Ident =>
1218
- // println("ID : " + id.show)
1219
1224
id.tpe match
1220
1225
case TermRef (NoPrefix , _) =>
1221
1226
// resolve this for the local method
@@ -1285,7 +1290,6 @@ class Objects(using Context @constructorOnly):
1285
1290
Fun (ddef, thisV, klass, summon[Env .Data ])
1286
1291
1287
1292
case Block (stats, expr) =>
1288
- // println("BLOCK DATA : " + expr.show)
1289
1293
evalExprs(stats, thisV, klass)
1290
1294
eval(expr, thisV, klass)
1291
1295
0 commit comments