@@ -57,15 +57,15 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
57
57
JavaEncoding .encode(typeSymbol) match
58
58
case s " scala.runtime. ${_}Ref " =>
59
59
val elemField = typeSymbol.info.decl(termName(" elem" )).symbol
60
- gen.setField(
60
+ gen.setField(tree)(
61
61
gen.getLocalValue(variableName),
62
62
elemField.asTerm,
63
63
value
64
64
)
65
65
case _ => gen.setLocalValue(variableName, value)
66
66
case ReflectEvalStrategy .ClassCapture (variable, cls, isByName) =>
67
67
val rawCapture = gen
68
- .getClassCapture(qualifier, variable.name, cls)
68
+ .getClassCapture(tree)( qualifier, variable.name, cls)
69
69
.getOrElse {
70
70
report.error(s " No capture found for $variable in $cls" , tree.srcPos)
71
71
ref(defn.Predef_undefined )
@@ -75,15 +75,15 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
75
75
gen.boxIfValueClass(variable, capturedValue)
76
76
case ReflectEvalStrategy .ClassCaptureAssign (variable, cls) =>
77
77
val capture = gen
78
- .getClassCapture(qualifier, variable.name, cls)
78
+ .getClassCapture(tree)( qualifier, variable.name, cls)
79
79
.getOrElse {
80
80
report.error(s " No capture found for $variable in $cls" , tree.srcPos)
81
81
ref(defn.Predef_undefined )
82
82
}
83
83
val value = gen.unboxIfValueClass(variable, args.head)
84
84
val typeSymbol = variable.info.typeSymbol
85
85
val elemField = typeSymbol.info.decl(termName(" elem" )).symbol
86
- gen.setField(capture, elemField.asTerm, value)
86
+ gen.setField(tree)( capture, elemField.asTerm, value)
87
87
case ReflectEvalStrategy .MethodCapture (variable, method, isByName) =>
88
88
val rawCapture = gen
89
89
.getMethodCapture(method, variable.name)
@@ -104,24 +104,25 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
104
104
val value = gen.unboxIfValueClass(variable, args.head)
105
105
val typeSymbol = variable.info.typeSymbol
106
106
val elemField = typeSymbol.info.decl(termName(" elem" )).symbol
107
- gen.setField(capture, elemField.asTerm, value)
107
+ gen.setField(tree)( capture, elemField.asTerm, value)
108
108
case ReflectEvalStrategy .StaticObject (obj) => gen.getStaticObject(obj)
109
109
case ReflectEvalStrategy .Field (field, isByName) =>
110
110
// if the field is lazy, if it is private in a value class or a trait
111
111
// then we must call the getter method
112
112
val fieldValue =
113
113
if field.is(Lazy ) || field.owner.isValueClass || field.owner.is(Trait )
114
- then gen.callMethod(qualifier, field.getter.asTerm, Nil )
114
+ then gen.callMethod(tree)( qualifier, field.getter.asTerm, Nil )
115
115
else
116
- val rawValue = gen.getField(qualifier, field)
116
+ val rawValue = gen.getField(tree)( qualifier, field)
117
117
if isByName then gen.evaluateByName(rawValue) else rawValue
118
118
gen.boxIfValueClass(field, fieldValue)
119
119
case ReflectEvalStrategy .FieldAssign (field) =>
120
120
val arg = gen.unboxIfValueClass(field, args.head)
121
- if field.owner.is(Trait ) then gen.callMethod(qualifier, field.setter.asTerm, List (arg))
122
- else gen.setField(qualifier, field, arg)
123
- case ReflectEvalStrategy .MethodCall (method) => gen.callMethod(qualifier, method, args)
124
- case ReflectEvalStrategy .ConstructorCall (ctr, cls) => gen.callConstructor(qualifier, ctr, args)
121
+ if field.owner.is(Trait ) then
122
+ gen.callMethod(tree)(qualifier, field.setter.asTerm, List (arg))
123
+ else gen.setField(tree)(qualifier, field, arg)
124
+ case ReflectEvalStrategy .MethodCall (method) => gen.callMethod(tree)(qualifier, method, args)
125
+ case ReflectEvalStrategy .ConstructorCall (ctr, cls) => gen.callConstructor(tree)(qualifier, ctr, args)
125
126
case _ => super .transform(tree)
126
127
127
128
private def isReflectEval (symbol : Symbol )(using Context ): Boolean =
@@ -135,7 +136,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
135
136
JavaEncoding .encode(typeSymbol) match
136
137
case s " scala.runtime. ${_}Ref " =>
137
138
val elemField = typeSymbol.info.decl(termName(" elem" )).symbol
138
- getField(tree, elemField.asTerm)
139
+ getField(tree)(tree , elemField.asTerm)
139
140
case _ => tree
140
141
141
142
def boxIfValueClass (term : TermSymbol , tree : Tree ): Tree =
@@ -147,7 +148,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
147
148
def boxValueClass (valueClass : ClassSymbol , tree : Tree ): Tree =
148
149
// qualifier is null: a value class cannot be nested into a class
149
150
val ctor = valueClass.primaryConstructor.asTerm
150
- callConstructor(nullLiteral, ctor, List (tree))
151
+ callConstructor(tree)( nullLiteral, ctor, List (tree))
151
152
152
153
def unboxIfValueClass (term : TermSymbol , tree : Tree ): Tree =
153
154
getErasedValueType(atPhase(Phases .elimErasedValueTypePhase)(term.info)) match
@@ -162,7 +163,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
162
163
private def unboxValueClass (tree : Tree , tpe : ErasedValueType ): Tree =
163
164
val cls = tpe.tycon.typeSymbol.asClass
164
165
val unboxMethod = ValueClasses .valueClassUnbox(cls).asTerm
165
- callMethod(tree, unboxMethod, Nil )
166
+ callMethod(tree)(tree , unboxMethod, Nil )
166
167
167
168
def getThisObject : Tree =
168
169
Apply (Select (expressionThis, termName(" getThisObject" )), List .empty)
@@ -185,7 +186,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
185
186
List (qualifier, Literal (Constant (JavaEncoding .encode(outerCls))))
186
187
)
187
188
188
- def getClassCapture (qualifier : Tree , originalName : Name , cls : ClassSymbol ): Option [Tree ] =
189
+ def getClassCapture (tree : Tree )( qualifier : Tree , originalName : Name , cls : ClassSymbol ): Option [Tree ] =
189
190
cls.info.decls.iterator
190
191
.filter(term => term.isField)
191
192
.find { field =>
@@ -196,7 +197,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
196
197
info.name == originalName
197
198
case _ => false
198
199
}
199
- .map(field => getField(qualifier, field.asTerm))
200
+ .map(field => getField(tree : Tree )( qualifier, field.asTerm))
200
201
201
202
def getMethodCapture (method : TermSymbol , originalName : TermName ): Option [Tree ] =
202
203
val methodType = method.info.asInstanceOf [MethodType ]
@@ -210,32 +211,40 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
210
211
List (Literal (Constant (JavaEncoding .encode(obj))))
211
212
)
212
213
213
- def getField (qualifier : Tree , field : TermSymbol ): Tree =
214
- Apply (
215
- Select (expressionThis, termName(" getField" )),
216
- List (
217
- qualifier,
218
- Literal (Constant (JavaEncoding .encode(field.owner.asType))),
219
- Literal (Constant (JavaEncoding .encode(field.name)))
214
+ def getField (tree : Tree )(qualifier : Tree , field : TermSymbol ): Tree =
215
+ if field.owner.isTerm then
216
+ report.error(s " Cannot access local val ${field.name} in ${field.owner} as field " , tree.srcPos)
217
+ ref(defn.Predef_undefined )
218
+ else
219
+ Apply (
220
+ Select (expressionThis, termName(" getField" )),
221
+ List (
222
+ qualifier,
223
+ Literal (Constant (JavaEncoding .encode(field.owner.asType))),
224
+ Literal (Constant (JavaEncoding .encode(field.name)))
225
+ )
220
226
)
221
- )
222
227
223
- def setField (qualifier : Tree , field : TermSymbol , value : Tree ): Tree =
224
- Apply (
225
- Select (expressionThis, termName(" setField" )),
226
- List (
227
- qualifier,
228
- Literal (Constant (JavaEncoding .encode(field.owner.asType))),
229
- Literal (Constant (JavaEncoding .encode(field.name))),
230
- value
228
+ def setField (tree : Tree )(qualifier : Tree , field : TermSymbol , value : Tree ): Tree =
229
+ if field.owner.isTerm then
230
+ report.error(s " Cannot access local var ${field.name} in ${field.owner} as field " , tree.srcPos)
231
+ ref(defn.Predef_undefined )
232
+ else
233
+ Apply (
234
+ Select (expressionThis, termName(" setField" )),
235
+ List (
236
+ qualifier,
237
+ Literal (Constant (JavaEncoding .encode(field.owner.asType))),
238
+ Literal (Constant (JavaEncoding .encode(field.name))),
239
+ value
240
+ )
231
241
)
232
- )
233
242
234
243
def evaluateByName (function : Tree ): Tree =
235
244
val castFunction = function.cast(defn.Function0 .typeRef.appliedTo(defn.AnyType ))
236
245
Apply (Select (castFunction, termName(" apply" )), List ())
237
246
238
- def callMethod (qualifier : Tree , method : TermSymbol , args : List [Tree ]): Tree =
247
+ def callMethod (tree : Tree )( qualifier : Tree , method : TermSymbol , args : List [Tree ]): Tree =
239
248
val methodType = method.info.asInstanceOf [MethodType ]
240
249
val paramTypesNames = methodType.paramInfos.map(JavaEncoding .encode)
241
250
val paramTypesArray = JavaSeqLiteral (
@@ -247,7 +256,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
247
256
report.error(s " Unknown captured variable $name in $method" , reflectEval.srcPos)
248
257
ref(defn.Predef_undefined )
249
258
val capturedArgs = methodType.paramNames.dropRight(args.size).map {
250
- case name @ DerivedName (underlying, _) => capturedValue(method, underlying).getOrElse(unknownCapture(name))
259
+ case name @ DerivedName (underlying, _) => capturedValue(tree)( method, underlying).getOrElse(unknownCapture(name))
251
260
case name => unknownCapture(name)
252
261
}
253
262
@@ -275,7 +284,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
275
284
case _ => result
276
285
end callMethod
277
286
278
- def callConstructor (qualifier : Tree , ctr : TermSymbol , args : List [Tree ]): Tree =
287
+ def callConstructor (tree : Tree )( qualifier : Tree , ctr : TermSymbol , args : List [Tree ]): Tree =
279
288
val methodType = ctr.info.asInstanceOf [MethodType ]
280
289
val paramTypesNames = methodType.paramInfos.map(JavaEncoding .encode)
281
290
val clsName = JavaEncoding .encode(methodType.resType)
@@ -285,7 +294,7 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
285
294
case outer if outer.toString == " $outer" => qualifier
286
295
case name @ DerivedName (underlying, _) =>
287
296
// if derived then probably a capture
288
- capturedValue(ctr.owner, underlying)
297
+ capturedValue(tree : Tree )( ctr.owner, underlying)
289
298
.getOrElse {
290
299
report.error(s " Unknown captured variable $name in $ctr of ${ctr.owner}" , reflectEval.srcPos)
291
300
ref(defn.Predef_undefined )
@@ -316,22 +325,22 @@ private class ResolveReflectEval(config: ExpressionCompilerConfig, expressionSto
316
325
)
317
326
end callConstructor
318
327
319
- private def capturedValue (sym : Symbol , originalName : TermName ): Option [Tree ] =
328
+ private def capturedValue (tree : Tree )( sym : Symbol , originalName : TermName ): Option [Tree ] =
320
329
val encodedName = JavaEncoding .encode(originalName)
321
- if expressionStore.classOwners.contains(sym) then capturedByClass(sym.asClass, originalName)
330
+ if expressionStore.classOwners.contains(sym) then capturedByClass(tree : Tree )( sym.asClass, originalName)
322
331
else if config.localVariables.contains(encodedName) then Some (getLocalValue(encodedName))
323
332
else
324
333
// if the captured value is not a local variables
325
334
// then it must have been captured by the outer method
326
335
expressionStore.capturingMethod.flatMap(getMethodCapture(_, originalName))
327
336
328
- private def capturedByClass (cls : ClassSymbol , originalName : TermName ): Option [Tree ] =
337
+ private def capturedByClass (tree : Tree )( cls : ClassSymbol , originalName : TermName ): Option [Tree ] =
329
338
val target = expressionStore.classOwners.indexOf(cls)
330
339
val qualifier = expressionStore.classOwners
331
340
.drop(1 )
332
341
.take(target)
333
342
.foldLeft(getThisObject)((q, cls) => getOuter(q, cls))
334
- getClassCapture(qualifier, originalName, cls)
343
+ getClassCapture(tree : Tree )( qualifier, originalName, cls)
335
344
336
345
private object ResolveReflectEval :
337
346
val name = " resolve-reflect-eval"
0 commit comments