Scripting: switch legacy CLI REPL to the new infrastructure
This commit is contained in:
+1
-1
@@ -98,7 +98,7 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
|
||||
is ReplEvalResult.Error ->
|
||||
when {
|
||||
result is ReplEvalResult.Error.Runtime && result.cause != null ->
|
||||
throw ScriptException(result.cause)
|
||||
throw ScriptException((result.cause as? java.lang.Exception) ?: RuntimeException(result.cause))
|
||||
result is ReplEvalResult.Error.CompileTime && result.location != null ->
|
||||
throw ScriptException(result.message, result.location.path, result.location.line, result.location.column)
|
||||
else -> throw ScriptException(result.message)
|
||||
|
||||
@@ -148,7 +148,7 @@ sealed class ReplEvalResult : Serializable {
|
||||
}
|
||||
|
||||
sealed class Error(val message: String) : ReplEvalResult() {
|
||||
class Runtime(message: String, val cause: Exception? = null) : Error(message) {
|
||||
class Runtime(message: String, val cause: Throwable? = null) : Error(message) {
|
||||
companion object { private val serialVersionUID: Long = 1L }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
>>> throw Exception("hi there")
|
||||
java.lang.Exception: hi there
|
||||
at Line_0.<init>(Line_0.kts:1)
|
||||
>>> fun foo() = 2
|
||||
>>> foo()
|
||||
2
|
||||
@@ -7,3 +8,4 @@ java.lang.Exception: hi there
|
||||
>>> bar()
|
||||
java.lang.AssertionError
|
||||
at Line_3.bar(Line_3.kts:1)
|
||||
at Line_4.<init>(Line_4.kts:1)
|
||||
|
||||
@@ -3,3 +3,4 @@
|
||||
java.lang.IllegalStateException: message
|
||||
at Line_0$B.foo(Line_0.kts:1)
|
||||
at Line_0$B.toString(Line_0.kts:1)
|
||||
at Line_1.<init>(Line_1.kts:1)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
java.lang.RuntimeException
|
||||
at Line_0$x$1.invoke(Line_0.kts:1)
|
||||
at Line_0$x$1.invoke(Line_0.kts:1)
|
||||
at Line_0.<init>(Line_0.kts:1)
|
||||
>>> x
|
||||
error: unresolved reference: x
|
||||
x
|
||||
^
|
||||
java.lang.NullPointerException
|
||||
at Line_1.<init>(Line_1.kts:1)
|
||||
|
||||
-3
@@ -2,9 +2,6 @@
|
||||
error: expecting an element
|
||||
)(
|
||||
^
|
||||
error: expecting an expression
|
||||
)(
|
||||
^
|
||||
>>> fun foo() = 98
|
||||
>>> foo()
|
||||
98
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
package org.jetbrains.kotlin.repl
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.script.loadScriptingPlugin
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplInterpreter
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.configuration.ConsoleReplConfiguration
|
||||
@@ -86,8 +89,14 @@ abstract class AbstractReplInterpreterTest : KtUsefulTestCase() {
|
||||
protected fun doTest(path: String) {
|
||||
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK)
|
||||
loadScriptingPlugin(configuration)
|
||||
val projectEnvironment =
|
||||
KotlinCoreEnvironment.ProjectEnvironment(
|
||||
testRootDisposable,
|
||||
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForTests(testRootDisposable, configuration),
|
||||
configuration
|
||||
)
|
||||
val repl = ReplInterpreter(
|
||||
testRootDisposable, configuration,
|
||||
projectEnvironment, configuration,
|
||||
ConsoleReplConfiguration()
|
||||
)
|
||||
|
||||
@@ -100,6 +109,7 @@ abstract class AbstractReplInterpreterTest : KtUsefulTestCase() {
|
||||
|
||||
val actual = when (lineResult) {
|
||||
is ReplEvalResult.ValueResult -> lineResult.value.toString()
|
||||
is ReplEvalResult.Error.CompileTime -> MessageRenderer.WITHOUT_PATHS.render(CompilerMessageSeverity.ERROR, lineResult.message, lineResult.location)
|
||||
is ReplEvalResult.Error -> lineResult.message
|
||||
is ReplEvalResult.Incomplete -> INCOMPLETE_LINE_MESSAGE
|
||||
is ReplEvalResult.UnitResult -> ""
|
||||
|
||||
@@ -98,6 +98,10 @@ data class ScriptDiagnostic(
|
||||
}
|
||||
}
|
||||
|
||||
fun ScriptDiagnostic.isError() =
|
||||
(severity == ScriptDiagnostic.Severity.ERROR || severity == ScriptDiagnostic.Severity.FATAL) &&
|
||||
(code == ScriptDiagnostic.unspecifiedException || code == ScriptDiagnostic.unspecifiedError)
|
||||
|
||||
/**
|
||||
* The result wrapper with diagnostics container
|
||||
*/
|
||||
|
||||
+4
-2
@@ -456,8 +456,10 @@ class ReplTest : TestCase() {
|
||||
is ResultValue.Unit -> Assert.assertNull("#$index: Expected $expectedVal, got Unit", expectedVal)
|
||||
is ResultValue.Error -> Assert.assertTrue(
|
||||
"#$index: Expected $expectedVal, got Error: ${actualVal.error}",
|
||||
expectedVal is Throwable && expectedVal.message == actualVal.error.message
|
||||
&& expectedVal.cause?.message == actualVal.error.cause?.message
|
||||
((expectedVal as? Throwable) ?: (expectedVal as? ResultValue.Error)?.error).let {
|
||||
it != null && it.message == actualVal.error.message
|
||||
&& it.cause?.message == actualVal.error.cause?.message
|
||||
}
|
||||
)
|
||||
is ResultValue.NotEvaluated -> Assert.assertEquals(
|
||||
"#$index: Expected $expectedVal, got NotEvaluated",
|
||||
|
||||
+1
-1
@@ -298,7 +298,7 @@ class ScriptingHostTest : TestCase() {
|
||||
"println(\"$greeting\")".toScriptSource(),
|
||||
{},
|
||||
{
|
||||
scriptExecutionWrapper {
|
||||
scriptExecutionWrapper<Any?> {
|
||||
val outStream = ByteArrayOutputStream()
|
||||
val prevOut = System.out
|
||||
System.setOut(PrintStream(outStream))
|
||||
|
||||
@@ -57,8 +57,13 @@ class BasicJvmReplEvaluator(val scriptEvaluator: ScriptEvaluator = BasicJvmScrip
|
||||
}
|
||||
KJvmEvaluatedSnippet(snippetVal, currentConfiguration, retVal)
|
||||
}
|
||||
else ->
|
||||
KJvmEvaluatedSnippet(snippetVal, currentConfiguration, ResultValue.NotEvaluated)
|
||||
else -> {
|
||||
val firstError = evalRes.reports.find { it.isError() }
|
||||
KJvmEvaluatedSnippet(
|
||||
snippetVal, currentConfiguration,
|
||||
firstError?.exception?.let { ResultValue.Error(it) } ?: ResultValue.NotEvaluated
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val newNode = lastEvaluatedSnippet.add(newEvalRes)
|
||||
|
||||
+9
@@ -5,6 +5,7 @@
|
||||
|
||||
package kotlin.script.experimental.jvm.util
|
||||
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.PrintStream
|
||||
import kotlin.script.experimental.api.ResultValue
|
||||
|
||||
@@ -42,3 +43,11 @@ fun ResultValue.Error.renderError(stream: PrintStream) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ResultValue.Error.renderError(): String =
|
||||
ByteArrayOutputStream().use { os ->
|
||||
val ps = PrintStream(os)
|
||||
renderError(ps)
|
||||
ps.flush()
|
||||
os.toString()
|
||||
}
|
||||
|
||||
+1
-3
@@ -10,7 +10,6 @@ import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplFromTerminal
|
||||
|
||||
class JvmCliReplShellExtension : ShellExtension {
|
||||
@@ -22,8 +21,7 @@ class JvmCliReplShellExtension : ShellExtension {
|
||||
configuration: CompilerConfiguration,
|
||||
projectEnvironment: JavaCoreProjectEnvironment
|
||||
): ExitCode {
|
||||
configuration.put(JVMConfigurationKeys.IR, false)
|
||||
ReplFromTerminal.run(projectEnvironment.parentDisposable, configuration)
|
||||
ReplFromTerminal.run(projectEnvironment, configuration)
|
||||
return ExitCode.OK
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -81,13 +81,13 @@ open class GenericReplCompiler(
|
||||
val analysisResult = compilerState.analyzerEngine.analyzeReplLine(psiFile, codeLine)
|
||||
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder, renderDiagnosticName = false)
|
||||
val scriptDescriptor = when (analysisResult) {
|
||||
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.WithErrors -> {
|
||||
return ReplCompileResult.Error(errorHolder.renderMessage())
|
||||
}
|
||||
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.Successful -> {
|
||||
(analysisResult.scriptDescriptor as? ScriptDescriptor)
|
||||
?: error("Unexpected script descriptor type ${analysisResult.scriptDescriptor::class}")
|
||||
}
|
||||
is ReplCodeAnalyzerBase.ReplLineAnalysisResult.WithErrors -> {
|
||||
return ReplCompileResult.Error(errorHolder.renderMessage())
|
||||
}
|
||||
else -> error("Unexpected result ${analysisResult::class.java}")
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin.repl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
|
||||
@@ -24,12 +24,12 @@ import java.util.concurrent.Executors
|
||||
import java.util.concurrent.Future
|
||||
|
||||
class ReplFromTerminal(
|
||||
disposable: Disposable,
|
||||
projectEnvironment: JavaCoreProjectEnvironment,
|
||||
compilerConfiguration: CompilerConfiguration,
|
||||
private val replConfiguration: ReplConfiguration
|
||||
) {
|
||||
private val replInitializer: Future<ReplInterpreter> = Executors.newSingleThreadExecutor().submit(Callable {
|
||||
ReplInterpreter(disposable, compilerConfiguration, replConfiguration)
|
||||
ReplInterpreter(projectEnvironment, compilerConfiguration, replConfiguration)
|
||||
})
|
||||
|
||||
private val replInterpreter: ReplInterpreter
|
||||
@@ -109,7 +109,7 @@ class ReplFromTerminal(
|
||||
}
|
||||
}
|
||||
is ReplEvalResult.Error.Runtime -> writer.outputRuntimeError(evalResult.message)
|
||||
is ReplEvalResult.Error.CompileTime -> writer.outputRuntimeError(evalResult.message)
|
||||
is ReplEvalResult.Error.CompileTime -> writer.outputCompileError(evalResult.message)
|
||||
is ReplEvalResult.Incomplete -> writer.notifyIncomplete()
|
||||
is ReplEvalResult.HistoryMismatch -> {} // assuming handled elsewhere
|
||||
}
|
||||
@@ -153,11 +153,11 @@ class ReplFromTerminal(
|
||||
return listOf(*command.split(" ".toRegex()).dropLastWhile(String::isEmpty).toTypedArray())
|
||||
}
|
||||
|
||||
fun run(disposable: Disposable, configuration: CompilerConfiguration) {
|
||||
fun run(projectEnvironment: JavaCoreProjectEnvironment, configuration: CompilerConfiguration) {
|
||||
val replIdeMode = System.getProperty("kotlin.repl.ideMode") == "true"
|
||||
val replConfiguration = if (replIdeMode) IdeReplConfiguration() else ConsoleReplConfiguration()
|
||||
return try {
|
||||
ReplFromTerminal(disposable, configuration, replConfiguration).doRun()
|
||||
ReplFromTerminal(projectEnvironment, configuration, replConfiguration).doRun()
|
||||
} catch (e: Exception) {
|
||||
replConfiguration.exceptionReporter.report(e)
|
||||
throw e
|
||||
|
||||
+131
-36
@@ -5,29 +5,98 @@
|
||||
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin.repl
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.*
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplClassLoader
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.messageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ReplCompilationState
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ScriptDiagnosticsMessageCollector
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.createCompilationContextFromEnvironment
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.configuration.ReplConfiguration
|
||||
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider
|
||||
import java.io.PrintWriter
|
||||
import java.net.URLClassLoader
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
import kotlin.script.experimental.host.withDefaultsFrom
|
||||
import kotlin.script.experimental.impl.internalScriptingRunSuspend
|
||||
import kotlin.script.experimental.jvm.BasicJvmReplEvaluator
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.util.renderError
|
||||
|
||||
class ReplInterpreter(
|
||||
disposable: Disposable,
|
||||
projectEnvironment: JavaCoreProjectEnvironment,
|
||||
private val configuration: CompilerConfiguration,
|
||||
private val replConfiguration: ReplConfiguration
|
||||
) {
|
||||
private val hostConfiguration: ScriptingHostConfiguration
|
||||
private val compilationConfiguration: ScriptCompilationConfiguration
|
||||
private val evaluationConfiguration: ScriptEvaluationConfiguration
|
||||
|
||||
private val replState: JvmReplCompilerState<*>
|
||||
|
||||
init {
|
||||
val scriptDefinition: ScriptDefinition? =
|
||||
ScriptDefinitionProvider.getInstance(projectEnvironment.project)?.getDefaultDefinition()
|
||||
hostConfiguration = scriptDefinition?.hostConfiguration.withDefaultsFrom(defaultJvmScriptingHostConfiguration)
|
||||
|
||||
val environment = (projectEnvironment as? KotlinCoreEnvironment.ProjectEnvironment)?.let {
|
||||
KotlinCoreEnvironment.createForProduction(it, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
}
|
||||
?: KotlinCoreEnvironment.createForProduction(
|
||||
projectEnvironment.parentDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
)
|
||||
|
||||
val context =
|
||||
createCompilationContextFromEnvironment(
|
||||
scriptDefinition?.compilationConfiguration.with {
|
||||
hostConfiguration(this@ReplInterpreter.hostConfiguration)
|
||||
},
|
||||
environment,
|
||||
ScriptDiagnosticsMessageCollector(environment.messageCollector)
|
||||
)
|
||||
|
||||
compilationConfiguration = context.baseScriptCompilationConfiguration
|
||||
evaluationConfiguration = scriptDefinition?.evaluationConfiguration.with {
|
||||
hostConfiguration(this@ReplInterpreter.hostConfiguration)
|
||||
scriptExecutionWrapper<Any> { replConfiguration.executionInterceptor.execute(it) }
|
||||
constructorArgs(emptyArray<String>())
|
||||
}
|
||||
|
||||
replState = JvmReplCompilerState(
|
||||
{
|
||||
ReplCompilationState(
|
||||
context,
|
||||
analyzerInit = { context1, resolutionFilter ->
|
||||
ReplCodeAnalyzerBase(context1.environment, implicitsResolutionFilter = resolutionFilter)
|
||||
},
|
||||
implicitsResolutionFilter = ReplImplicitsExtensionsResolutionFilter()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private val compiler = KJvmReplCompilerBase<ReplCodeAnalyzerBase>(hostConfiguration, replState)
|
||||
private val evaluator = BasicJvmReplEvaluator()
|
||||
|
||||
private val lineNumber = AtomicInteger()
|
||||
|
||||
private fun nextSnippet(code: String) =
|
||||
code.toScriptSource(
|
||||
"Line_${lineNumber.getAndIncrement()}.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}"
|
||||
)
|
||||
|
||||
private val previousIncompleteLines = arrayListOf<String>()
|
||||
|
||||
private val classpathRoots = configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS).mapNotNull { root ->
|
||||
@@ -75,33 +144,65 @@ class ReplInterpreter(
|
||||
override fun hasErrors(): Boolean = hasErrors
|
||||
}
|
||||
|
||||
// TODO: add script definition with project-based resolving for IDEA repl
|
||||
private val scriptCompiler: ReplCompilerWithoutCheck by lazy {
|
||||
GenericReplCompiler(
|
||||
disposable,
|
||||
REPL_LINE_AS_SCRIPT_DEFINITION,
|
||||
configuration,
|
||||
messageCollector
|
||||
)
|
||||
}
|
||||
private val scriptEvaluator: ReplFullEvaluator by lazy {
|
||||
GenericReplCompilingEvaluator(scriptCompiler, classpathRoots, classLoader, null, ReplRepeatingMode.REPEAT_ANY_PREVIOUS)
|
||||
}
|
||||
|
||||
private val evalState by lazy { scriptEvaluator.createState() }
|
||||
|
||||
fun eval(line: String): ReplEvalResult {
|
||||
val fullText = (previousIncompleteLines + line).joinToString(separator = "\n")
|
||||
|
||||
try {
|
||||
val evalRes = scriptEvaluator.compileAndEval(
|
||||
evalState,
|
||||
ReplCodeLine(lineNumber.getAndIncrement(), 0, fullText),
|
||||
null,
|
||||
object : InvokeWrapper {
|
||||
override fun <T> invoke(body: () -> T): T = replConfiguration.executionInterceptor.execute(body)
|
||||
val snippet = nextSnippet(fullText)
|
||||
|
||||
fun SourceCode.Location.toCompilerMessageLocation() =
|
||||
CompilerMessageLocation.create(
|
||||
snippet.name,
|
||||
start.line, start.col,
|
||||
snippet.text.lines().getOrNull(start.line - 1)
|
||||
)
|
||||
|
||||
fun ResultWithDiagnostics<*>.reportToMessageCollector() {
|
||||
for (it in reports) {
|
||||
val diagnosticSeverity = when (it.severity) {
|
||||
ScriptDiagnostic.Severity.ERROR -> CompilerMessageSeverity.ERROR
|
||||
ScriptDiagnostic.Severity.FATAL -> CompilerMessageSeverity.EXCEPTION
|
||||
ScriptDiagnostic.Severity.WARNING -> CompilerMessageSeverity.WARNING
|
||||
else -> continue
|
||||
}
|
||||
messageCollector.report(diagnosticSeverity, it.message, it.location?.toCompilerMessageLocation())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
val evalRes: ReplEvalResult = internalScriptingRunSuspend {
|
||||
when (val compileResult = compiler.compile(listOf(snippet), compilationConfiguration)) {
|
||||
is ResultWithDiagnostics.Failure -> {
|
||||
val incompleteReport = compileResult.reports.find { it.code == ScriptDiagnostic.incompleteCode }
|
||||
val firstError = compileResult.reports.find { it.isError() }
|
||||
if (incompleteReport != null)
|
||||
ReplEvalResult.Incomplete(incompleteReport.message)
|
||||
else {
|
||||
compileResult.reportToMessageCollector()
|
||||
ReplEvalResult.Error.CompileTime(firstError?.message ?: "", firstError?.location?.toCompilerMessageLocation())
|
||||
}
|
||||
}
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
compileResult.reportToMessageCollector()
|
||||
val evalResult = evaluator.eval(compileResult.value, evaluationConfiguration)
|
||||
when (evalResult) {
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
when (val evalValue = evalResult.value.get().result) {
|
||||
is ResultValue.Unit -> ReplEvalResult.UnitResult()
|
||||
is ResultValue.Value -> ReplEvalResult.ValueResult(evalValue.name, evalValue.value, evalValue.type)
|
||||
is ResultValue.Error -> ReplEvalResult.Error.Runtime(evalValue.renderError())
|
||||
else -> ReplEvalResult.Error.Runtime("Error: snippet is not evaluated")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val firstError = evalResult.reports.find { it.isError() }
|
||||
evalResult.reportToMessageCollector()
|
||||
ReplEvalResult.Error.Runtime(firstError?.message ?: "", firstError?.exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when {
|
||||
evalRes !is ReplEvalResult.Incomplete -> previousIncompleteLines.clear()
|
||||
@@ -120,10 +221,4 @@ class ReplInterpreter(
|
||||
fun dumpClasses(out: PrintWriter) {
|
||||
classLoader.dumpClasses(out)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val REPL_LINE_AS_SCRIPT_DEFINITION = object : KotlinScriptDefinition(Any::class) {
|
||||
override val name = "Kotlin REPL"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user