diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptEvaluation.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptEvaluation.kt index c1449428c13..8a90984bb9e 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptEvaluation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptEvaluation.kt @@ -142,20 +142,20 @@ sealed class ResultValue(val scriptClass: KClass<*>? = null, val scriptInstance: * @param value actual result value * @param type name of the result type * @param scriptClass the loaded class of the script - * @param scriptInstance instance of the script class + * @param scriptInstance instance of the script class. Should be nullable since on some platforms (e.g. JS) there is no actual instance */ - class Value(val name: String, val value: Any?, val type: String, scriptClass: KClass<*>, scriptInstance: Any) : + class Value(val name: String, val value: Any?, val type: String, scriptClass: KClass<*>?, scriptInstance: Any?) : ResultValue(scriptClass, scriptInstance) { override fun toString(): String = "$name: $type = $value" } /** - * The result value representing unit result, e.g. when the script ends with a statement + * The result value representing unit result, e.g. when the script ends with a statement. * @param scriptClass the loaded class of the script - * @param scriptInstance instance of the script class + * @param scriptInstance instance of the script class. Please note it's nullable for symmetry with `Value` */ - class Unit(scriptClass: KClass<*>, scriptInstance: Any) : ResultValue(scriptClass, scriptInstance) { + class Unit(scriptClass: KClass<*>, scriptInstance: Any?) : ResultValue(scriptClass, scriptInstance) { override fun toString(): String = "Unit" } diff --git a/libraries/scripting/js/build.gradle.kts b/libraries/scripting/js/build.gradle.kts new file mode 100644 index 00000000000..43985e52d2c --- /dev/null +++ b/libraries/scripting/js/build.gradle.kts @@ -0,0 +1,22 @@ + +plugins { + kotlin("jvm") +} + +jvmTarget = "1.6" + +dependencies { + compile(project(":kotlin-scripting-common")) + compile(project(":compiler:cli-common")) + compile(project(":js:js.engines")) + compile(intellijCoreDep()) { includeJars("intellij-core") } +} + +sourceSets { + "main" { projectDefault() } + "test" { } +} + +publish() + +standardPublicJars() diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt new file mode 100644 index 00000000000..3e8f906a891 --- /dev/null +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplEvaluator.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.scripting.repl.js + +import org.jetbrains.kotlin.cli.common.repl.* +import org.jetbrains.kotlin.js.engine.ScriptEngineNashorn +import java.util.concurrent.locks.ReentrantReadWriteLock + +class JsReplEvaluator : ReplEvaluator { + //TODO: support println() + private val engine = ScriptEngineNashorn() + + override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = JsState(lock) + + override fun eval( + state: IReplStageState<*>, + compileResult: ReplCompileResult.CompiledClasses, + scriptArgs: ScriptArgsWithTypes?, + invokeWrapper: InvokeWrapper? + ): ReplEvalResult { + return try { + val evalResult = engine.eval(compileResult.data as String) + ReplEvalResult.ValueResult("result", evalResult, "Any?") + } catch (e: Exception) { + ReplEvalResult.Error.Runtime("Error while evaluating", e) + } + } +} diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt new file mode 100644 index 00000000000..c89f4fb9b29 --- /dev/null +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsReplUtils.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.scripting.repl.js + +import org.jetbrains.kotlin.cli.common.repl.* +import org.jetbrains.kotlin.descriptors.ScriptDescriptor +import java.util.concurrent.locks.ReentrantReadWriteLock +import kotlin.reflect.KClass +import kotlin.script.experimental.api.CompiledScript +import kotlin.script.experimental.api.ResultWithDiagnostics +import kotlin.script.experimental.api.ScriptCompilationConfiguration +import kotlin.script.experimental.api.ScriptEvaluationConfiguration + +class JsState(override val lock: ReentrantReadWriteLock) : IReplStageState { + override val history: IReplStageHistory + get() = TODO("not implemented") + + override val currentGeneration: Int + get() = TODO("not implemented") + +} + +class CompiledToJsScript( + val jsCode: String, + override val compilationConfiguration: ScriptCompilationConfiguration +) : CompiledScript { + override suspend fun getClass(scriptEvaluationConfiguration: ScriptEvaluationConfiguration?): ResultWithDiagnostics> { + throw IllegalStateException("Class is not available for JS implementation") + } +} diff --git a/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt new file mode 100644 index 00000000000..f20764f8686 --- /dev/null +++ b/libraries/scripting/js/src/org/jetbrains/kotlin/scripting/repl/js/JsScriptEvaluator.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.scripting.repl.js + +import org.jetbrains.kotlin.js.engine.ScriptEngineNashorn +import kotlin.script.experimental.api.* + +class JsScriptEvaluator : ScriptEvaluator { + //TODO: support println() + private val engine = ScriptEngineNashorn() + + override suspend fun invoke( + compiledScript: CompiledScript<*>, + scriptEvaluationConfiguration: ScriptEvaluationConfiguration + ): ResultWithDiagnostics { + return try { + val evalResult = engine.eval((compiledScript as CompiledToJsScript).jsCode) + ResultWithDiagnostics.Success( + EvaluationResult( + ResultValue.Value( + name = "result", + value = evalResult, + type = "Any?", + scriptClass = null, + scriptInstance = null + ), + scriptEvaluationConfiguration + ) + ) + } catch (e: Exception) { + ResultWithDiagnostics.Failure( + ScriptDiagnostic( + message = e.localizedMessage, + severity = ScriptDiagnostic.Severity.ERROR, + exception = e + ) + ) + } + } +}