@@ -3,41 +3,42 @@ package org.jetbrains.kotlin.jupyter
3
3
import jupyter.kotlin.*
4
4
import jupyter.kotlin.KotlinContext
5
5
import jupyter.kotlin.KotlinReceiver
6
- import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
7
- import org.jetbrains.kotlin.cli.common.repl.*
8
6
import org.jetbrains.kotlin.config.KotlinCompilerVersion
9
7
import org.jetbrains.kotlin.jupyter.repl.completion.CompletionResult
10
8
import org.jetbrains.kotlin.jupyter.repl.completion.KotlinCompleter
11
9
import org.jetbrains.kotlin.jupyter.repl.completion.ListErrorsResult
10
+ import org.jetbrains.kotlin.jupyter.repl.completion.SourceCodeImpl
12
11
import org.jetbrains.kotlin.jupyter.repl.reflect.ContextUpdater
13
- import org.jetbrains.kotlin.jupyter.repl.reflect.lines
14
12
import org.jetbrains.kotlin.jupyter.repl.spark.ClassWriter
13
+ import org.jetbrains.kotlin.scripting.ide_services.compiler.KJvmReplCompilerImpl
14
+ import org.jetbrains.kotlin.scripting.ide_services.evaluator.KJvmReplEvaluatorImpl
15
15
import java.io.File
16
16
import java.net.URLClassLoader
17
17
import java.util.*
18
- import java.util.concurrent.locks.ReentrantReadWriteLock
19
18
import kotlin.script.dependencies.ScriptContents
20
19
import kotlin.script.experimental.api.*
21
20
import kotlin.script.experimental.host.withDefaultsFrom
22
21
import kotlin.script.experimental.jvm.*
23
- import kotlin.script.experimental.jvmhost.repl.JvmReplCompiler
24
- import kotlin.script.experimental.jvmhost.repl.JvmReplEvaluator
22
+ import kotlin.script.experimental.util.hasErrors
23
+ import kotlin.script.experimental.util.isIncomplete
24
+ import kotlin.script.experimental.util.renderError
25
25
26
26
data class EvalResult (val resultValue : Any? )
27
27
28
- data class CheckResult (val codeLine : LineId , val isComplete : Boolean = true )
28
+ data class CheckResult (val isComplete : Boolean = true )
29
29
30
30
open class ReplException (message : String , cause : Throwable ? = null ) : Exception(message, cause)
31
31
32
- class ReplEvalRuntimeException (val errorResult : ReplEvalResult . Error . Runtime ) : ReplException(errorResult. message, errorResult. cause)
32
+ class ReplEvalRuntimeException (message : String , cause : Throwable ? = null ) : ReplException(message, cause)
33
33
34
- class ReplCompilerException (val errorResult : ReplCompileResult .Error ) : ReplException(errorResult.message) {
35
- constructor (checkResult: ReplCheckResult .Error ) : this (ReplCompileResult .Error (checkResult.message, checkResult.location))
36
- constructor (incompleteResult: ReplCompileResult .Incomplete ) : this (ReplCompileResult .Error (" Incomplete Code" , null ))
37
- constructor (checkResult: ReplEvalResult .Error .CompileTime ) : this (ReplCompileResult .Error (checkResult.message, checkResult.location))
38
- constructor (incompleteResult: ReplEvalResult .Incomplete ) : this (ReplCompileResult .Error (" Incomplete Code" , null ))
39
- constructor (historyMismatchResult: ReplEvalResult .HistoryMismatch ) : this (ReplCompileResult .Error (" History Mismatch" , CompilerMessageLocation .create(null , historyMismatchResult.lineNo, 0 , null )))
40
- constructor (message: String ) : this (ReplCompileResult .Error (message, null ))
34
+ class ReplCompilerException (val errorResult : ResultWithDiagnostics .Failure ? = null , message : String? = null )
35
+ : ReplException (message ? : errorResult?.renderError() ? : " " ) {
36
+
37
+ val firstDiagnostics = errorResult?.reports?.firstOrNull {
38
+ it.severity == ScriptDiagnostic .Severity .ERROR || it.severity == ScriptDiagnostic .Severity .FATAL
39
+ }
40
+
41
+ constructor (message: String ): this (null , message)
41
42
}
42
43
43
44
enum class ExecutedCodeLogging {
@@ -241,25 +242,17 @@ class ReplForJupyterImpl(val scriptClasspath: List<File> = emptyList(),
241
242
242
243
private var executionCounter = 0
243
244
244
- private val compiler: IDELikeReplCompiler by lazy {
245
- JvmReplCompiler (compilerConfiguration )
245
+ private val compiler: KJvmReplCompilerImpl by lazy {
246
+ KJvmReplCompilerImpl ( )
246
247
}
247
248
248
- private val evaluator: ReplEvaluator by lazy {
249
- JvmReplEvaluator (evaluatorConfiguration )
249
+ private val evaluator: KJvmReplEvaluatorImpl by lazy {
250
+ KJvmReplEvaluatorImpl ( )
250
251
}
251
252
252
- private val stateLock = ReentrantReadWriteLock ()
253
-
254
- private val compilerState = compiler.createState(stateLock)
255
-
256
- private val evaluatorState = evaluator.createState(stateLock)
257
-
258
- private val state = AggregatedReplStageState (compilerState, evaluatorState, stateLock)
259
-
260
253
private val completer = KotlinCompleter ()
261
254
262
- private val contextUpdater = ContextUpdater (state, ctx )
255
+ private val contextUpdater = ContextUpdater (ctx, evaluator )
263
256
264
257
private val typeProvidersProcessor: TypeProvidersProcessor = TypeProvidersProcessorImpl (contextUpdater)
265
258
@@ -270,12 +263,12 @@ class ReplForJupyterImpl(val scriptClasspath: List<File> = emptyList(),
270
263
private val scheduledExecutions = LinkedList <Code >()
271
264
272
265
override fun checkComplete (executionNumber : Long , code : String ): CheckResult {
273
- val codeLine = ReplCodeLine (executionNumber.toInt(), 0 , code)
274
- return when ( val result = compiler.check(compilerState, codeLine)) {
275
- is ReplCheckResult . Error -> throw ReplCompilerException (result)
276
- is ReplCheckResult . Ok -> CheckResult (LineId (codeLine), true )
277
- is ReplCheckResult . Incomplete -> CheckResult ( LineId (codeLine), false )
278
- else -> throw IllegalStateException ( " Unknown check result type ${result} " )
266
+ val codeLine = SourceCodeImpl (executionNumber.toInt(), code)
267
+ val result = compiler.analyze(codeLine, 0 , compilerConfiguration)
268
+ return when {
269
+ result.isIncomplete() -> CheckResult (false )
270
+ result.hasErrors() -> throw ReplException (result.renderError() )
271
+ else -> CheckResult ( true )
279
272
}
280
273
}
281
274
@@ -329,7 +322,7 @@ class ReplForJupyterImpl(val scriptClasspath: List<File> = emptyList(),
329
322
typeRenderers.putAll(p.typeRenderers.map { it.className to it.code })
330
323
}
331
324
332
- private fun lastReplLine () = state.lines[ 0 ]
325
+ private fun lastReplLine () = evaluator.lastEvaluatedSnippet()?.kInstance
333
326
334
327
override fun eval (code : String , displayHandler : ((Any ) -> Unit )? , jupyterId : Int ): EvalResult {
335
328
synchronized(this ) {
@@ -412,14 +405,16 @@ class ReplForJupyterImpl(val scriptClasspath: List<File> = emptyList(),
412
405
413
406
private val completionQueue = LockQueue <CompletionResult , CompletionArgs >()
414
407
override suspend fun complete (code : String , cursor : Int , callback : (CompletionResult ) -> Unit ) = doWithLock(CompletionArgs (code, cursor, callback), completionQueue, CompletionResult .Empty (code, cursor)) {
415
- completer.complete(compiler, compilerState, code, executionCounter++ , cursor)
408
+ // val preprocessed = preprocessCode(code)
409
+ completer.complete(compiler, compilerConfiguration, code, executionCounter++ , cursor)
416
410
}
417
411
418
412
private val listErrorsQueue = LockQueue <ListErrorsResult , ListErrorsArgs >()
419
413
override suspend fun listErrors (code : String , callback : (ListErrorsResult ) -> Unit ) = doWithLock(ListErrorsArgs (code, callback), listErrorsQueue, ListErrorsResult (code)) {
420
- val codeLine = ReplCodeLine (executionCounter++ , 0 , code)
421
- val errorsList = compiler.listErrors(compilerState, codeLine)
422
- ListErrorsResult (code, errorsList)
414
+ // val preprocessed = preprocessCode(code)
415
+ val codeLine = SourceCodeImpl (executionCounter++ , code)
416
+ val errorsList = compiler.analyze(codeLine, 0 , compilerConfiguration)
417
+ ListErrorsResult (code, errorsList.valueOrThrow())
423
418
}
424
419
425
420
private fun <T , Args : LockQueueArgs <T >> doWithLock (args : Args , queue : LockQueue <T , Args >, default : T , action : (Args ) -> T ) {
@@ -467,29 +462,31 @@ class ReplForJupyterImpl(val scriptClasspath: List<File> = emptyList(),
467
462
if (executedCodeLogging == ExecutedCodeLogging .All )
468
463
println (code)
469
464
val id = executionCounter++
470
- val codeLine = ReplCodeLine (id, 0 , code)
471
- when (val compileResult = compiler.compile(compilerState, codeLine)) {
472
- is ReplCompileResult .CompiledClasses -> {
473
- classWriter?.writeClasses(compileResult)
474
- val scriptArgs = ScriptArgsWithTypes (arrayOf(this ), arrayOf(KotlinKernelHost ::class ))
475
- val result = evaluator.eval(evaluatorState, compileResult, scriptArgs)
465
+ val codeLine = SourceCodeImpl (id, code)
466
+ when (val compileResultWithDiagnostics = compiler.compile(codeLine, compilerConfiguration)) {
467
+ is ResultWithDiagnostics .Success -> {
468
+ val compileResult = compileResultWithDiagnostics.value
469
+ classWriter?.writeClasses(compileResult())
470
+ val repl = this
471
+ val currentEvalConfig = ScriptEvaluationConfiguration (evaluatorConfiguration) {
472
+ constructorArgs.invoke(repl as KotlinKernelHost )
473
+ }
474
+ val result = evaluator.eval(compileResult, currentEvalConfig).valueOrThrow()
476
475
contextUpdater.update()
477
- return when (result) {
478
- is ReplEvalResult .Error .CompileTime -> throw ReplCompilerException (result)
479
- is ReplEvalResult .Error .Runtime -> throw ReplEvalRuntimeException (result)
480
- is ReplEvalResult .Incomplete -> throw ReplCompilerException (result)
481
- is ReplEvalResult .HistoryMismatch -> throw ReplCompilerException (result)
482
- is ReplEvalResult .UnitResult -> {
476
+
477
+ val pureResult = result()
478
+ return when {
479
+ pureResult.isErrorResult -> throw ReplEvalRuntimeException (pureResult.error?.message.orEmpty(), pureResult.error)
480
+ pureResult.isUnitResult -> {
483
481
InternalEvalResult (Unit , id)
484
482
}
485
- is ReplEvalResult . ValueResult -> {
486
- InternalEvalResult (result.value , id)
483
+ pureResult.isValueResult -> {
484
+ InternalEvalResult (pureResult.result , id)
487
485
}
488
486
else -> throw IllegalStateException (" Unknown eval result type ${this } " )
489
487
}
490
488
}
491
- is ReplCompileResult .Error -> throw ReplCompilerException (compileResult)
492
- is ReplCompileResult .Incomplete -> throw ReplCompilerException (compileResult)
489
+ is ResultWithDiagnostics .Failure -> throw ReplCompilerException (compileResultWithDiagnostics)
493
490
}
494
491
}
495
492
0 commit comments