Skip to content

Commit 166d28a

Browse files
cmelchiorSpace Team
authored and
Space Team
committed
Add ReplCompilerMode enum, allowing users of the Kernel to start it in either K1 or K2 mode
Merge-request: KDS-MR-59 Merged-by: Christian Melchior <[email protected]>
1 parent 200696e commit 166d28a

File tree

11 files changed

+96
-6
lines changed

11 files changed

+96
-6
lines changed

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/config/Compilation.kt

+9
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import jupyter.kotlin.CompilerArgs
44
import jupyter.kotlin.DependsOn
55
import jupyter.kotlin.Repository
66
import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicitsExceptInnermost
7+
import org.jetbrains.kotlinx.jupyter.api.KernelLoggerFactory
78
import org.jetbrains.kotlinx.jupyter.compiler.CompilerArgsConfigurator
89
import org.jetbrains.kotlinx.jupyter.compiler.ScriptDataCollector
910
import org.jetbrains.kotlinx.jupyter.messaging.ExecutionCount
11+
import org.jetbrains.kotlinx.jupyter.startup.DEFAULT
12+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
1013
import java.io.File
1114
import kotlin.script.experimental.api.KotlinType
1215
import kotlin.script.experimental.api.ScriptAcceptedLocation
@@ -61,14 +64,20 @@ val ScriptCompilationConfigurationKeys.jupyterOptions by PropertiesCollection.ke
6164
defaultValue = JupyterCompilingOptions.DEFAULT,
6265
)
6366

