@@ -36,14 +36,17 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
36
36
import Interpreter ._
37
37
import tpd ._
38
38
39
+ /** Local variable environment */
39
40
type Env = Map [Symbol , Object ]
41
+ def emptyEnv : Env = Map .empty
42
+ inline def env (using e : Env ): e.type = e
40
43
41
44
/** Returns the result of interpreting the code in the tree.
42
45
* Return Some of the result or None if the result type is not consistent with the expected type.
43
46
* Throws a StopInterpretation if the tree could not be interpreted or a runtime exception ocurred.
44
47
*/
45
- final def interpret [T ](tree : Tree )(implicit ct : ClassTag [T ]): Option [T ] =
46
- interpretTree(tree)(Map .empty ) match {
48
+ final def interpret [T ](tree : Tree )(using ct : ClassTag [T ]): Option [T ] =
49
+ interpretTree(tree)(using emptyEnv ) match {
47
50
case obj : T => Some (obj)
48
51
case obj =>
49
52
// TODO upgrade to a full type tag check or something similar
@@ -54,7 +57,7 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
54
57
/** Returns the result of interpreting the code in the tree.
55
58
* Throws a StopInterpretation if the tree could not be interpreted or a runtime exception ocurred.
56
59
*/
57
- protected def interpretTree (tree : Tree )(implicit env : Env ): Object = tree match {
60
+ protected def interpretTree (tree : Tree )(using Env ): Object = tree match {
58
61
case Literal (Constant (value)) =>
59
62
interpretLiteral(value)
60
63
@@ -70,8 +73,7 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
70
73
else if (fn.symbol.is(Module ))
71
74
interpretModuleAccess(fn.symbol)
72
75
else if (fn.symbol.is(Method ) && fn.symbol.isStatic) {
73
- val staticMethodCall = interpretedStaticMethodCall(fn.symbol.owner, fn.symbol)
74
- staticMethodCall(interpretArgs(args, fn.symbol.info))
76
+ interpretedStaticMethodCall(fn.symbol.owner, fn.symbol, interpretArgs(args, fn.symbol.info))
75
77
}
76
78
else if fn.symbol.isStatic then
77
79
assert(args.isEmpty)
@@ -80,8 +82,7 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
80
82
if (fn.name == nme.asInstanceOfPM)
81
83
interpretModuleAccess(fn.qualifier.symbol)
82
84
else {
83
- val staticMethodCall = interpretedStaticMethodCall(fn.qualifier.symbol.moduleClass, fn.symbol)
84
- staticMethodCall(interpretArgs(args, fn.symbol.info))
85
+ interpretedStaticMethodCall(fn.qualifier.symbol.moduleClass, fn.symbol, interpretArgs(args, fn.symbol.info))
85
86
}
86
87
else if (env.contains(fn.symbol))
87
88
env(fn.symbol)
@@ -136,26 +137,26 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
136
137
Nil
137
138
}
138
139
139
- private def interpretBlock (stats : List [Tree ], expr : Tree )(implicit env : Env ) = {
140
+ private def interpretBlock (stats : List [Tree ], expr : Tree )(using Env ) = {
140
141
var unexpected : Option [Object ] = None
141
- val newEnv = stats.foldLeft(env)((accEnv, stat) => stat match {
142
+ val newEnv = stats.foldLeft(env)((accEnv, stat) => stat match
142
143
case stat : ValDef =>
143
- accEnv.updated(stat.symbol, interpretTree(stat.rhs)(accEnv))
144
+ accEnv.updated(stat.symbol, interpretTree(stat.rhs)(using accEnv))
144
145
case stat =>
145
146
if (unexpected.isEmpty)
146
147
unexpected = Some (unexpectedTree(stat))
147
148
accEnv
148
- } )
149
- unexpected.getOrElse(interpretTree(expr)(newEnv))
149
+ )
150
+ unexpected.getOrElse(interpretTree(expr)(using newEnv))
150
151
}
151
152
152
- private def interpretLiteral (value : Any )( implicit env : Env ) : Object =
153
+ private def interpretLiteral (value : Any ): Object =
153
154
value.asInstanceOf [Object ]
154
155
155
- private def interpretVarargs (args : List [Object ])( implicit env : Env ) : Object =
156
+ private def interpretVarargs (args : List [Object ]): Object =
156
157
args.toSeq
157
158
158
- private def interpretedStaticMethodCall (moduleClass : Symbol , fn : Symbol )( implicit env : Env ) : List [Object ] => Object = {
159
+ private def interpretedStaticMethodCall (moduleClass : Symbol , fn : Symbol , args : List [Object ]) : Object = {
159
160
val (inst, clazz) =
160
161
try
161
162
if (moduleClass.name.startsWith(str.REPL_SESSION_LINE ))
@@ -172,25 +173,25 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
172
173
173
174
val name = fn.name.asTermName
174
175
val method = getMethod(clazz, name, paramsSig(fn))
175
- ( args : List [ Object ]) => stopIfRuntimeException(method.invoke(inst, args : _* ), method)
176
+ stopIfRuntimeException(method.invoke(inst, args : _* ), method)
176
177
}
177
178
178
- private def interpretedStaticFieldAccess (sym : Symbol )( implicit env : Env ) : Object = {
179
+ private def interpretedStaticFieldAccess (sym : Symbol ): Object = {
179
180
val clazz = loadClass(sym.owner.fullName.toString)
180
181
val field = clazz.getField(sym.name.toString)
181
182
field.get(null )
182
183
}
183
184
184
- private def interpretModuleAccess (fn : Symbol )( implicit env : Env ) : Object =
185
+ private def interpretModuleAccess (fn : Symbol ): Object =
185
186
loadModule(fn.moduleClass)
186
187
187
- private def interpretNew (fn : Symbol , args : => List [Object ])( implicit env : Env ) : Object = {
188
+ private def interpretNew (fn : Symbol , args : => List [Object ]): Object = {
188
189
val clazz = loadClass(fn.owner.fullName.toString)
189
190
val constr = clazz.getConstructor(paramsSig(fn): _* )
190
191
constr.newInstance(args : _* ).asInstanceOf [Object ]
191
192
}
192
193
193
- private def unexpectedTree (tree : Tree )( implicit env : Env ) : Object =
194
+ private def unexpectedTree (tree : Tree ): Object =
194
195
throw new StopInterpretation (em " Unexpected tree could not be interpreted: ${tree.toString}" , tree.srcPos)
195
196
196
197
private def loadModule (sym : Symbol ): Object =
@@ -210,7 +211,7 @@ abstract class Interpreter(pos: SrcPos, classLoader: ClassLoader)(using Context)
210
211
clazz.getConstructor().newInstance().asInstanceOf [Object ]
211
212
}
212
213
213
- private def loadReplLineClass (moduleClass : Symbol )( implicit env : Env ) : Class [? ] = {
214
+ private def loadReplLineClass (moduleClass : Symbol ): Class [? ] = {
214
215
val lineClassloader = new AbstractFileClassLoader (ctx.settings.outputDir.value, classLoader)
215
216
lineClassloader.loadClass(moduleClass.name.firstPart.toString)
216
217
}
0 commit comments