Make state of the default REPL compiler explicit and replaceable
restores proper object hierarchy in case the legacy REPL infrastructure
This commit is contained in:
committed by
TeamCityServer
parent
e7c9a46329
commit
a45e31720c
+1
-1
@@ -125,7 +125,7 @@ internal class LegacyTestRepl : Closeable {
|
||||
fun nextCodeLine(code: String): ReplCodeLine = ReplCodeLine(currentLineCounter.getAndIncrement(), 0, code)
|
||||
|
||||
val replCompiler: JvmReplCompiler by lazy {
|
||||
JvmReplCompiler(simpleScriptCompilationConfiguration, false)
|
||||
JvmReplCompiler(simpleScriptCompilationConfiguration)
|
||||
}
|
||||
|
||||
val compiledEvaluator: ReplEvaluator by lazy {
|
||||
|
||||
+15
-6
@@ -8,12 +8,12 @@ package kotlin.script.experimental.jvmhost.test
|
||||
import junit.framework.TestCase
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
import kotlin.script.experimental.jvm.BasicJvmReplEvaluator
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.updateClasspath
|
||||
import kotlin.script.experimental.jvm.util.classpathFromClass
|
||||
import kotlin.script.experimental.jvmhost.createJvmScriptDefinitionFromTemplate
|
||||
@@ -212,7 +212,7 @@ class ReplTest : TestCase() {
|
||||
|
||||
@Test
|
||||
fun testAddNewAnnotationHandler() {
|
||||
val replCompiler = KJvmReplCompilerBase.create(defaultJvmScriptingHostConfiguration)
|
||||
val replCompiler = KJvmReplCompilerBase<ReplCodeAnalyzerBase>()
|
||||
val replEvaluator = BasicJvmReplEvaluator()
|
||||
val compilationConfiguration = ScriptCompilationConfiguration().with {
|
||||
updateClasspath(classpathFromClass<NewAnn>())
|
||||
@@ -224,7 +224,10 @@ class ReplTest : TestCase() {
|
||||
replEvaluator.eval(it, evaluationConfiguration)
|
||||
}
|
||||
}
|
||||
assertTrue("Expecting 1 got $res0", res0 is ResultWithDiagnostics.Success && (res0.value.get().result as ResultValue.Value).value == 1)
|
||||
assertTrue(
|
||||
"Expecting 1 got $res0",
|
||||
res0 is ResultWithDiagnostics.Success && (res0.value.get().result as ResultValue.Value).value == 1
|
||||
)
|
||||
|
||||
var handlerInvoked = false
|
||||
|
||||
@@ -239,11 +242,17 @@ class ReplTest : TestCase() {
|
||||
}
|
||||
|
||||
val res1 = runBlocking {
|
||||
replCompiler.compile("@file:kotlin.script.experimental.jvmhost.test.NewAnn()\n2".toScriptSource("Line_1.kts"), compilationConfiguration2).onSuccess {
|
||||
replCompiler.compile(
|
||||
"@file:kotlin.script.experimental.jvmhost.test.NewAnn()\n2".toScriptSource("Line_1.kts"),
|
||||
compilationConfiguration2
|
||||
).onSuccess {
|
||||
replEvaluator.eval(it, evaluationConfiguration)
|
||||
}
|
||||
}
|
||||
assertTrue("Expecting 2 got $res1", res1 is ResultWithDiagnostics.Success && (res1.value.get().result as ResultValue.Value).value == 2)
|
||||
assertTrue(
|
||||
"Expecting 2 got $res1",
|
||||
res1 is ResultWithDiagnostics.Success && (res1.value.get().result as ResultValue.Value).value == 2
|
||||
)
|
||||
|
||||
assertTrue("Refinement handler on annotation is not invoked", handlerInvoked)
|
||||
}
|
||||
@@ -275,7 +284,7 @@ class ReplTest : TestCase() {
|
||||
evaluationConfiguration: ScriptEvaluationConfiguration? = simpleScriptEvaluationConfiguration,
|
||||
limit: Int = 0
|
||||
): Sequence<ResultWithDiagnostics<EvaluatedSnippet>> {
|
||||
val replCompiler = KJvmReplCompilerBase.create(defaultJvmScriptingHostConfiguration)
|
||||
val replCompiler = KJvmReplCompilerBase<ReplCodeAnalyzerBase>()
|
||||
val replEvaluator = BasicJvmReplEvaluator()
|
||||
val currentEvalConfig = evaluationConfiguration ?: ScriptEvaluationConfiguration()
|
||||
val snipetsLimited = if (limit == 0) snippets else snippets.take(limit)
|
||||
|
||||
+1
-2
@@ -6,7 +6,6 @@
|
||||
package kotlin.script.experimental.jvmhost.jsr223
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCompilerWithoutCheck
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import javax.script.ScriptContext
|
||||
import javax.script.ScriptEngineFactory
|
||||
@@ -63,7 +62,7 @@ class KotlinJsr223ScriptEngineImpl(
|
||||
}
|
||||
|
||||
override val replCompiler: ReplCompilerWithoutCheck by lazy {
|
||||
JvmReplCompiler(compilationConfiguration, true)
|
||||
JvmReplCompiler(compilationConfiguration)
|
||||
}
|
||||
|
||||
private val localEvaluator by lazy {
|
||||
|
||||
+14
-45
@@ -5,18 +5,16 @@
|
||||
|
||||
package kotlin.script.experimental.jvmhost.repl
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.push
|
||||
import org.jetbrains.kotlin.cli.common.repl.*
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerBase
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerStageHistory
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.write
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.impl.internalScriptingRunSuspend
|
||||
import kotlin.script.experimental.host.ScriptingHostConfiguration
|
||||
import kotlin.script.experimental.host.withDefaultsFrom
|
||||
import kotlin.script.experimental.impl.internalScriptingRunSuspend
|
||||
import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration
|
||||
import kotlin.script.experimental.jvm.util.isIncomplete
|
||||
|
||||
@@ -25,50 +23,28 @@ import kotlin.script.experimental.jvm.util.isIncomplete
|
||||
*/
|
||||
class JvmReplCompiler(
|
||||
val scriptCompilationConfiguration: ScriptCompilationConfiguration,
|
||||
val allowReInit: Boolean = true,
|
||||
val hostConfiguration: ScriptingHostConfiguration = defaultJvmScriptingHostConfiguration,
|
||||
var replCompiler: KJvmReplCompilerBase<ReplCodeAnalyzerBase> = KJvmReplCompilerBase.create(
|
||||
hostConfiguration.withDefaultsFrom(defaultJvmScriptingHostConfiguration)
|
||||
)
|
||||
val hostConfiguration: ScriptingHostConfiguration = defaultJvmScriptingHostConfiguration
|
||||
) : ReplCompilerWithoutCheck {
|
||||
|
||||
private val compilers = mutableListOf(replCompiler)
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> =
|
||||
if (allowReInit) {
|
||||
JvmReplCompilerState({ replCompiler.createReplCompilationState(it, replCompiler.initAnalyzer) }, lock)
|
||||
} else {
|
||||
replCompiler.state
|
||||
}
|
||||
JvmReplCompilerState({ KJvmReplCompilerBase.createCompilationState(it, hostConfiguration) }, lock)
|
||||
|
||||
override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult = replCompiler.state.lock.write {
|
||||
override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult = state.lock.write {
|
||||
val replCompilerState = state.asState(JvmReplCompilerState::class.java)
|
||||
val snippet = codeLine.toSourceCode(scriptCompilationConfiguration)
|
||||
|
||||
if (allowReInit) {
|
||||
replCompiler = compilers.find { historiesEq(it.history, replCompilerState.history) } ?: {
|
||||
compilers.push(
|
||||
KJvmReplCompilerBase.create(
|
||||
hostConfiguration.withDefaultsFrom(defaultJvmScriptingHostConfiguration)
|
||||
)
|
||||
)
|
||||
compilers.last()
|
||||
}()
|
||||
}
|
||||
val replCompiler = KJvmReplCompilerBase<ReplCodeAnalyzerBase>(
|
||||
hostConfiguration.withDefaultsFrom(defaultJvmScriptingHostConfiguration),
|
||||
replCompilerState
|
||||
)
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
when (val res = internalScriptingRunSuspend { replCompiler.compile(listOf(snippet), scriptCompilationConfiguration) }) {
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
val lineId = LineId(codeLine.no, 0, snippet.hashCode())
|
||||
replCompilerState.apply {
|
||||
lock.write {
|
||||
val compilerHistory = history as JvmReplCompilerStageHistory<*>
|
||||
compilerHistory.push(lineId, replCompiler.history.last().item)
|
||||
}
|
||||
}
|
||||
ReplCompileResult.CompiledClasses(
|
||||
lineId,
|
||||
replCompiler.history.map { it.id },
|
||||
replCompiler.state.history.map { it.id },
|
||||
snippet.name!!,
|
||||
emptyList(),
|
||||
res.value.get().resultField != null,
|
||||
@@ -87,15 +63,6 @@ class JvmReplCompiler(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun historiesEq(history1: IReplStageHistory<*>, history2: IReplStageHistory<*>) =
|
||||
history1.count() == history2.count() &&
|
||||
history1.zip(history2).all {
|
||||
val (it1, it2) = it
|
||||
it1.item === it2.item
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,9 +72,11 @@ internal class SourceCodeFromReplCodeLine(
|
||||
) : SourceCode {
|
||||
override val text: String get() = codeLine.code
|
||||
override val name: String =
|
||||
"${compilationConfiguration[ScriptCompilationConfiguration.repl.makeSnippetIdentifier]!!(
|
||||
compilationConfiguration, ReplSnippetIdImpl(codeLine.no, codeLine.generation, 0)
|
||||
)}.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}"
|
||||
"${
|
||||
compilationConfiguration[ScriptCompilationConfiguration.repl.makeSnippetIdentifier]!!(
|
||||
compilationConfiguration, ReplSnippetIdImpl(codeLine.no, codeLine.generation, 0)
|
||||
)
|
||||
}.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}"
|
||||
override val locationId: String? = null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user