@@ -410,7 +410,6 @@ class Objects(using Context @constructorOnly):
410410 new LocalEnv (argMap, meth, outer)(valsMap = mutable.Map .empty, varsMap = mutable.Map .empty)
411411
412412 def ofDefDef (ddef : DefDef , args : List [Value ], outer : Data )(using Context ): Data =
413- // println(ddef.show)
414413 val params = ddef.termParamss.flatten.map(_.symbol)
415414 assert(args.size == params.size, " arguments = " + args.size + " , params = " + params.size)
416415 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):
439438 throw new RuntimeException (" Incorrect local environment for initializing " + x.show)
440439
441440 /**
442- * Resolve the environment owned by the given method .
441+ * Resolve the environment by searching for a given symbol .
443442 *
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.
446444 *
447445 * Due to widening, the corresponding environment might not exist. As a result reading the local
448446 * variable will return `Cold` and it's forbidden to write to the local variable.
449447 *
450- * @param meth The method which owns the environment
448+ * @param target The symbol to search for.
451449 * @param thisV The value for `this` of the enclosing class where the local variable is referenced.
452450 * @param env The local environment where the local variable is referenced.
453451 *
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.
455453 */
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) {
457455 env match
458456 case localEnv : LocalEnv =>
459457 if localEnv.getVal(target).isDefined then Some (thisV -> localEnv)
460458 else if localEnv.getVar(target).isDefined then Some (thisV -> localEnv)
461- else _resolveEnvByValue (target, thisV, localEnv.outer)
459+ else resolveEnvByValue (target, thisV, localEnv.outer)
462460 case NoEnv =>
463461 thisV match
464462 case ref : OfClass =>
465463 ref.outer match
466464 case outer : ThisValue =>
467- _resolveEnvByValue (target, outer, ref.env)
465+ resolveEnvByValue (target, outer, ref.env)
468466 case _ =>
469467 // TODO: properly handle the case where ref.outer is ValueSet
470468 None
471469 case _ =>
472470 None
473471 }
474472
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) {
483489 env match
484490 case localEnv : LocalEnv =>
485491 if localEnv.meth == meth then Some (thisV -> env)
@@ -752,7 +758,6 @@ class Objects(using Context @constructorOnly):
752758 if meth.owner.isClass then
753759 (ref, Env .NoEnv )
754760 else
755- // println("1: " + meth.show + " env : " + summon[Env.Data].show)
756761 Env .resolveEnvByOwner(meth.owner.enclosingMethod, ref, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
757762
758763 val env2 = Env .ofDefDef(ddef, args.map(_.value), outerEnv)
@@ -991,7 +996,6 @@ class Objects(using Context @constructorOnly):
991996 (thisV.widenRefOrCold(1 ), Env .NoEnv )
992997 else
993998 // klass.enclosingMethod returns its primary constructor
994- // println("callsite 2: " + klass.show + " env : " + summon[Env.Data].show)
995999 Env .resolveEnvByOwner(klass.owner.enclosingMethod, thisV, summon[Env .Data ]).getOrElse(Cold -> Env .NoEnv )
9961000
9971001 val instance = OfClass (klass, outerWidened, ctor, args.map(_.value), envWidened)
@@ -1022,7 +1026,8 @@ class Objects(using Context @constructorOnly):
10221026 */
10231027 def readLocal (thisV : ThisValue , sym : Symbol ): Contextual [Value ] = log(" reading local " + sym.show, printer, (_ : Value ).show) {
10241028 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.
10261031 Env .resolveEnvByValue(sym, thisV, summon[Env .Data ]) match
10271032 case Some (thisV -> env) =>
10281033 if sym.is(Flags .Mutable ) then
@@ -1078,7 +1083,8 @@ class Objects(using Context @constructorOnly):
10781083 */
10791084 def writeLocal (thisV : ThisValue , sym : Symbol , value : Value ): Contextual [Value ] = log(" write local " + sym.show + " with " + value.show, printer, (_ : Value ).show) {
10801085 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.
10821088 Env .resolveEnvByValue(sym, thisV, summon[Env .Data ]) match
10831089 case Some (thisV -> env) =>
10841090 given Env .Data = env
@@ -1215,7 +1221,6 @@ class Objects(using Context @constructorOnly):
12151221 withTrace(trace2) { call(receiver, ref.symbol, args, receiver = qual.tpe, superType = NoType ) }
12161222
12171223 case id : Ident =>
1218- // println("ID : " + id.show)
12191224 id.tpe match
12201225 case TermRef (NoPrefix , _) =>
12211226 // resolve this for the local method
@@ -1285,7 +1290,6 @@ class Objects(using Context @constructorOnly):
12851290 Fun (ddef, thisV, klass, summon[Env .Data ])
12861291
12871292 case Block (stats, expr) =>
1288- // println("BLOCK DATA : " + expr.show)
12891293 evalExprs(stats, thisV, klass)
12901294 eval(expr, thisV, klass)
12911295
0 commit comments