Add new experimental scripting API
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("unused")
|
||||
|
||||
package kotlin.script.experimental.host
|
||||
|
||||
import kotlinx.coroutines.experimental.CoroutineScope
|
||||
import kotlinx.coroutines.experimental.runBlocking
|
||||
import kotlin.script.experimental.api.*
|
||||
|
||||
abstract class BasicScriptingHost<ScriptBase : Any>(
|
||||
val configurator: ScriptConfigurator,
|
||||
val compiler: ScriptCompiler,
|
||||
val runner: ScriptRunner<ScriptBase>
|
||||
) {
|
||||
open fun <T> runInCoroutineContext(block: suspend CoroutineScope.() -> T): T = runBlocking { block() }
|
||||
|
||||
open fun eval(configuration: ScriptCompileConfiguration, environment: ScriptEvaluationEnvironment): ResultWithDiagnostics<EvaluationResult> =
|
||||
runInCoroutineContext {
|
||||
val compiled = compiler.compile(configuration, configurator)
|
||||
when (compiled) {
|
||||
is ResultWithDiagnostics.Failure -> compiled
|
||||
is ResultWithDiagnostics.Success -> {
|
||||
val compiledScript = compiled.value!! as CompiledScript<ScriptBase>
|
||||
runner.run(compiledScript, environment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package kotlin.script.experimental.host
|
||||
|
||||
import kotlin.script.experimental.api.ScriptSource
|
||||
import kotlin.script.experimental.api.ScriptSourceFragments
|
||||
import kotlin.script.experimental.api.ScriptSourceNamedFragment
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
||||
fun ScriptSourceFragments.isWholeFile(): Boolean = fragments?.isEmpty() ?: true
|
||||
|
||||
fun ScriptSource.getScriptText(): String = when {
|
||||
text != null -> text!!
|
||||
location != null ->
|
||||
location!!.openStream().bufferedReader().readText()
|
||||
else -> throw RuntimeException("unable to get text from null script")
|
||||
}
|
||||
|
||||
fun ScriptSourceFragments.getMergedScriptText(): String {
|
||||
val originalScriptText = originalSource.getScriptText()
|
||||
return if (isWholeFile()) {
|
||||
originalScriptText
|
||||
} else {
|
||||
val sb = StringBuilder(originalScriptText.length)
|
||||
var prevFragment: ScriptSourceNamedFragment? = null
|
||||
for (fragment in fragments!!) {
|
||||
val fragmentStartPos = fragment.range.start.absolutePos
|
||||
val fragmentEndPos = fragment.range.end.absolutePos
|
||||
if (fragmentStartPos == null || fragmentEndPos == null)
|
||||
throw RuntimeException("Script fragments require absolute positions (received: $fragment)")
|
||||
val curPos = if (prevFragment == null) 0 else prevFragment.range.end.absolutePos!!
|
||||
if (prevFragment != null && prevFragment.range.end.absolutePos!! > fragmentStartPos) throw RuntimeException("Unsorted or overlapping fragments: previous: $prevFragment, current: $fragment")
|
||||
if (curPos < fragmentStartPos) {
|
||||
sb.append(
|
||||
originalScriptText.subSequence(
|
||||
curPos,
|
||||
fragmentStartPos
|
||||
).map { if (it == '\r' || it == '\n') it else ' ' }) // preserving lines layout
|
||||
}
|
||||
sb.append(originalScriptText.subSequence(fragmentStartPos, fragmentEndPos))
|
||||
prevFragment = fragment
|
||||
}
|
||||
sb.toString()
|
||||
}
|
||||
}
|
||||
|
||||
open class FileScriptSource(val file: File) : ScriptSource {
|
||||
override val location: URL? get() = file.toURI().toURL()
|
||||
override val text: String? get() = null
|
||||
}
|
||||
|
||||
fun File.toScriptSource(): ScriptSource = FileScriptSource(this)
|
||||
|
||||
open class StringScriptSource(val source: String) : ScriptSource {
|
||||
override val location: URL? get() = null
|
||||
override val text: String? get() = source
|
||||
}
|
||||
|
||||
fun String.toScriptSource(): ScriptSource = StringScriptSource(this)
|
||||
Reference in New Issue
Block a user