Skip to content

Commit 24f7a60

Browse files
authoredDec 29, 2016
Merge pull request #5 from apatrida/master
Move to latest 1.1-M04 and kotlin-script-util to lower code in this kernel
2 parents 31fc5ff + e115bb5 commit 24f7a60

File tree

10 files changed

+139
-380
lines changed

10 files changed

+139
-380
lines changed
 

‎build.gradle

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
buildscript {
33
ext.shadowJarVersion = "1.2.3"
4-
ext.kotlinVersion = '1.1.0-dev-1920'
4+
ext.kotlinVersion = '1.1-M04'
55
repositories {
66
maven { url 'https://dl.bintray.com/kotlin/kotlin-dev' }
77
maven { url 'https://repo.gradle.org/gradle/repo' }
@@ -43,6 +43,7 @@ configurations {
4343
dependencies {
4444
compile project(':jupyter-lib')
4545
compile "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlinVersion"
46+
compile "org.jetbrains.kotlin:kotlin-script-util:$kotlinVersion"
4647
compile 'org.slf4j:slf4j-api:1.7.21'
4748
compile 'org.zeromq:jeromq:0.3.5'
4849
compile 'com.beust:klaxon:0.24'

‎jupyter-lib/src/main/kotlin/jupyter/kotlin/dependencies.kt

-12
This file was deleted.

‎jupyter-lib/src/main/kotlin/jupyter/kotlin/script.kt

-26
This file was deleted.

‎src/main/kotlin/org/jetbrains/kotlin/jupyter/display.kt

+52-6
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,65 @@ package org.jetbrains.kotlin.jupyter
22

33
import jupyter.kotlin.Result
44
import jupyter.kotlin.textResult
5+
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
6+
import java.io.ByteArrayOutputStream
7+
import java.io.OutputStream
8+
import java.io.PrintStream
59

6-
val ReplForJupyter.EvalResult.asResult: Result get() = when (this) {
7-
is ReplForJupyter.EvalResult.ValueResult -> {
8-
if (value is Result) value
10+
val ReplEvalResult.asResult: Result get() = when (this) {
11+
is ReplEvalResult.ValueResult -> {
12+
if (value is Result) value as Result
913
else textResult(
1014
try {
1115
value.toString()
1216
} catch (e: Exception) {
1317
"Unable to convert result to string: $e"
1418
})
1519
}
16-
is ReplForJupyter.EvalResult.UnitResult -> textResult("Ok")
17-
is ReplForJupyter.EvalResult.Error -> textResult(errorText)
18-
is ReplForJupyter.EvalResult.Incomplete -> textResult("error: incomplete code")
20+
is ReplEvalResult.UnitResult -> textResult("Ok")
21+
is ReplEvalResult.Error -> textResult(message)
22+
is ReplEvalResult.Incomplete -> textResult("error: incomplete code")
1923
else -> throw Exception("Unexpected result from eval call: $this")
2024
}
25+
26+
class ForkingOutputStream(val stdout: PrintStream, val publish: PrintStream, val captureOutput: Boolean) : OutputStream() {
27+
val capturedOutput = ByteArrayOutputStream()
28+
29+
override fun write(b: Int) {
30+
stdout.write(b)
31+
publish.write(b)
32+
if (captureOutput) capturedOutput.write(b)
33+
}
34+
}
35+
36+
fun JupyterConnection.evalWithIO(body: () -> ReplEvalResult): ReplEvalResult {
37+
val out = System.out
38+
val err = System.err
39+
40+
// TODO: make configuration option of whether to pipe back stdout and stderr
41+
// TODO: make a configuration option to limit the total stdout / stderr possibly returned (in case it goes wild...)
42+
val forkedOut = ForkingOutputStream(out, iopubOut, true)
43+
val forkedError = ForkingOutputStream(err, iopubErr, false)
44+
45+
System.setOut(PrintStream(forkedOut, true, "UTF-8"))
46+
System.setErr(PrintStream(forkedError, true, "UTF-8"))
47+
48+
val `in` = System.`in`
49+
System.setIn(stdinIn)
50+
try {
51+
return body().let {
52+
// TODO: make this a configuration option to pass back the stdout as the value if Unit (notebooks do not display the stdout, only console does)
53+
if (it is ReplEvalResult.UnitResult) {
54+
ReplEvalResult.ValueResult(it.updatedHistory, String(forkedOut.capturedOutput.toByteArray()))
55+
} else {
56+
it
57+
}
58+
}
59+
60+
}
61+
finally {
62+
System.setIn(`in`)
63+
System.setErr(err)
64+
System.setOut(out)
65+
}
66+
}

‎src/main/kotlin/org/jetbrains/kotlin/jupyter/ikotlin.kt

+10-8
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import com.beust.klaxon.JsonObject
55
import com.beust.klaxon.Parser
66
import com.beust.klaxon.int
77
import com.beust.klaxon.string
8-
import org.jetbrains.kotlin.cli.common.KotlinVersion
8+
import org.jetbrains.kotlin.cli.common.repl.ReplCheckResult
9+
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
10+
import org.jetbrains.kotlin.config.KotlinCompilerVersion
911
import java.io.File
1012
import java.util.concurrent.atomic.AtomicLong
1113
import kotlin.concurrent.thread
@@ -111,7 +113,7 @@ fun JupyterConnection.Socket.shellMessagesHandler(msg: Message, repl: ReplForJup
111113
content = jsonObject(
112114
"protocol_version" to protocolVersion,
113115
"language" to "Kotlin",
114-
"language_version" to KotlinVersion.VERSION,
116+
"language_version" to KotlinCompilerVersion.VERSION,
115117
"language_info" to jsonObject("name" to "kotlin", "file_extension" to "kt")
116118
)))
117119
"history_request" ->
@@ -126,7 +128,7 @@ fun JupyterConnection.Socket.shellMessagesHandler(msg: Message, repl: ReplForJup
126128
"connect_request" ->
127129
send(makeReplyMessage(msg, "connection_reply",
128130
content = jsonObject(JupyterSockets.values()
129-
.map { Pair("${it.name}_port", connection.config.ports[it.ordinal]) })))
131+
.map { Pair("${it.name}_port", connection.config.ports[it.ordinal]) })))
130132
"execute_request" -> {
131133
connection.contextMessage = msg
132134
val count = executionCount.getAndIncrement()
@@ -138,7 +140,7 @@ fun JupyterConnection.Socket.shellMessagesHandler(msg: Message, repl: ReplForJup
138140
"execution_count" to count,
139141
"code" to code)))
140142
val res = if (isCommand(code.toString())) runCommand(code.toString(), repl)
141-
else (repl?.eval(count, code.toString()) ?: ReplForJupyter.EvalResult.Error.Runtime("no repl!")).asResult
143+
else (connection.evalWithIO { repl?.eval(count, code.toString()) ?: ReplEvalResult.Error.Runtime(emptyList(), "no repl!") }).asResult
142144
send(makeReplyMessage(msg, "execute_result", content = jsonObject(
143145
"execution_count" to count,
144146
"data" to res,
@@ -157,17 +159,17 @@ fun JupyterConnection.Socket.shellMessagesHandler(msg: Message, repl: ReplForJup
157159
"user_variables" to JsonObject(),
158160
"payload" to listOf<String>(),
159161
"user_expressions" to JsonObject())
160-
))
162+
))
161163
connection.contextMessage = null
162164
}
163165
"is_complete_request" -> {
164166
val code = msg.content["code"].toString()
165167
val resStr = if (isCommand(code)) "complete" else {
166168
val res = repl?.checkComplete(executionCount.get(), code)
167169
when (res) {
168-
is ReplForJupyter.EvalResult.Error -> "invalid"
169-
is ReplForJupyter.EvalResult.Incomplete -> "incomplete"
170-
is ReplForJupyter.EvalResult.Ready -> "complete"
170+
is ReplCheckResult.Error -> "invalid"
171+
is ReplCheckResult.Incomplete -> "incomplete"
172+
is ReplCheckResult.Ok -> "complete"
171173
null -> "error: no repl"
172174
else -> throw Exception("unexpected result from checkComplete call: $res")
173175
}

0 commit comments

Comments
 (0)
Please sign in to comment.