67+
// Also called from IDEA
6468
fun getCompilationConfiguration(
6569
scriptClasspath: List<File> = emptyList(),
6670
scriptReceivers: List<Any> = emptyList(),
6771
compilerArgsConfigurator: CompilerArgsConfigurator,
6872
scriptingClassGetter: GetScriptingClassByClassLoader = JvmGetScriptingClass(),
6973
scriptDataCollectors: List<ScriptDataCollector> = emptyList(),
74+
replCompilerMode: ReplCompilerMode = ReplCompilerMode.DEFAULT,
75+
loggerFactory: KernelLoggerFactory,
7076
body: ScriptCompilationConfiguration.Builder.() -> Unit = {},
7177
): ScriptCompilationConfiguration {
78+
if (replCompilerMode == ReplCompilerMode.K2) {
79+
loggerFactory.getLogger("getCompilationConfiguration").warn("K2 Repl Mode is ignored for now. Falling back to K1")
80+
}
7281
return ScriptCompilationConfiguration {
7382
hostConfiguration.update {
7483
it.with {

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/DefaultReplComponentsProvider.kt

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import org.jetbrains.kotlinx.jupyter.repl.MavenRepositoryCoordinates
1818
import org.jetbrains.kotlinx.jupyter.repl.ReplRuntimeProperties
1919
import org.jetbrains.kotlinx.jupyter.repl.config.DefaultReplSettings
2020
import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
21+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
2122
import org.jetbrains.kotlinx.jupyter.util.toUpperCaseAsciiOnly
2223
import java.io.File
2324

@@ -115,4 +116,8 @@ open class DefaultReplComponentsProvider(
115116
override fun provideInMemoryReplResultsHolder(): InMemoryReplResultsHolder {
116117
return _inMemoryResultsHolder
117118
}
119+
120+
override fun provideReplCompilerMode(): ReplCompilerMode {
121+
return _settings.kernelConfig.replCompilerMode
122+
}
118123
}

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/LazilyConstructibleReplComponentsProvider.kt

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlinx.jupyter.repl.ReplOptions
2424
import org.jetbrains.kotlinx.jupyter.repl.ReplRuntimeProperties
2525
import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
2626
import org.jetbrains.kotlinx.jupyter.repl.notebook.MutableNotebook
27+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
2728
import java.io.File
2829

2930
interface LazilyConstructibleReplComponentsProvider : ReplComponentsProvider {
@@ -80,4 +81,6 @@ interface LazilyConstructibleReplComponentsProvider : ReplComponentsProvider {
8081
fun provideLibraryReferenceParser(): LibraryReferenceParser
8182

8283
fun provideInMemoryReplResultsHolder(): InMemoryReplResultsHolder
84+
85+
fun provideReplCompilerMode(): ReplCompilerMode
8386
}

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/LazilyConstructibleReplComponentsProviderImpl.kt

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.jetbrains.kotlinx.jupyter.repl.MavenRepositoryCoordinates
2121
import org.jetbrains.kotlinx.jupyter.repl.ReplOptions
2222
import org.jetbrains.kotlinx.jupyter.repl.ReplRuntimeProperties
2323
import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
24+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
2425
import java.io.File
2526

2627
abstract class LazilyConstructibleReplComponentsProviderImpl : LazilyConstructibleReplComponentsProvider {
@@ -51,6 +52,7 @@ abstract class LazilyConstructibleReplComponentsProviderImpl : LazilyConstructib
5152
override val magicsHandler: LibrariesAwareMagicsHandler? by lazy { provideMagicsHandler() }
5253
override val libraryReferenceParser: LibraryReferenceParser by lazy { provideLibraryReferenceParser() }
5354
override val inMemoryReplResultsHolder: InMemoryReplResultsHolder by lazy { provideInMemoryReplResultsHolder() }
55+
override val replCompilerMode: ReplCompilerMode by lazy { provideReplCompilerMode() }
5456

5557
// TODO: add other methods incl. display handler and socket messages listener
5658
// Inheritors should be constructed of connection (JupyterConnection)

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/ReplComponentsProvider.kt

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlinx.jupyter.repl.ReplOptions
2424
import org.jetbrains.kotlinx.jupyter.repl.ReplRuntimeProperties
2525
import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
2626
import org.jetbrains.kotlinx.jupyter.repl.notebook.MutableNotebook
27+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
2728
import java.io.File
2829

2930
interface ReplComponentsProvider {
@@ -54,4 +55,5 @@ interface ReplComponentsProvider {
5455
val magicsHandler: LibrariesAwareMagicsHandler?
5556
val libraryReferenceParser: LibraryReferenceParser
5657
val inMemoryReplResultsHolder: InMemoryReplResultsHolder
58+
val replCompilerMode: ReplCompilerMode
5759
}

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/ReplComponentsProviderBase.kt

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
4141
import org.jetbrains.kotlinx.jupyter.repl.embedded.NoOpInMemoryReplResultsHolder
4242
import org.jetbrains.kotlinx.jupyter.repl.notebook.MutableNotebook
4343
import org.jetbrains.kotlinx.jupyter.repl.notebook.impl.NotebookImpl
44+
import org.jetbrains.kotlinx.jupyter.startup.DEFAULT
45+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
4446
import org.jetbrains.kotlinx.jupyter.util.asCommonFactory
4547
import java.io.File
4648

@@ -130,4 +132,6 @@ abstract class ReplComponentsProviderBase : LazilyConstructibleReplComponentsPro
130132
override fun provideLibraryReferenceParser(): LibraryReferenceParser = LibraryReferenceParserImpl(libraryInfoCache)
131133

132134
override fun provideInMemoryReplResultsHolder(): InMemoryReplResultsHolder = NoOpInMemoryReplResultsHolder
135+
136+
override fun provideReplCompilerMode(): ReplCompilerMode = ReplCompilerMode.DEFAULT
133137
}

Diff for: jupyter-lib/shared-compiler/src/main/kotlin/org/jetbrains/kotlinx/jupyter/startup/Arguments.kt

+21-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ import java.util.EnumMap
1818

1919
typealias KernelPorts = Map<JupyterSocketType, Int>
2020

21+
/**
22+
* This is used to represent whether the underlying REPL is running in either K1 or K2 mode.
23+
*/
24+
enum class ReplCompilerMode {
25+
K1,
26+
K2,
27+
;
28+
29+
companion object
30+
}
31+
32+
val ReplCompilerMode.Companion.DEFAULT get() = ReplCompilerMode.K1
2133
const val KERNEL_TRANSPORT_SCHEME = "tcp"
2234
const val KERNEL_SIGNATURE_SCHEME = "HmacSHA256"
2335

@@ -37,6 +49,7 @@ data class KernelArgs(
3749
val debugPort: Int?,
3850
val clientType: String?,
3951
val jvmTargetForSnippets: String?,
52+
val replCompilerMode: ReplCompilerMode,
4053
) {
4154
fun parseParams(): KernelJupyterParams {
4255
return KernelJupyterParams.fromFile(cfgFile)
@@ -53,6 +66,7 @@ data class KernelArgs(
5366
debugPort?.let { add("-debugPort=$it") }
5467
clientType?.let { add("-client=$it") }
5568
jvmTargetForSnippets?.let { add("-jvmTarget=$it") }
69+
add("-replCompilerMode=${replCompilerMode.name}")
5670
}
5771
}
5872
}
@@ -120,6 +134,7 @@ data class KernelConfig(
120134
val debugPort: Int? = null,
121135
val clientType: String? = null,
122136
val jvmTargetForSnippets: String? = null,
137+
val replCompilerMode: ReplCompilerMode = ReplCompilerMode.DEFAULT,
123138
) {
124139
val hmac by lazy {
125140
HMAC(signatureScheme.replace("-", ""), signatureKey)
@@ -133,7 +148,7 @@ data class KernelConfig(
133148
val format = Json { prettyPrint = true }
134149
cfgFile.writeText(format.encodeToString(params))
135150

136-
return KernelArgs(cfgFile, scriptClasspath, homeDir, debugPort, clientType, jvmTargetForSnippets)
151+
return KernelArgs(cfgFile, scriptClasspath, homeDir, debugPort, clientType, jvmTargetForSnippets, replCompilerMode)
137152
}
138153
}
139154

@@ -149,13 +164,15 @@ fun createClientKotlinKernelConfig(
149164
host: String,
150165
ports: KernelPorts,
151166
signatureKey: String,
167+
replCompilerMode: ReplCompilerMode,
152168
) = KernelConfig(
153169
host = host,
154170
ports = ports,
155171
transport = KERNEL_TRANSPORT_SCHEME,
156172
signatureScheme = KERNEL_SIGNATURE_SCHEME,
157173
signatureKey = signatureKey,
158174
homeDir = null,
175+
replCompilerMode = replCompilerMode,
159176
)
160177

161178
/**
@@ -179,6 +196,7 @@ fun createKotlinKernelConfig(
179196
homeDir: File? = null,
180197
debugPort: Int? = null,
181198
clientType: String? = null,
199+
replCompilerMode: ReplCompilerMode = ReplCompilerMode.DEFAULT,
182200
) = KernelConfig(
183201
ports = ports,
184202
transport = KERNEL_TRANSPORT_SCHEME,
@@ -188,6 +206,7 @@ fun createKotlinKernelConfig(
188206
homeDir = homeDir,
189207
debugPort = debugPort,
190208
clientType = clientType,
209+
replCompilerMode = replCompilerMode,
191210
)
192211

193212
const val MAIN_CLASS_NAME = "org.jetbrains.kotlinx.jupyter.IkotlinKt"
@@ -230,5 +249,6 @@ fun KernelArgs.getConfig(): KernelConfig {
230249
debugPort = debugPort,
231250
clientType = clientType,
232251
jvmTargetForSnippets = jvmTargetForSnippets,
252+
replCompilerMode = replCompilerMode,
233253
)
234254
}

Diff for: src/main/kotlin/org/jetbrains/kotlinx/jupyter/Ikotlin.kt

+20-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ import org.jetbrains.kotlinx.jupyter.repl.config.DefaultReplSettings
3636
import org.jetbrains.kotlinx.jupyter.repl.creating.DefaultReplComponentsProvider
3737
import org.jetbrains.kotlinx.jupyter.repl.creating.createRepl
3838
import org.jetbrains.kotlinx.jupyter.repl.embedded.NoOpInMemoryReplResultsHolder
39+
import org.jetbrains.kotlinx.jupyter.startup.DEFAULT
3940
import org.jetbrains.kotlinx.jupyter.startup.KernelArgs
4041
import org.jetbrains.kotlinx.jupyter.startup.KernelConfig
42+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
4143
import org.jetbrains.kotlinx.jupyter.startup.getConfig
4244
import org.slf4j.Logger
4345
import java.io.File
@@ -53,6 +55,7 @@ private fun parseCommandLine(vararg args: String): KernelArgs {
5355
var debugPort: Int? = null
5456
var clientType: String? = null
5557
var jvmTargetForSnippets: String? = null
58+
var replCompilerMode: ReplCompilerMode = ReplCompilerMode.DEFAULT
5659
args.forEach { arg ->
5760
when {
5861
arg.startsWith("-cp=") || arg.startsWith("-classpath=") -> {
@@ -73,6 +76,12 @@ private fun parseCommandLine(vararg args: String): KernelArgs {
7376
arg.startsWith("-jvmTarget") -> {
7477
jvmTargetForSnippets = arg.substringAfter('=')
7578
}
79+
arg.startsWith("-replCompilerMode=") -> {
80+
val userMode = arg.substringAfter('=')
81+
replCompilerMode = ReplCompilerMode.entries.find {
82+
it.name == userMode
83+
} ?: throw IllegalArgumentException("Invalid replCompilerMode: $userMode")
84+
}
7685
else -> {
7786
cfgFile?.let { throw IllegalArgumentException("config file already set to $it") }
7887
cfgFile = File(arg)
@@ -82,7 +91,7 @@ private fun parseCommandLine(vararg args: String): KernelArgs {
8291
val cfgFileValue = cfgFile ?: throw IllegalArgumentException("config file is not provided")
8392
if (!cfgFileValue.exists() || !cfgFileValue.isFile) throw IllegalArgumentException("invalid config file $cfgFileValue")
8493

85-
return KernelArgs(cfgFileValue, classpath ?: emptyList(), homeDir, debugPort, clientType, jvmTargetForSnippets)
94+
return KernelArgs(cfgFileValue, classpath ?: emptyList(), homeDir, debugPort, clientType, jvmTargetForSnippets, replCompilerMode)
8695
}
8796

8897
fun printClassPath(logger: Logger) {
@@ -129,7 +138,16 @@ fun embedKernel(
129138
scriptReceivers: List<Any>? = null,
130139
) {
131140
val scriptClasspath = System.getProperty("java.class.path").split(File.pathSeparator).toTypedArray().map { File(it) }
132-
val kernelConfig = KernelArgs(cfgFile, scriptClasspath, null, null, null, null).getConfig()
141+
val kernelConfig =
142+
KernelArgs(
143+
cfgFile = cfgFile,
144+
scriptClasspath = scriptClasspath,
145+
homeDir = null,
146+
debugPort = null,
147+
clientType = null,
148+
jvmTargetForSnippets = null,
149+
replCompilerMode = ReplCompilerMode.DEFAULT,
150+
).getConfig()
133151
val replSettings =
134152
createReplSettings(
135153
DefaultKernelLoggerFactory,

Diff for: src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/CreatingUtil.kt

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import org.jetbrains.kotlinx.jupyter.repl.ReplForJupyter
1616
import org.jetbrains.kotlinx.jupyter.repl.ReplRuntimeProperties
1717
import org.jetbrains.kotlinx.jupyter.repl.embedded.InMemoryReplResultsHolder
1818
import org.jetbrains.kotlinx.jupyter.repl.embedded.NoOpInMemoryReplResultsHolder
19+
import org.jetbrains.kotlinx.jupyter.startup.DEFAULT
20+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
1921
import java.io.File
2022

2123
fun createRepl(
@@ -32,6 +34,7 @@ fun createRepl(
3234
communicationFacility: JupyterCommunicationFacility = CommunicationFacilityMock,
3335
debugPort: Int? = null,
3436
inMemoryReplResultsHolder: InMemoryReplResultsHolder = NoOpInMemoryReplResultsHolder,
37+
replCompilerMode: ReplCompilerMode = ReplCompilerMode.DEFAULT,
3538
): ReplForJupyter {
3639
val componentsProvider =
3740
object : ReplComponentsProviderBase() {
@@ -66,6 +69,8 @@ fun createRepl(
6669
override fun provideLibraryReferenceParser() = httpUtil.libraryReferenceParser
6770

6871
override fun provideInMemoryReplResultsHolder() = inMemoryReplResultsHolder
72+
73+
override fun provideReplCompilerMode(): ReplCompilerMode = replCompilerMode
6974
}
7075
return componentsProvider.createRepl()
7176
}

Diff for: src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/creating/ReplFactoryBase.kt

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class ReplFactoryBase(
3232
sessionOptions,
3333
magicsHandler,
3434
inMemoryReplResultsHolder,
35+
replCompilerMode,
3536
)
3637
}
3738
}

Diff for: src/main/kotlin/org/jetbrains/kotlinx/jupyter/repl/impl/ReplForJupyterImpl.kt

+24-3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import org.jetbrains.kotlinx.jupyter.compiler.DefaultCompilerArgsConfigurator
5353
import org.jetbrains.kotlinx.jupyter.compiler.ScriptDeclarationsCollectorInternal
5454
import org.jetbrains.kotlinx.jupyter.compiler.ScriptImportsCollector
5555
import org.jetbrains.kotlinx.jupyter.config.CellId
56+
import org.jetbrains.kotlinx.jupyter.config.DefaultKernelLoggerFactory
5657
import org.jetbrains.kotlinx.jupyter.config.addBaseClass
5758
import org.jetbrains.kotlinx.jupyter.config.catchAll
5859
import org.jetbrains.kotlinx.jupyter.config.defaultRuntimeProperties
@@ -118,6 +119,7 @@ import org.jetbrains.kotlinx.jupyter.repl.result.InternalMetadataImpl
118119
import org.jetbrains.kotlinx.jupyter.repl.result.InternalReplResult
119120
import org.jetbrains.kotlinx.jupyter.repl.result.SerializedCompiledScriptsData
120121
import org.jetbrains.kotlinx.jupyter.repl.result.buildScriptsData
122+
import org.jetbrains.kotlinx.jupyter.startup.ReplCompilerMode
121123
import java.io.Closeable
122124
import java.io.File
123125
import java.net.URLClassLoader
@@ -162,6 +164,7 @@ class ReplForJupyterImpl(
162164
override val sessionOptions: SessionOptions,
163165
customMagicsHandler: LibrariesAwareMagicsHandler?,
164166
private val inMemoryReplResultsHolder: InMemoryReplResultsHolder,
167+
private val replCompilerMode: ReplCompilerMode,
165168
) : ReplForJupyter, BaseKernelHost, UserHandlesProvider, Closeable {
166169
private val logger = loggerFactory.getLogger(this::class)
167170

@@ -244,6 +247,7 @@ class ReplForJupyterImpl(
244247
scriptReceivers,
245248
compilerArgsConfigurator,
246249
scriptDataCollectors = listOf(importsCollector, declarationsCollector),
250+
loggerFactory = DefaultKernelLoggerFactory,
247251
body = { addBaseClass<ScriptTemplateWithDisplayHelpers>() },
248252
).with {
249253
refineConfiguration {
@@ -305,12 +309,25 @@ class ReplForJupyterImpl(
305309
constructorArgs(this@ReplForJupyterImpl)
306310
}
307311

308-
private val jupyterCompiler by lazy {
309-
JupyterCompilerWithCompletion.create(compilerConfiguration, evaluatorConfiguration)
312+
private val jupyterCompiler: JupyterCompilerWithCompletion by lazy {
313+
when (replCompilerMode) {
314+
ReplCompilerMode.K1 -> {
315+
JupyterCompilerWithCompletion.create(
316+
compilerConfiguration,
317+
evaluatorConfiguration,
318+
)
319+
}
320+
ReplCompilerMode.K2 -> {
321+
k2Unsupported()
322+
}
323+
}
310324
}
311325

312326
private val evaluator: BasicJvmReplEvaluator by lazy {
313-
BasicJvmReplEvaluator()
327+
when (replCompilerMode) {
328+
ReplCompilerMode.K1 -> BasicJvmReplEvaluator()
329+
ReplCompilerMode.K2 -> k2Unsupported()
330+
}
314331
}
315332

316333
private val hostProvider =
@@ -780,4 +797,8 @@ class ReplForJupyterImpl(
780797
override fun close() {
781798
notebook.closeIfPossible()
782799
}
800+
801+
private fun k2Unsupported(): Nothing {
802+
throw IllegalStateException("K2 REPL is not supported yet")
803+
}
783804
}

0 commit comments

Comments
 (0)