@@ -12,7 +12,6 @@ import org.jetbrains.plugins.scala.compiler.data.{Arguments, ComputeStampsArgume
12
12
import org .jetbrains .plugins .scala .server .CompileServerToken
13
13
14
14
import java .io .{IOException , PrintStream }
15
- import java .lang .reflect .Method
16
15
import java .net .URLClassLoader
17
16
import java .nio .charset .StandardCharsets
18
17
import java .nio .file .{Files , Path }
@@ -226,23 +225,69 @@ object Main {
226
225
server.compileDocument(arguments, client)
227
226
}
228
227
229
- private val expressionCompilerCache : Cache [Seq [Path ], ( AnyRef , Method ) ] = new Cache (3 )
228
+ private val classLoaderCache : Cache [Seq [Path ], ClassLoader ] = new Cache (3 )
230
229
231
230
private def evaluateExpressionLogic (args : ExpressionEvaluationArguments , client : Client ): Unit = {
232
- val ExpressionEvaluationArguments (outDir, classpath, scalacOptions, source, line, expression, localVariableNames, packageName) = args
233
-
234
- val (instance, method) = expressionCompilerCache.getOrUpdate(classpath) { () =>
235
- val classLoader = new URLClassLoader (classpath.map(_.toUri.toURL).toArray, this .getClass.getClassLoader)
236
- val bridgeClass = Class .forName(" dotty.tools.dotc.ExpressionCompilerBridge" , true , classLoader)
237
- val instance = bridgeClass.getDeclaredConstructor().newInstance().asInstanceOf [AnyRef ]
238
- val method = bridgeClass.getMethods.find(_.getName == " run" ).get
239
- (instance, method)
231
+ val ExpressionEvaluationArguments (useBuiltInExpressionCompiler, outDir, classpath, scalacOptions, source, line, expression, localVariableNames, packageName) = args
232
+
233
+ val classLoader = classLoaderCache.getOrUpdate(classpath) { () =>
234
+ new URLClassLoader (classpath.map(_.toUri.toURL).toArray, this .getClass.getClassLoader)
240
235
}
241
236
237
+ val bridgeClassName =
238
+ if (useBuiltInExpressionCompiler) " dotty.tools.debug.ExpressionCompilerBridge"
239
+ else " dotty.tools.dotc.ExpressionCompilerBridge"
240
+
241
+ val bridgeClass = Class .forName(bridgeClassName, true , classLoader)
242
+ val bridgeInstance = bridgeClass.getDeclaredConstructor().newInstance().asInstanceOf [AnyRef ]
243
+ val runMethod = bridgeClass.getMethods.find(_.getName == " run" ).get
244
+
242
245
val consumer : java.util.function.Consumer [String ] = client.error(_)
246
+ val expressionClassName = " CompiledExpression"
247
+ val classpathString = classpath.mkString(java.io.File .pathSeparator)
248
+ val scalacOptionsArray = scalacOptions.toArray
249
+ val localVariableNamesJavaSet = localVariableNames.asJava
250
+
251
+ if (useBuiltInExpressionCompiler) {
252
+ val config = assembleExpressionCompilerConfig(classLoader, packageName, expressionClassName, line, expression, localVariableNamesJavaSet, consumer)
253
+ runMethod.invoke(bridgeInstance, outDir, classpathString, scalacOptionsArray, source, config)
254
+ } else {
255
+ runMethod.invoke(bridgeInstance, outDir, expressionClassName, classpathString, scalacOptionsArray, source, line,
256
+ expression, localVariableNamesJavaSet, packageName, consumer, true )
257
+ }
258
+ }
259
+
260
+ private def assembleExpressionCompilerConfig (
261
+ classLoader : ClassLoader ,
262
+ packageName : String ,
263
+ outputClassName : String ,
264
+ breakpointLine : Int ,
265
+ expression : String ,
266
+ localVariables : java.util.Set [String ],
267
+ errorReporter : java.util.function.Consumer [String ]
268
+ ): AnyRef = {
269
+ val configClass = Class .forName(" dotty.tools.debug.ExpressionCompilerConfig" , true , classLoader)
270
+ var configInstance = configClass.getDeclaredConstructor().newInstance().asInstanceOf [AnyRef ]
271
+
272
+ val withPackageNameMethod = configClass.getDeclaredMethod(" withPackageName" , classOf [String ])
273
+ configInstance = withPackageNameMethod.invoke(configInstance, packageName)
274
+
275
+ val withOutputClassNameMethod = configClass.getDeclaredMethod(" withOutputClassName" , classOf [String ])
276
+ configInstance = withOutputClassNameMethod.invoke(configInstance, outputClassName)
277
+
278
+ val withBreakpointLineMethod = configClass.getDeclaredMethod(" withBreakpointLine" , classOf [Int ])
279
+ configInstance = withBreakpointLineMethod.invoke(configInstance, breakpointLine)
280
+
281
+ val withExpressionMethod = configClass.getDeclaredMethod(" withExpression" , classOf [String ])
282
+ configInstance = withExpressionMethod.invoke(configInstance, expression)
283
+
284
+ val withLocalVariablesMethod = configClass.getDeclaredMethod(" withLocalVariables" , classOf [java.util.Set [String ]])
285
+ configInstance = withLocalVariablesMethod.invoke(configInstance, localVariables)
286
+
287
+ val withErrorReporterMethod = configClass.getDeclaredMethod(" withErrorReporter" , classOf [java.util.function.Consumer [String ]])
288
+ configInstance = withErrorReporterMethod.invoke(configInstance, errorReporter)
243
289
244
- method.invoke(instance, outDir, " CompiledExpression" , classpath.mkString(java.io.File .pathSeparator), scalacOptions.toArray, source, line,
245
- expression, localVariableNames.asJava, packageName, consumer, false )
290
+ configInstance
246
291
}
247
292
248
293
private def getMetricsLogic (client : Client ): Unit = {
0 commit comments