Grand refactoring of the scripting DSL + many minor usability refactorings around it
This commit is contained in:
@@ -75,7 +75,6 @@ dependencies {
|
|||||||
testCompile(project(":compiler:ir.ir2cfg"))
|
testCompile(project(":compiler:ir.ir2cfg"))
|
||||||
testCompile(project(":compiler:ir.tree")) // used for deepCopyWithSymbols call that is removed by proguard from the compiler TODO: make it more straightforward
|
testCompile(project(":compiler:ir.tree")) // used for deepCopyWithSymbols call that is removed by proguard from the compiler TODO: make it more straightforward
|
||||||
testCompile(project(":kotlin-scripting-compiler"))
|
testCompile(project(":kotlin-scripting-compiler"))
|
||||||
testCompile(project(":kotlin-scripting-misc"))
|
|
||||||
testCompile(project(":kotlin-script-util"))
|
testCompile(project(":kotlin-script-util"))
|
||||||
testCompileOnly(projectRuntimeJar(":kotlin-daemon-client"))
|
testCompileOnly(projectRuntimeJar(":kotlin-daemon-client"))
|
||||||
testCompileOnly(project(":kotlin-reflect-api"))
|
testCompileOnly(project(":kotlin-reflect-api"))
|
||||||
|
|||||||
@@ -244,9 +244,9 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
|||||||
with(PathUtil) {
|
with(PathUtil) {
|
||||||
val jars = arrayOf(
|
val jars = arrayOf(
|
||||||
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
||||||
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
|
KOTLIN_SCRIPTING_JVM_JAR
|
||||||
).mapNotNull { File(libPath, it).takeIf(File::exists)?.canonicalPath }
|
).mapNotNull { File(libPath, it).takeIf { it.exists() }?.canonicalPath }
|
||||||
if (jars.size == 4) {
|
if (jars.size == 3) {
|
||||||
pluginClasspaths = jars + pluginClasspaths
|
pluginClasspaths = jars + pluginClasspaths
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ import org.jetbrains.kotlin.utils.PathUtil
|
|||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMMON_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMMON_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_JVM_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_JVM_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_MISC_JAR
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.script.experimental.annotations.KotlinScript
|
import kotlin.script.experimental.annotations.KotlinScript
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
import kotlin.script.experimental.api.ScriptDefinition
|
||||||
import kotlin.script.experimental.api.KotlinType
|
import kotlin.script.experimental.api.contextVariables
|
||||||
import kotlin.script.experimental.api.ScriptDefinitionProperties
|
import kotlin.script.experimental.api.scriptImplicitReceivers
|
||||||
import kotlin.script.experimental.util.TypedKey
|
|
||||||
|
|
||||||
abstract class AbstractCustomScriptCodegenTest : CodegenTestCase() {
|
abstract class AbstractCustomScriptCodegenTest : CodegenTestCase() {
|
||||||
private lateinit var scriptDefinitions: List<String>
|
private lateinit var scriptDefinitions: List<String>
|
||||||
@@ -59,7 +57,7 @@ abstract class AbstractCustomScriptCodegenTest : CodegenTestCase() {
|
|||||||
with(PathUtil.kotlinPathsForDistDirectory) {
|
with(PathUtil.kotlinPathsForDistDirectory) {
|
||||||
arrayOf(
|
arrayOf(
|
||||||
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
||||||
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
|
KOTLIN_SCRIPTING_JVM_JAR
|
||||||
).mapNotNull { File(libPath, it).takeIf { it.exists() } }
|
).mapNotNull { File(libPath, it).takeIf { it.exists() } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,24 +121,22 @@ abstract class AbstractCustomScriptCodegenTest : CodegenTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object TestScriptWithReceiversConfiguration : ArrayList<Pair<TypedKey<*>, Any?>>(
|
object TestScriptWithReceiversConfiguration : ScriptDefinition {
|
||||||
listOf(
|
override val properties = properties {
|
||||||
ScriptDefinitionProperties.scriptImplicitReceivers to listOf(KotlinType(String::class))
|
scriptImplicitReceivers<String>()
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@KotlinScript
|
@KotlinScript(definition = TestScriptWithReceiversConfiguration::class)
|
||||||
@KotlinScriptPropertiesFromList(TestScriptWithReceiversConfiguration::class)
|
|
||||||
abstract class TestScriptWithReceivers
|
abstract class TestScriptWithReceivers
|
||||||
|
|
||||||
object TestScriptWithSimpleEnvVarsConfiguration : ArrayList<Pair<TypedKey<*>, Any?>>(
|
object TestScriptWithSimpleEnvVarsConfiguration : ScriptDefinition {
|
||||||
listOf(
|
override val properties = properties {
|
||||||
ScriptDefinitionProperties.contextVariables to mapOf("stringVar1" to KotlinType(String::class))
|
contextVariables("stringVar1" to String::class)
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@KotlinScript
|
@KotlinScript(definition = TestScriptWithSimpleEnvVarsConfiguration::class)
|
||||||
@KotlinScriptPropertiesFromList(TestScriptWithSimpleEnvVarsConfiguration::class)
|
|
||||||
abstract class TestScriptWithSimpleEnvVars
|
abstract class TestScriptWithSimpleEnvVars
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.utils.PathUtil
|
|||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMMON_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMMON_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_JVM_JAR
|
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_JVM_JAR
|
||||||
import org.jetbrains.kotlin.utils.PathUtil.KOTLIN_SCRIPTING_MISC_JAR
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.annotations.KotlinScript
|
import kotlin.script.experimental.annotations.KotlinScript
|
||||||
@@ -50,7 +49,7 @@ class CustomScriptCodegenTest : CodegenTestCase() {
|
|||||||
with(PathUtil.kotlinPathsForDistDirectory) {
|
with(PathUtil.kotlinPathsForDistDirectory) {
|
||||||
arrayOf(
|
arrayOf(
|
||||||
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
|
||||||
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
|
KOTLIN_SCRIPTING_JVM_JAR
|
||||||
).mapNotNull { File(libPath, it).also { assertTrue("$it not found", it.exists()) } }
|
).mapNotNull { File(libPath, it).also { assertTrue("$it not found", it.exists()) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ object PathUtil {
|
|||||||
const val KOTLIN_JAVA_SCRIPT_RUNTIME_JAR = "kotlin-script-runtime.jar"
|
const val KOTLIN_JAVA_SCRIPT_RUNTIME_JAR = "kotlin-script-runtime.jar"
|
||||||
const val KOTLIN_SCRIPTING_COMMON_JAR = "kotlin-scripting-common.jar"
|
const val KOTLIN_SCRIPTING_COMMON_JAR = "kotlin-scripting-common.jar"
|
||||||
const val KOTLIN_SCRIPTING_JVM_JAR = "kotlin-scripting-jvm.jar"
|
const val KOTLIN_SCRIPTING_JVM_JAR = "kotlin-scripting-jvm.jar"
|
||||||
const val KOTLIN_SCRIPTING_MISC_JAR = "kotlin-scripting-misc.jar"
|
|
||||||
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME = "kotlin-scripting-compiler"
|
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME = "kotlin-scripting-compiler"
|
||||||
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR = "$KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME.jar"
|
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR = "$KOTLIN_SCRIPTING_COMPILER_PLUGIN_NAME.jar"
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -50,7 +50,7 @@ import kotlin.script.dependencies.Environment
|
|||||||
import kotlin.script.dependencies.ScriptContents
|
import kotlin.script.dependencies.ScriptContents
|
||||||
import kotlin.script.experimental.api.KotlinType
|
import kotlin.script.experimental.api.KotlinType
|
||||||
import kotlin.script.experimental.api.ScriptingEnvironment
|
import kotlin.script.experimental.api.ScriptingEnvironment
|
||||||
import kotlin.script.experimental.api.ScriptingEnvironmentProperties
|
import kotlin.script.experimental.api.configurationDependencies
|
||||||
import kotlin.script.experimental.definitions.createScriptDefinitionFromAnnotatedBaseClass
|
import kotlin.script.experimental.definitions.createScriptDefinitionFromAnnotatedBaseClass
|
||||||
import kotlin.script.experimental.dependencies.DependenciesResolver
|
import kotlin.script.experimental.dependencies.DependenciesResolver
|
||||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||||
@@ -208,10 +208,10 @@ fun loadDefinitionsFromTemplates(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
template.annotations.firstIsInstanceOrNull<kotlin.script.experimental.annotations.KotlinScript>() != null -> {
|
template.annotations.firstIsInstanceOrNull<kotlin.script.experimental.annotations.KotlinScript>() != null -> {
|
||||||
val hostEnvironment = ScriptingEnvironment(
|
val hostEnvironment = ScriptingEnvironment.create {
|
||||||
defaultJvmScriptingEnvironment,
|
include(defaultJvmScriptingEnvironment)
|
||||||
ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath))
|
configurationDependencies(JvmDependency(classpath))
|
||||||
)
|
}
|
||||||
KotlinScriptDefinitionAdapterFromNewAPI(
|
KotlinScriptDefinitionAdapterFromNewAPI(
|
||||||
createScriptDefinitionFromAnnotatedBaseClass(KotlinType(template), hostEnvironment, KotlinScriptDefinition::class),
|
createScriptDefinitionFromAnnotatedBaseClass(KotlinType(template), hostEnvironment, KotlinScriptDefinition::class),
|
||||||
hostEnvironment
|
hostEnvironment
|
||||||
|
|||||||
+1
-5
@@ -9,17 +9,13 @@ import org.jetbrains.kotlin.script.examples.jvm.resolve.maven.MyScriptWithMavenD
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.script.experimental.api.EvaluationResult
|
import kotlin.script.experimental.api.EvaluationResult
|
||||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||||
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
|
||||||
import kotlin.script.experimental.api.ScriptEvaluationEnvironment
|
|
||||||
import kotlin.script.experimental.host.toScriptSource
|
import kotlin.script.experimental.host.toScriptSource
|
||||||
import kotlin.script.experimental.jvmhost.makeBasicHostFromAnnotatedScriptBaseClass
|
import kotlin.script.experimental.jvmhost.makeBasicHostFromAnnotatedScriptBaseClass
|
||||||
|
|
||||||
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
|
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
|
||||||
val host = makeBasicHostFromAnnotatedScriptBaseClass<MyScriptWithMavenDeps>()
|
val host = makeBasicHostFromAnnotatedScriptBaseClass<MyScriptWithMavenDeps>()
|
||||||
|
|
||||||
return host.eval(
|
return host.eval(scriptFile.toScriptSource(), null, null)
|
||||||
scriptFile.toScriptSource(), ScriptCompileConfiguration(), ScriptEvaluationEnvironment()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(vararg args: String) {
|
fun main(vararg args: String) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ plugins {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile(project(":kotlin-scripting-jvm"))
|
compile(project(":kotlin-scripting-jvm"))
|
||||||
compile(project(":kotlin-scripting-misc"))
|
|
||||||
compile(project(":kotlin-script-util"))
|
compile(project(":kotlin-script-util"))
|
||||||
runtime("com.jcabi:jcabi-aether:0.10.1")
|
runtime("com.jcabi:jcabi-aether:0.10.1")
|
||||||
runtime("org.sonatype.aether:aether-api:1.13.1")
|
runtime("org.sonatype.aether:aether-api:1.13.1")
|
||||||
|
|||||||
+25
-24
@@ -16,34 +16,35 @@ import kotlin.script.experimental.api.*
|
|||||||
import kotlin.script.experimental.jvm.JvmDependency
|
import kotlin.script.experimental.jvm.JvmDependency
|
||||||
import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity
|
import kotlin.script.experimental.jvm.compat.mapLegacyDiagnosticSeverity
|
||||||
import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition
|
import kotlin.script.experimental.jvm.compat.mapLegacyScriptPosition
|
||||||
import kotlin.script.experimental.jvm.jvmDependenciesFromCurrentContext
|
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
|
||||||
import kotlin.script.experimental.misc.invoke
|
import kotlin.script.experimental.jvm.jvm
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
@KotlinScript(
|
@KotlinScript(
|
||||||
extension = "scriptwithdeps.kts",
|
extension = "scriptwithdeps.kts",
|
||||||
properties = MyScriptProperties::class
|
definition = MyScriptDefinition::class
|
||||||
)
|
)
|
||||||
abstract class MyScriptWithMavenDeps {
|
abstract class MyScriptWithMavenDeps {
|
||||||
// abstract fun body(vararg args: String): Int
|
// abstract fun body(vararg args: String): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyScriptProperties : ScriptingProperties() {
|
object MyScriptDefinition : ScriptDefinition {
|
||||||
override fun setup() {
|
override val properties = properties {
|
||||||
scriptDefinition {
|
defaultImports<DependsOn>()
|
||||||
defaultImports<DependsOn>()
|
defaultImports(Repository::class)
|
||||||
defaultImports(Repository::class)
|
jvm {
|
||||||
jvmDependenciesFromCurrentContext(
|
dependenciesFromCurrentContext(
|
||||||
"scripting-jvm-maven-deps", // script library jar name
|
"scripting-jvm-maven-deps", // script library jar name
|
||||||
"kotlin-script-util" // DependsOn annotation is taken from script-util
|
"kotlin-script-util" // DependsOn annotation is taken from script-util
|
||||||
)
|
)
|
||||||
// variant: dependencies(collectDependenciesFromCurrentContext(...
|
}
|
||||||
refineConfiguration {
|
// variant: dependencies(collectDependenciesFromCurrentContext(...
|
||||||
|
refineConfiguration {
|
||||||
// variant ^: dynamicConfiguration
|
// variant ^: dynamicConfiguration
|
||||||
handler(MyConfigurator())
|
handler(MyConfigurator())
|
||||||
triggerOnAnnotations(DependsOn::class, Repository::class)
|
triggerOnAnnotations(DependsOn::class, Repository::class)
|
||||||
// variants: onAnnotations, refineOnAnnotations (esp. for dynamicConfiguration), updateOnAnnotations
|
// variants: onAnnotations, refineOnAnnotations (esp. for dynamicConfiguration), updateOnAnnotations
|
||||||
// other triggers: beforeParsing, onSections
|
// other triggers: beforeParsing, onSections
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,10 +55,11 @@ class MyConfigurator : RefineScriptCompilationConfigurationHandler {
|
|||||||
|
|
||||||
override suspend operator fun invoke(
|
override suspend operator fun invoke(
|
||||||
scriptSource: ScriptSource,
|
scriptSource: ScriptSource,
|
||||||
configuration: ScriptCompileConfiguration,
|
scriptDefinition: ScriptDefinition,
|
||||||
processedScriptData: ProcessedScriptData
|
configuration: ScriptCompileConfiguration?,
|
||||||
): ResultWithDiagnostics<ScriptCompileConfiguration> {
|
processedScriptData: ProcessedScriptData?
|
||||||
val annotations = processedScriptData.getOrNull(ProcessedScriptDataProperties.foundAnnotations)?.takeIf { it.isNotEmpty() }
|
): ResultWithDiagnostics<ScriptCompileConfiguration?> {
|
||||||
|
val annotations = processedScriptData?.getOrNull(ProcessedScriptData.foundAnnotations)?.takeIf { it.isNotEmpty() }
|
||||||
?: return configuration.asSuccess()
|
?: return configuration.asSuccess()
|
||||||
val scriptContents = object : ScriptContents {
|
val scriptContents = object : ScriptContents {
|
||||||
override val annotations: Iterable<Annotation> = annotations
|
override val annotations: Iterable<Annotation> = annotations
|
||||||
@@ -73,10 +75,9 @@ class MyConfigurator : RefineScriptCompilationConfigurationHandler {
|
|||||||
?: return configuration.asSuccess(diagnostics)
|
?: return configuration.asSuccess(diagnostics)
|
||||||
val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() }
|
val resolvedClasspath = newDepsFromResolver.classpath.toList().takeIf { it.isNotEmpty() }
|
||||||
?: return configuration.asSuccess(diagnostics)
|
?: return configuration.asSuccess(diagnostics)
|
||||||
val newDependency = JvmDependency(resolvedClasspath)
|
ScriptCompileConfiguration.create {
|
||||||
val updatedDeps =
|
dependencies(JvmDependency(resolvedClasspath))
|
||||||
configuration.getOrNull(ScriptDefinitionProperties.dependencies)?.plus(newDependency) ?: listOf(newDependency)
|
}.asSuccess(diagnostics)
|
||||||
ScriptCompileConfiguration(configuration, ScriptDefinitionProperties.dependencies(updatedDeps)).asSuccess(diagnostics)
|
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics())
|
ResultWithDiagnostics.Failure(*diagnostics.toTypedArray(), e.asDiagnostics())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ plugins {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile(project(":examples:scripting-jvm-simple-script"))
|
compile(project(":examples:scripting-jvm-simple-script"))
|
||||||
compile(project(":kotlin-scripting-jvm-host"))
|
compile(project(":kotlin-scripting-jvm-host"))
|
||||||
compile(project(":kotlin-scripting-misc"))
|
|
||||||
compile(project(":kotlin-script-util"))
|
compile(project(":kotlin-script-util"))
|
||||||
runtime(projectRuntimeJar(":kotlin-compiler"))
|
runtime(projectRuntimeJar(":kotlin-compiler"))
|
||||||
testCompile(commonDep("junit"))
|
testCompile(commonDep("junit"))
|
||||||
|
|||||||
+10
-9
@@ -9,24 +9,25 @@ import org.jetbrains.kotlin.script.examples.jvm.simple.MyScript
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.script.experimental.api.EvaluationResult
|
import kotlin.script.experimental.api.EvaluationResult
|
||||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||||
|
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||||
import kotlin.script.experimental.api.ScriptEvaluationEnvironment
|
import kotlin.script.experimental.api.ScriptEvaluationEnvironment
|
||||||
import kotlin.script.experimental.api.buildScriptingProperties
|
|
||||||
import kotlin.script.experimental.host.toScriptSource
|
import kotlin.script.experimental.host.toScriptSource
|
||||||
import kotlin.script.experimental.jvm.jvmDependenciesFromCurrentContext
|
import kotlin.script.experimental.jvm.dependenciesFromCurrentContext
|
||||||
|
import kotlin.script.experimental.jvm.jvm
|
||||||
import kotlin.script.experimental.jvmhost.makeBasicHostFromAnnotatedScriptBaseClass
|
import kotlin.script.experimental.jvmhost.makeBasicHostFromAnnotatedScriptBaseClass
|
||||||
|
|
||||||
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
|
fun evalFile(scriptFile: File): ResultWithDiagnostics<EvaluationResult> {
|
||||||
val additionalCompilationProperties = buildScriptingProperties {
|
val additionalCompilationProperties = ScriptCompileConfiguration.create {
|
||||||
jvmDependenciesFromCurrentContext(
|
jvm {
|
||||||
"scripting-jvm-simple-script" /* script library jar name */
|
dependenciesFromCurrentContext(
|
||||||
)
|
"scripting-jvm-simple-script" /* script library jar name */
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val host = makeBasicHostFromAnnotatedScriptBaseClass<MyScript>()
|
val host = makeBasicHostFromAnnotatedScriptBaseClass<MyScript>()
|
||||||
|
|
||||||
return host.eval(
|
return host.eval(scriptFile.toScriptSource(), additionalCompilationProperties, null)
|
||||||
scriptFile.toScriptSource(), additionalCompilationProperties, ScriptEvaluationEnvironment()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main(vararg args: String) {
|
fun main(vararg args: String) {
|
||||||
|
|||||||
+3
-10
@@ -13,14 +13,14 @@
|
|||||||
package kotlin.script.experimental.annotations
|
package kotlin.script.experimental.annotations
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.api.ScriptingProperties
|
import kotlin.script.experimental.api.ScriptDefinition
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
annotation class KotlinScript(
|
annotation class KotlinScript(
|
||||||
val name: String = "Kotlin script",
|
val name: String = "Kotlin script",
|
||||||
val extension: String = "kts",
|
val extension: String = "kts",
|
||||||
val properties: KClass<out ScriptingProperties> = ScriptingProperties::class // object or class filled in 0-ary constructor
|
val definition: KClass<out ScriptDefinition> = ScriptDefinition.Default::class // object or class filled in 0-ary constructor
|
||||||
)
|
)
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@@ -29,15 +29,8 @@ annotation class KotlinScriptFileExtension(
|
|||||||
val extension: String
|
val extension: String
|
||||||
)
|
)
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
|
||||||
@Deprecated("Use KotlinScriptProperties", replaceWith = ReplaceWith("KotlinScriptProperties"))
|
|
||||||
annotation class KotlinScriptPropertiesFromList(
|
|
||||||
val definitionProperties: KClass<out List<*>> // object or class filled in 0-ary constructor
|
|
||||||
)
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.CLASS)
|
@Target(AnnotationTarget.CLASS)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
annotation class KotlinScriptProperties(
|
annotation class KotlinScriptProperties(
|
||||||
val definitionProperties: KClass<out ScriptingProperties> // object or class filled in 0-ary constructor
|
val definition: KClass<out ScriptDefinition> // object or class filled in 0-ary constructor
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,10 +33,11 @@ sealed class ResultWithDiagnostics<out R> {
|
|||||||
|
|
||||||
// call chaining
|
// call chaining
|
||||||
|
|
||||||
suspend fun <R1, R2> ResultWithDiagnostics<R1>.onSuccess(body: suspend (R1) -> ResultWithDiagnostics<R2>): ResultWithDiagnostics<R2> = when (this) {
|
suspend fun <R1, R2> ResultWithDiagnostics<R1>.onSuccess(body: suspend (R1) -> ResultWithDiagnostics<R2>): ResultWithDiagnostics<R2> =
|
||||||
is ResultWithDiagnostics.Success -> this.reports + body(this.value)
|
when (this) {
|
||||||
is ResultWithDiagnostics.Failure -> this
|
is ResultWithDiagnostics.Success -> this.reports + body(this.value)
|
||||||
}
|
is ResultWithDiagnostics.Failure -> this
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun <R> ResultWithDiagnostics<R>.onFailure(body: suspend (ResultWithDiagnostics<R>) -> Unit): ResultWithDiagnostics<R> {
|
suspend fun <R> ResultWithDiagnostics<R>.onFailure(body: suspend (ResultWithDiagnostics<R>) -> Unit): ResultWithDiagnostics<R> {
|
||||||
if (this is ResultWithDiagnostics.Failure) {
|
if (this is ResultWithDiagnostics.Failure) {
|
||||||
@@ -52,7 +53,7 @@ operator fun <R> List<ScriptDiagnostic>.plus(res: ResultWithDiagnostics<R>): Res
|
|||||||
|
|
||||||
// results creation
|
// results creation
|
||||||
|
|
||||||
fun <R : Any> R.asSuccess(reports: List<ScriptDiagnostic> = listOf()): ResultWithDiagnostics.Success<R> =
|
fun <R> R.asSuccess(reports: List<ScriptDiagnostic> = listOf()): ResultWithDiagnostics.Success<R> =
|
||||||
ResultWithDiagnostics.Success(this, reports)
|
ResultWithDiagnostics.Success(this, reports)
|
||||||
|
|
||||||
fun Throwable.asDiagnostics(customMessage: String? = null, location: ScriptSource.Location? = null): ScriptDiagnostic =
|
fun Throwable.asDiagnostics(customMessage: String? = null, location: ScriptSource.Location? = null): ScriptDiagnostic =
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-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.api
|
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
import kotlin.reflect.KType
|
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
|
||||||
import kotlin.script.experimental.util.TypedKey
|
|
||||||
|
|
||||||
interface PropertiesGroup
|
|
||||||
|
|
||||||
|
|
||||||
open class PropertiesBuilder(val props: ScriptingProperties)
|
|
||||||
|
|
||||||
class PropertiesBuilderDelegate<T: PropertiesBuilder>(val kclass: KClass<T>) {
|
|
||||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): KClass<T> = kclass
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <reified T : PropertiesBuilder> propertiesBuilder() = PropertiesBuilderDelegate(T::class)
|
|
||||||
|
|
||||||
fun buildScriptingProperties(body: ScriptingProperties.() -> Unit): ChainedPropertyBag =
|
|
||||||
ScriptingProperties(body).build()
|
|
||||||
|
|
||||||
open class ScriptingProperties(body: ScriptingProperties.() -> Unit = {}) {
|
|
||||||
|
|
||||||
var parentPropertiesBag: ChainedPropertyBag? = null
|
|
||||||
var parentPropertiesBuilder: ScriptingProperties? = null
|
|
||||||
val data = HashMap<TypedKey<*>, Any?>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
body()
|
|
||||||
setupOnce() // TODO: does it work?
|
|
||||||
}
|
|
||||||
|
|
||||||
private var isSetUp = false
|
|
||||||
fun setupOnce() {
|
|
||||||
if (!isSetUp) setup()
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun setup() {}
|
|
||||||
|
|
||||||
fun build(): ChainedPropertyBag =
|
|
||||||
ChainedPropertyBag.createOptimized(parentPropertiesBag ?: parentPropertiesBuilder?.build(), data)
|
|
||||||
|
|
||||||
// --------------------------
|
|
||||||
// DSL:
|
|
||||||
|
|
||||||
// generic invoke for properties groups, allowing to use syntax:
|
|
||||||
// PropertiesGroup {
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
|
|
||||||
inline operator fun <T : PropertiesGroup> T.invoke(body: T.() -> Unit) = body()
|
|
||||||
|
|
||||||
// generic invoke for properties builder - for extending dsl with complex builders
|
|
||||||
|
|
||||||
inline operator fun <reified T : PropertiesBuilder> KClass<T>.invoke(body: T.() -> Unit) {
|
|
||||||
constructors.first().call(this@ScriptingProperties).body()
|
|
||||||
}
|
|
||||||
|
|
||||||
// chaining:
|
|
||||||
|
|
||||||
private fun chain(propsBag: ChainedPropertyBag?, propsBuilder: ScriptingProperties?, replaceParent: Boolean) {
|
|
||||||
assert(propsBag == null || propsBuilder == null)
|
|
||||||
if (!replaceParent && parentPropertiesBag != null || parentPropertiesBuilder != null)
|
|
||||||
throw RuntimeException("Parent already defined for properties being build: ${parentPropertiesBag ?: parentPropertiesBuilder}")
|
|
||||||
parentPropertiesBag = propsBag
|
|
||||||
parentPropertiesBuilder = propsBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chain(props: ScriptingProperties, replaceParent: Boolean = false) {
|
|
||||||
chain(null, props, replaceParent)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chain(props: ChainedPropertyBag, replaceParent: Boolean = false) {
|
|
||||||
chain(props, null, replaceParent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// inclusion:
|
|
||||||
|
|
||||||
fun include(props: ScriptingProperties) {
|
|
||||||
props.setupOnce()
|
|
||||||
data.putAll(props.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun include(props: ChainedPropertyBag) {
|
|
||||||
data.putAll(props.data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// builders for known property types, allowing to use syntax
|
|
||||||
// propertyKey(value...)
|
|
||||||
// or
|
|
||||||
// propertyKey<Type>()
|
|
||||||
|
|
||||||
// generic:
|
|
||||||
|
|
||||||
inline operator fun <reified T> TypedKey<T>.invoke(v: T) {
|
|
||||||
data[this] = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// for KotlinType:
|
|
||||||
|
|
||||||
inline operator fun <reified K> TypedKey<KotlinType>.invoke() {
|
|
||||||
data[this] = KotlinType(K::class)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(kclass: KClass<*>) {
|
|
||||||
data[this] = KotlinType(kclass)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(ktype: KType) {
|
|
||||||
data[this] = KotlinType(ktype)
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(fqname: String) {
|
|
||||||
data[this] = KotlinType(fqname)
|
|
||||||
}
|
|
||||||
|
|
||||||
// for list of KotlinTypes
|
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_list_from_generic")
|
|
||||||
inline operator fun <reified K> TypedKey<in List<KotlinType>>.invoke() {
|
|
||||||
data.addToListProperty(this, KotlinType(K::class))
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg classes: KClass<*>) {
|
|
||||||
data.addToListProperty(this, classes.map { KotlinType(it) })
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg types: KType) {
|
|
||||||
data.addToListProperty(this, types.map { KotlinType(it) })
|
|
||||||
}
|
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg fqnames: String) {
|
|
||||||
data.addToListProperty(this, fqnames.map { KotlinType(it) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// generic for list
|
|
||||||
|
|
||||||
inline operator fun <reified E> TypedKey<List<E>>.invoke(vararg vs: E) {
|
|
||||||
data.addToListProperty(this, vs.toList())
|
|
||||||
}
|
|
||||||
|
|
||||||
// for map of generic keys to KotlinTypes:
|
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_kclass")
|
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg classes: Pair<K, KClass<*>>) {
|
|
||||||
data.addToMapProperty(this, classes.map { (k, v) -> k to KotlinType(v) })
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_ktype")
|
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg types: Pair<K, KType>) {
|
|
||||||
data.addToMapProperty(this, types.map { (k, v) -> k to KotlinType(v) })
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_fqname")
|
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg fqnames: Pair<K, String>) {
|
|
||||||
data.addToMapProperty(this, fqnames.map { (k, v) -> k to KotlinType(v) })
|
|
||||||
}
|
|
||||||
|
|
||||||
// generic for maps:
|
|
||||||
|
|
||||||
inline operator fun <reified K, reified V> TypedKey<Map<K, V>>.invoke(vararg vs: Pair<K, V>) {
|
|
||||||
data.addToMapProperty(this, vs.asIterable())
|
|
||||||
}
|
|
||||||
|
|
||||||
// for strings and list of strings that could be converted from other types
|
|
||||||
|
|
||||||
@JvmName("invoke_string_fqn_from_generic")
|
|
||||||
inline operator fun <reified K> TypedKey<String>.invoke() {
|
|
||||||
data[this] = K::class.qualifiedName!!
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("invoke_string_fqn_from_reflected_class")
|
|
||||||
operator fun TypedKey<String>.invoke(kclass: KClass<*>) {
|
|
||||||
data[this] = kclass.qualifiedName!!
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("invoke_string_list_fqn_from_generic")
|
|
||||||
inline operator fun <reified K> TypedKey<in List<String>>.invoke() {
|
|
||||||
data.addToListProperty(this, K::class.qualifiedName!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmName("invoke_string_list_fqn_from_reflected_class")
|
|
||||||
operator fun TypedKey<in List<String>>.invoke(vararg kclasses: KClass<*>) {
|
|
||||||
data.addToListProperty(this, kclasses.map { it.qualifiedName!! })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <V> HashMap<TypedKey<*>, Any?>.addToListProperty(key: TypedKey<in List<V>>, values: Iterable<V>) {
|
|
||||||
val newValues = get(key)?.let { (it as List<V>) + values } ?: values.toList()
|
|
||||||
put(key, newValues)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <V> HashMap<TypedKey<*>, Any?>.addToListProperty(key: TypedKey<in List<V>>, vararg values: V) {
|
|
||||||
val newValues = get(key)?.let { (it as List<V>) + values } ?: values.toList()
|
|
||||||
put(key, newValues)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <K, V> HashMap<TypedKey<*>, Any?>.addToMapProperty(key: TypedKey<in Map<K, V>>, values: Map<K, V>) {
|
|
||||||
val newValues = get(key)?.let { (it as Map<K, V>) + values } ?: values
|
|
||||||
put(key, newValues)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <K, V> HashMap<TypedKey<*>, Any?>.addToMapProperty(key: TypedKey<in Map<K, V>>, values: Iterable<Pair<K, V>>) {
|
|
||||||
val newValues = get(key)?.let { (it as Map<K, V>) + values } ?: values
|
|
||||||
put(key, newValues)
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,8 @@ interface ScriptCompiler {
|
|||||||
|
|
||||||
interface CompiledScript<out ScriptBase : Any> {
|
interface CompiledScript<out ScriptBase : Any> {
|
||||||
|
|
||||||
val configuration: ScriptCompileConfiguration
|
val definition: ScriptDefinition
|
||||||
|
val additionalConfiguration: ScriptCompileConfiguration?
|
||||||
|
|
||||||
suspend fun instantiate(scriptEvaluationEnvironment: ScriptEvaluationEnvironment): ResultWithDiagnostics<ScriptBase>
|
suspend fun instantiate(scriptEvaluationEnvironment: ScriptEvaluationEnvironment?): ResultWithDiagnostics<ScriptBase>
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-13
@@ -7,30 +7,54 @@
|
|||||||
|
|
||||||
package kotlin.script.experimental.api
|
package kotlin.script.experimental.api
|
||||||
|
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.util.typedKey
|
|
||||||
|
|
||||||
typealias ScriptCompileConfiguration = ChainedPropertyBag
|
interface ScriptCompileConfiguration : PropertiesCollection {
|
||||||
|
|
||||||
|
companion object : ScriptCompileConfiguration {
|
||||||
|
|
||||||
object ScriptCompileConfigurationProperties : PropertiesGroup {
|
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptCompileConfiguration {
|
||||||
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
val sourceFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
fun create(body: Builder.() -> Unit): ScriptCompileConfiguration = Builder().apply(body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ScriptingProperties.compilationConfiguration get() = ScriptCompileConfigurationProperties
|
val ScriptCompileConfiguration.sourceFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||||
|
|
||||||
typealias ProcessedScriptData = ChainedPropertyBag
|
val ScriptCompileConfiguration.scriptBodyTarget by PropertiesCollection.keyCopy(ScriptDefinition.scriptBodyTarget)
|
||||||
|
|
||||||
object ProcessedScriptDataProperties : PropertiesGroup {
|
val ScriptCompileConfiguration.scriptImplicitReceivers by PropertiesCollection.keyCopy(ScriptDefinition.scriptImplicitReceivers)
|
||||||
val foundAnnotations by typedKey<List<Annotation>>()
|
|
||||||
|
|
||||||
val foundFragments by typedKey<List<ScriptSourceNamedFragment>>()
|
val ScriptCompileConfiguration.contextVariables by PropertiesCollection.keyCopy(ScriptDefinition.contextVariables)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.defaultImports by PropertiesCollection.keyCopy(ScriptDefinition.defaultImports)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.restrictions by PropertiesCollection.keyCopy(ScriptDefinition.restrictions)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.importedScripts by PropertiesCollection.keyCopy(ScriptDefinition.importedScripts)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.dependencies by PropertiesCollection.keyCopy(ScriptDefinition.dependencies)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.compilerOptions by PropertiesCollection.keyCopy(ScriptDefinition.compilerOptions)
|
||||||
|
|
||||||
|
|
||||||
|
interface ProcessedScriptData : PropertiesCollection {
|
||||||
|
|
||||||
|
companion object : ProcessedScriptData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ProcessedScriptData.foundAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||||
|
|
||||||
|
val ProcessedScriptData.foundFragments by PropertiesCollection.key<List<ScriptSourceNamedFragment>>()
|
||||||
|
|
||||||
|
|
||||||
interface RefineScriptCompilationConfigurationHandler {
|
interface RefineScriptCompilationConfigurationHandler {
|
||||||
suspend operator fun invoke(
|
suspend operator fun invoke(
|
||||||
scriptSource: ScriptSource,
|
scriptSource: ScriptSource,
|
||||||
configuration: ScriptCompileConfiguration,
|
scriptDefinition: ScriptDefinition,
|
||||||
processedScriptData: ProcessedScriptData = ProcessedScriptData()
|
configuration: ScriptCompileConfiguration?,
|
||||||
): ResultWithDiagnostics<ScriptCompileConfiguration>
|
processedScriptData: ProcessedScriptData? = null
|
||||||
|
): ResultWithDiagnostics<ScriptCompileConfiguration?>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,73 +8,73 @@
|
|||||||
package kotlin.script.experimental.api
|
package kotlin.script.experimental.api
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.util.typedKey
|
|
||||||
|
|
||||||
typealias ScriptDefinition = ChainedPropertyBag
|
interface ScriptDefinition : PropertiesCollection {
|
||||||
|
|
||||||
object ScriptDefinitionProperties : PropertiesGroup {
|
companion object : ScriptDefinition {
|
||||||
|
|
||||||
val name by typedKey<String>() // Name of the script type, by default "Kotlin script"
|
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptDefinition {
|
||||||
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
val fileExtension by typedKey<String>() // default: "kts"
|
fun create(body: Builder.() -> Unit): ScriptDefinition = Builder().apply(body)
|
||||||
|
|
||||||
val baseClass by typedKey<KotlinType>() // script base class
|
|
||||||
|
|
||||||
val scriptBodyTarget by typedKey<ScriptBodyTarget>()
|
|
||||||
|
|
||||||
val scriptImplicitReceivers by typedKey<List<KotlinType>>() // in the order from outer to inner scope
|
|
||||||
|
|
||||||
val contextVariables by typedKey<Map<String, KotlinType>>() // external variables
|
|
||||||
|
|
||||||
val defaultImports by typedKey<List<String>>()
|
|
||||||
|
|
||||||
val restrictions by typedKey<List<ResolvingRestrictionRule>>()
|
|
||||||
|
|
||||||
val importedScripts by typedKey<List<ScriptSource>>()
|
|
||||||
|
|
||||||
val dependencies by typedKey<List<ScriptDependency>>()
|
|
||||||
|
|
||||||
val generatedClassAnnotations by typedKey<List<Annotation>>()
|
|
||||||
|
|
||||||
val generatedMethodAnnotations by typedKey<List<Annotation>>()
|
|
||||||
|
|
||||||
val compilerOptions by typedKey<List<String>>() // Q: CommonCompilerOptions instead?
|
|
||||||
|
|
||||||
val refineConfigurationHandler by typedKey<RefineScriptCompilationConfigurationHandler>() // dynamic configurator
|
|
||||||
|
|
||||||
val refineConfigurationBeforeParsing by typedKey<Boolean>() // default: false
|
|
||||||
|
|
||||||
val refineConfigurationOnAnnotations by typedKey<List<KotlinType>>()
|
|
||||||
|
|
||||||
val refineConfigurationOnSections by typedKey<List<String>>()
|
|
||||||
|
|
||||||
// DSL:
|
|
||||||
|
|
||||||
val refineConfiguration by propertiesBuilder<RefineConfigurationBuilder>()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DSL --------------------
|
|
||||||
|
|
||||||
val ScriptingProperties.scriptDefinition get() = ScriptDefinitionProperties
|
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
|
||||||
class RefineConfigurationBuilder(props: ScriptingProperties) : PropertiesBuilder(props) {
|
|
||||||
|
|
||||||
inline operator fun invoke(body: RefineConfigurationBuilder.() -> Unit) {
|
|
||||||
body()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Default : ScriptDefinition
|
||||||
|
}
|
||||||
|
|
||||||
|
val ScriptDefinition.name by PropertiesCollection.key<String>("Kotlin script") // Name of the script type
|
||||||
|
|
||||||
|
val ScriptDefinition.fileExtension by PropertiesCollection.key<String>("kts") // file extension
|
||||||
|
|
||||||
|
val ScriptDefinition.baseClass by PropertiesCollection.key<KotlinType>() // script base class
|
||||||
|
|
||||||
|
val ScriptDefinition.scriptBodyTarget by PropertiesCollection.key<ScriptBodyTarget>(ScriptBodyTarget.Constructor)
|
||||||
|
|
||||||
|
val ScriptDefinition.scriptImplicitReceivers by PropertiesCollection.key<List<KotlinType>>() // in the order from outer to inner scope
|
||||||
|
|
||||||
|
val ScriptDefinition.contextVariables by PropertiesCollection.key<Map<String, KotlinType>>() // external variables
|
||||||
|
|
||||||
|
val ScriptDefinition.defaultImports by PropertiesCollection.key<List<String>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.restrictions by PropertiesCollection.key<List<ResolvingRestrictionRule>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.importedScripts by PropertiesCollection.key<List<ScriptSource>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.dependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.generatedClassAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.generatedMethodAnnotations by PropertiesCollection.key<List<Annotation>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.compilerOptions by PropertiesCollection.key<List<String>>() // Q: CommonCompilerOptions instead?
|
||||||
|
|
||||||
|
val ScriptDefinition.refineConfigurationHandler by PropertiesCollection.key<RefineScriptCompilationConfigurationHandler>() // dynamic configurator
|
||||||
|
|
||||||
|
val ScriptDefinition.refineConfigurationBeforeParsing by PropertiesCollection.key<Boolean>() // default: false
|
||||||
|
|
||||||
|
val ScriptDefinition.refineConfigurationOnAnnotations by PropertiesCollection.key<List<KotlinType>>()
|
||||||
|
|
||||||
|
val ScriptDefinition.refineConfigurationOnSections by PropertiesCollection.key<List<String>>()
|
||||||
|
|
||||||
|
// DSL:
|
||||||
|
|
||||||
|
val ScriptDefinition.refineConfiguration get() = RefineConfigurationBuilder()
|
||||||
|
|
||||||
|
|
||||||
|
class RefineConfigurationBuilder : PropertiesCollection.Builder() {
|
||||||
|
|
||||||
fun handler(fn: RefineScriptCompilationConfigurationHandler) {
|
fun handler(fn: RefineScriptCompilationConfigurationHandler) {
|
||||||
props.data[ScriptDefinitionProperties.refineConfigurationHandler] = fn
|
set(ScriptDefinition.refineConfigurationHandler, fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun triggerBeforeParsing(value: Boolean = true) {
|
fun triggerBeforeParsing(value: Boolean = true) {
|
||||||
props.data[ScriptDefinitionProperties.refineConfigurationBeforeParsing] = value
|
set(ScriptDefinition.refineConfigurationBeforeParsing, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun triggerOnAnnotations(annotations: Iterable<KotlinType>) {
|
fun triggerOnAnnotations(annotations: Iterable<KotlinType>) {
|
||||||
props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnAnnotations, annotations)
|
ScriptDefinition.refineConfigurationOnAnnotations.append(annotations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun triggerOnAnnotations(vararg annotations: KotlinType) {
|
fun triggerOnAnnotations(vararg annotations: KotlinType) {
|
||||||
@@ -90,11 +90,11 @@ class RefineConfigurationBuilder(props: ScriptingProperties) : PropertiesBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun triggerOnSections(sections: Iterable<String>) {
|
fun triggerOnSections(sections: Iterable<String>) {
|
||||||
props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnSections, sections)
|
ScriptDefinition.refineConfigurationOnSections.append(sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun triggerOnSections(vararg sections: String) {
|
fun triggerOnSections(vararg sections: String) {
|
||||||
props.data.addToListProperty(ScriptDefinitionProperties.refineConfigurationOnSections, *sections)
|
ScriptDefinition.refineConfigurationOnSections.append(*sections)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,20 +7,27 @@
|
|||||||
|
|
||||||
package kotlin.script.experimental.api
|
package kotlin.script.experimental.api
|
||||||
|
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.util.typedKey
|
|
||||||
|
|
||||||
object ScriptEvaluationEnvironmentParams {
|
interface ScriptEvaluationEnvironment : PropertiesCollection {
|
||||||
val implicitReceivers by typedKey<List<Any>>()
|
|
||||||
|
|
||||||
val contextVariables by typedKey<Map<String, Any?>>() // external variables
|
companion object : ScriptEvaluationEnvironment {
|
||||||
|
|
||||||
val constructorArgs by typedKey<List<Any?>>()
|
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptEvaluationEnvironment {
|
||||||
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
val runArgs by typedKey<List<Any?>>()
|
fun create(body: Builder.() -> Unit): ScriptEvaluationEnvironment = Builder().apply(body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias ScriptEvaluationEnvironment = ChainedPropertyBag
|
val ScriptEvaluationEnvironment.implicitReceivers by PropertiesCollection.key<List<Any>>()
|
||||||
|
|
||||||
|
val ScriptEvaluationEnvironment.contextVariables by PropertiesCollection.key<Map<String, Any?>>() // external variables
|
||||||
|
|
||||||
|
val ScriptEvaluationEnvironment.constructorArgs by PropertiesCollection.key<List<Any?>>()
|
||||||
|
|
||||||
|
val ScriptEvaluationEnvironment.runArgs by PropertiesCollection.key<List<Any?>>()
|
||||||
|
|
||||||
sealed class ResultValue {
|
sealed class ResultValue {
|
||||||
class Value(val name: String, val value: Any?, val type: String) : ResultValue() {
|
class Value(val name: String, val value: Any?, val type: String) : ResultValue() {
|
||||||
@@ -30,12 +37,12 @@ sealed class ResultValue {
|
|||||||
object Unit : ResultValue()
|
object Unit : ResultValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class EvaluationResult(val returnValue: ResultValue, val environment: ScriptEvaluationEnvironment)
|
data class EvaluationResult(val returnValue: ResultValue, val environment: ScriptEvaluationEnvironment?)
|
||||||
|
|
||||||
interface ScriptEvaluator {
|
interface ScriptEvaluator {
|
||||||
|
|
||||||
suspend operator fun invoke(
|
suspend operator fun invoke(
|
||||||
compiledScript: CompiledScript<*>,
|
compiledScript: CompiledScript<*>,
|
||||||
scriptEvaluationEnvironment: ScriptEvaluationEnvironment
|
scriptEvaluationEnvironment: ScriptEvaluationEnvironment?
|
||||||
): ResultWithDiagnostics<EvaluationResult>
|
): ResultWithDiagnostics<EvaluationResult>
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-15
@@ -6,33 +6,38 @@
|
|||||||
package kotlin.script.experimental.api
|
package kotlin.script.experimental.api
|
||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.util.typedKey
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
typealias ScriptingEnvironment = ChainedPropertyBag
|
interface ScriptingEnvironment : PropertiesCollection {
|
||||||
|
|
||||||
object ScriptingEnvironmentProperties : PropertiesGroup {
|
companion object : ScriptingEnvironment {
|
||||||
|
|
||||||
// should contain all dependencies needed for baseClass and compilationConfigurator
|
class Builder internal constructor() : PropertiesCollection.Builder(), ScriptingEnvironment {
|
||||||
val configurationDependencies by typedKey<List<ScriptDependency>>()
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
// do not use configurationDependencies as script dependencies, so only the dependencies defined by compilationConfigurator will be used
|
fun create(body: Builder.() -> Unit): ScriptingEnvironment = Builder().apply(body)
|
||||||
// (NOTE: in this case they should include the dependencies for the base class anyway, since this class is needed for script
|
}
|
||||||
// compilation and instantiation, but compilationConfigurator could be excluded)
|
|
||||||
val isolatedDependencies by typedKey(false)
|
|
||||||
|
|
||||||
// a "class loader" for KotlinTypes
|
|
||||||
val getScriptingClass by typedKey<GetScriptingClass>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val ScriptingProperties.scriptingEnvironment get() = ScriptDefinitionProperties
|
// should contain all dependencies needed for baseClass and compilationConfigurator
|
||||||
|
val ScriptingEnvironment.configurationDependencies by PropertiesCollection.key<List<ScriptDependency>>()
|
||||||
|
|
||||||
|
// do not use configurationDependencies as script dependencies, so only the dependencies defined by compilationConfigurator will be used
|
||||||
|
// (NOTE: in this case they should include the dependencies for the base class anyway, since this class is needed for script
|
||||||
|
// compilation and instantiation, but compilationConfigurator could be excluded)
|
||||||
|
val ScriptingEnvironment.isolatedDependencies by PropertiesCollection.key<Boolean>(false)
|
||||||
|
|
||||||
|
// a "class loader" for KotlinTypes
|
||||||
|
val ScriptingEnvironment.getScriptingClass by PropertiesCollection.key<GetScriptingClass>()
|
||||||
|
|
||||||
interface GetScriptingClass {
|
interface GetScriptingClass {
|
||||||
operator fun invoke(classType: KotlinType, contextClass: KClass<*>, environment: ScriptingEnvironment): KClass<*>
|
operator fun invoke(classType: KotlinType, contextClass: KClass<*>, environment: ScriptingEnvironment): KClass<*>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ScriptingEnvironment.getScriptingClass(type: KotlinType, contextClass: KClass<*>): KClass<*> {
|
fun ScriptingEnvironment.getScriptingClass(type: KotlinType, contextClass: KClass<*>): KClass<*> {
|
||||||
val getClass = getOrNull(ScriptingEnvironmentProperties.getScriptingClass)
|
val getClass = getOrNull(ScriptingEnvironment.getScriptingClass)
|
||||||
?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment: unable to load scripting class $type")
|
?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment: unable to load scripting class $type")
|
||||||
return getClass(type, contextClass, this)
|
return getClass(type, contextClass, this)
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-31
@@ -11,9 +11,8 @@ import kotlin.reflect.full.findAnnotation
|
|||||||
import kotlin.script.experimental.annotations.KotlinScript
|
import kotlin.script.experimental.annotations.KotlinScript
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
import kotlin.script.experimental.annotations.KotlinScriptFileExtension
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptProperties
|
import kotlin.script.experimental.annotations.KotlinScriptProperties
|
||||||
import kotlin.script.experimental.annotations.KotlinScriptPropertiesFromList
|
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.util.TypedKey
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
private const val ERROR_MSG_PREFIX = "Unable to construct script definition: "
|
||||||
|
|
||||||
@@ -26,7 +25,7 @@ fun createScriptDefinitionFromAnnotatedBaseClass(
|
|||||||
contextClass: KClass<*> = ScriptDefinition::class
|
contextClass: KClass<*> = ScriptDefinition::class
|
||||||
): ScriptDefinition {
|
): ScriptDefinition {
|
||||||
|
|
||||||
val getScriptingClass = environment.getOrNull(ScriptingEnvironmentProperties.getScriptingClass)
|
val getScriptingClass = environment.getOrNull(ScriptingEnvironment.getScriptingClass)
|
||||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting 'getScriptingClass' parameter in the scripting environment")
|
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting 'getScriptingClass' parameter in the scripting environment")
|
||||||
|
|
||||||
val baseClass: KClass<*> =
|
val baseClass: KClass<*> =
|
||||||
@@ -39,38 +38,24 @@ fun createScriptDefinitionFromAnnotatedBaseClass(
|
|||||||
val mainAnnotation = baseClass.findAnnotation<KotlinScript>()
|
val mainAnnotation = baseClass.findAnnotation<KotlinScript>()
|
||||||
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting KotlinScript annotation on the $baseClass")
|
?: throw IllegalArgumentException("${ERROR_MSG_PREFIX}Expecting KotlinScript annotation on the $baseClass")
|
||||||
|
|
||||||
val propertiesData = hashMapOf<TypedKey<*>, Any?>(ScriptDefinitionProperties.baseClass to baseClassType)
|
fun scriptingPropsInstance(kclass: KClass<out ScriptDefinition>): ScriptDefinition = try {
|
||||||
|
kclass.objectInstance ?: kclass.createInstance()
|
||||||
propertiesData[ScriptDefinitionProperties.fileExtension] =
|
|
||||||
baseClass.findAnnotation<KotlinScriptFileExtension>()?.let { it.extension }
|
|
||||||
?: mainAnnotation.extension
|
|
||||||
propertiesData += ScriptDefinitionProperties.name to mainAnnotation.name
|
|
||||||
baseClass.annotations.filterIsInstance(KotlinScriptPropertiesFromList::class.java).forEach { ann ->
|
|
||||||
val params = try {
|
|
||||||
ann.definitionProperties.objectInstance ?: ann.definitionProperties.createInstance()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
|
||||||
}
|
|
||||||
params.forEach { param ->
|
|
||||||
if (param !is Pair<*, *> || param.first !is TypedKey<*>)
|
|
||||||
throw IllegalArgumentException("$ILLEGAL_CONFIG_ANN_ARG: invalid parameter $param")
|
|
||||||
(param as Pair<TypedKey<*>, Any?>).let { (k, v) ->
|
|
||||||
propertiesData[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun scriptingPropsInstance(kclass: KClass<out ScriptingProperties>): ScriptingProperties = try {
|
|
||||||
kclass.objectInstance ?: kclass.createInstance().also { it.setupOnce() }
|
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
throw IllegalArgumentException(ILLEGAL_CONFIG_ANN_ARG, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
baseClass.annotations.filterIsInstance(KotlinScriptProperties::class.java).forEach { ann ->
|
return object : ScriptDefinition {
|
||||||
propertiesData.putAll(scriptingPropsInstance(ann.definitionProperties).data)
|
override val properties = properties {
|
||||||
|
baseClass(baseClassType)
|
||||||
|
fileExtension(baseClass.findAnnotation<KotlinScriptFileExtension>()?.extension ?: mainAnnotation.extension)
|
||||||
|
name(mainAnnotation.name)
|
||||||
|
|
||||||
|
include(scriptingPropsInstance(mainAnnotation.definition))
|
||||||
|
|
||||||
|
baseClass.annotations.filterIsInstance(KotlinScriptProperties::class.java).forEach { ann ->
|
||||||
|
include(scriptingPropsInstance(ann.definition))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO: chaining is lost here and above, fix it
|
|
||||||
propertiesData.putAll(scriptingPropsInstance(mainAnnotation.properties).data)
|
|
||||||
return ScriptingEnvironment.createOptimized(null, propertiesData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -31,8 +31,8 @@ abstract class BasicScriptingHost(
|
|||||||
|
|
||||||
open fun eval(
|
open fun eval(
|
||||||
script: ScriptSource,
|
script: ScriptSource,
|
||||||
compileConfiguration: ScriptCompileConfiguration,
|
compileConfiguration: ScriptCompileConfiguration?,
|
||||||
environment: ScriptEvaluationEnvironment
|
environment: ScriptEvaluationEnvironment?
|
||||||
): ResultWithDiagnostics<EvaluationResult> =
|
): ResultWithDiagnostics<EvaluationResult> =
|
||||||
runInCoroutineContext {
|
runInCoroutineContext {
|
||||||
compiler(script, scriptDefinition, compileConfiguration).onSuccess {
|
compiler(script, scriptDefinition, compileConfiguration).onSuccess {
|
||||||
|
|||||||
@@ -7,7 +7,11 @@ package kotlin.script.experimental.host
|
|||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||||
|
import kotlin.script.experimental.api.ScriptSource
|
||||||
|
import kotlin.script.experimental.api.ScriptSourceNamedFragment
|
||||||
|
import kotlin.script.experimental.api.sourceFragments
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
fun ScriptSource.getScriptText(): String = when {
|
fun ScriptSource.getScriptText(): String = when {
|
||||||
text != null -> text!!
|
text != null -> text!!
|
||||||
@@ -16,9 +20,9 @@ fun ScriptSource.getScriptText(): String = when {
|
|||||||
else -> throw RuntimeException("unable to get text from null script")
|
else -> throw RuntimeException("unable to get text from null script")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMergedScriptText(script: ScriptSource, configuration: ScriptCompileConfiguration): String {
|
fun getMergedScriptText(script: ScriptSource, configuration: ScriptCompileConfiguration?): String {
|
||||||
val originalScriptText = script.getScriptText()
|
val originalScriptText = script.getScriptText()
|
||||||
val sourceFragments = configuration.getOrNull(ScriptCompileConfigurationProperties.sourceFragments)
|
val sourceFragments = configuration?.getOrNull(ScriptCompileConfiguration.sourceFragments)
|
||||||
return if (sourceFragments == null || sourceFragments.isEmpty()) {
|
return if (sourceFragments == null || sourceFragments.isEmpty()) {
|
||||||
originalScriptText
|
originalScriptText
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,15 +7,20 @@ package kotlin.script.experimental.repl
|
|||||||
|
|
||||||
import kotlin.script.experimental.api.EvaluationResult
|
import kotlin.script.experimental.api.EvaluationResult
|
||||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
|
|
||||||
|
interface ReplEvaluationEnvironment : PropertiesCollection {
|
||||||
|
|
||||||
object ReplEvaluationEnvironmentParams {
|
companion object : ReplEvaluationEnvironment {
|
||||||
|
|
||||||
|
class Builder internal constructor() : PropertiesCollection.Builder(), ReplEvaluationEnvironment {
|
||||||
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(body: Builder.() -> Unit): ReplEvaluationEnvironment = Builder().apply(body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias ReplEvaluationEnvironment = ChainedPropertyBag
|
|
||||||
|
|
||||||
interface ReplSnippetEvaluator {
|
interface ReplSnippetEvaluator {
|
||||||
|
|
||||||
suspend operator fun invoke(
|
suspend operator fun invoke(
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ import kotlin.script.experimental.api.EvaluationResult
|
|||||||
import kotlin.script.experimental.api.ResultWithDiagnostics
|
import kotlin.script.experimental.api.ResultWithDiagnostics
|
||||||
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||||
import kotlin.script.experimental.api.ScriptDefinition
|
import kotlin.script.experimental.api.ScriptDefinition
|
||||||
import kotlin.script.experimental.util.ChainedPropertyBag
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.util.typedKey
|
|
||||||
|
|
||||||
interface ReplCommandProcessor {
|
interface ReplCommandProcessor {
|
||||||
suspend operator fun invoke(
|
suspend operator fun invoke(
|
||||||
@@ -23,12 +22,19 @@ interface ReplCommandProcessor {
|
|||||||
|
|
||||||
data class ReplCommand(val commandName: String, val processor: ReplCommandProcessor)
|
data class ReplCommand(val commandName: String, val processor: ReplCommandProcessor)
|
||||||
|
|
||||||
object ReplHostEnvironmentParams {
|
interface ReplHostEnvironment : PropertiesCollection {
|
||||||
|
|
||||||
val replCommands by typedKey<List<ReplCommand>>()
|
companion object : ReplHostEnvironment {
|
||||||
|
|
||||||
|
class Builder internal constructor() : PropertiesCollection.Builder(), ReplHostEnvironment {
|
||||||
|
override val properties = data
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(body: Builder.() -> Unit): ReplHostEnvironment = Builder().apply(body)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias ReplHostEnvironment = ChainedPropertyBag
|
val ReplHostEnvironment.replCommands by PropertiesCollection.key<List<ReplCommand>>()
|
||||||
|
|
||||||
abstract class ReplHost(
|
abstract class ReplHost(
|
||||||
val environment: ReplHostEnvironment,
|
val environment: ReplHostEnvironment,
|
||||||
|
|||||||
+208
@@ -0,0 +1,208 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-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.util
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.script.experimental.api.KotlinType
|
||||||
|
|
||||||
|
interface PropertiesCollection {
|
||||||
|
|
||||||
|
val properties: Map<Key<*>, Any> get() = emptyMap()
|
||||||
|
|
||||||
|
data class Key<T>(val name: String, val defaultValue: T? = null)
|
||||||
|
|
||||||
|
class PropertyKeyDelegate<T>(private val defaultValue: T? = null) {
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): Key<T> =
|
||||||
|
Key(property.name, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
class PropertyKeyCopyDelegate<T>(val source: Key<T>) {
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): Key<T> = source
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T> key(defaultValue: T? = null) = PropertyKeyDelegate(defaultValue)
|
||||||
|
fun <T> keyCopy(source: Key<T>) = PropertyKeyCopyDelegate(source)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun properties(body: Builder.() -> Unit): Map<Key<*>, Any> = Builder().apply(body).data
|
||||||
|
|
||||||
|
// properties builder base class (DSL for building properties collection)
|
||||||
|
|
||||||
|
open class Builder {
|
||||||
|
|
||||||
|
val data: MutableMap<PropertiesCollection.Key<*>, Any> = LinkedHashMap()
|
||||||
|
|
||||||
|
// generic builder for all properties
|
||||||
|
operator fun <T : Any> PropertiesCollection.Key<T>.invoke(v: T) {
|
||||||
|
set(this, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic for lists
|
||||||
|
|
||||||
|
operator fun <T> PropertiesCollection.Key<in List<T>>.invoke(vararg vals: T) {
|
||||||
|
append(vals.asIterable())
|
||||||
|
}
|
||||||
|
|
||||||
|
// generic for maps:
|
||||||
|
|
||||||
|
operator fun <K, V> PropertiesCollection.Key<Map<K, V>>.invoke(vararg vs: Pair<K, V>) {
|
||||||
|
append(vs.asIterable())
|
||||||
|
}
|
||||||
|
|
||||||
|
// for strings and list of strings that could be converted from other types
|
||||||
|
|
||||||
|
@JvmName("invoke_string_fqn_from_generic")
|
||||||
|
inline operator fun <reified K> PropertiesCollection.Key<String>.invoke() {
|
||||||
|
set(this, K::class.qualifiedName!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_string_fqn_from_reflected_class")
|
||||||
|
operator fun PropertiesCollection.Key<String>.invoke(kclass: KClass<*>) {
|
||||||
|
set(this, kclass.qualifiedName!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_string_list_fqn_from_generic")
|
||||||
|
inline operator fun <reified K> PropertiesCollection.Key<in List<String>>.invoke() {
|
||||||
|
append(K::class.qualifiedName!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_string_list_fqn_from_reflected_class")
|
||||||
|
operator fun PropertiesCollection.Key<in List<String>>.invoke(vararg kclasses: KClass<*>) {
|
||||||
|
append(kclasses.map { it.qualifiedName!! })
|
||||||
|
}
|
||||||
|
|
||||||
|
// for KotlinType:
|
||||||
|
|
||||||
|
inline operator fun <reified K> PropertiesCollection.Key<KotlinType>.invoke() {
|
||||||
|
set(this, KotlinType(K::class))
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<KotlinType>.invoke(kclass: KClass<*>) {
|
||||||
|
data[this] = KotlinType(kclass)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<KotlinType>.invoke(ktype: KType) {
|
||||||
|
data[this] = KotlinType(ktype)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<KotlinType>.invoke(fqname: String) {
|
||||||
|
data[this] = KotlinType(fqname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// for list of KotlinTypes
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_list_from_generic")
|
||||||
|
inline operator fun <reified K> PropertiesCollection.Key<in List<KotlinType>>.invoke() {
|
||||||
|
append(KotlinType(K::class))
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<List<KotlinType>>.invoke(vararg classes: KClass<*>) {
|
||||||
|
append(classes.map { KotlinType(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<List<KotlinType>>.invoke(vararg types: KType) {
|
||||||
|
append(types.map { KotlinType(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun PropertiesCollection.Key<List<KotlinType>>.invoke(vararg fqnames: String) {
|
||||||
|
append(fqnames.map { KotlinType(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// for map of generic keys to KotlinTypes:
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_kclass")
|
||||||
|
operator fun <K> PropertiesCollection.Key<Map<K, KotlinType>>.invoke(vararg classes: Pair<K, KClass<*>>) {
|
||||||
|
append(classes.map { (k, v) -> k to KotlinType(v) })
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_ktype")
|
||||||
|
operator fun <K> PropertiesCollection.Key<Map<K, KotlinType>>.invoke(vararg types: Pair<K, KType>) {
|
||||||
|
append(types.map { (k, v) -> k to KotlinType(v) })
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("invoke_kotlintype_map_from_fqname")
|
||||||
|
operator fun <K> PropertiesCollection.Key<Map<K, KotlinType>>.invoke(vararg fqnames: Pair<K, String>) {
|
||||||
|
append(fqnames.map { (k, v) -> k to KotlinType(v) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// direct manipulation - public - for usage in inline dsl methods and for extending dsl
|
||||||
|
|
||||||
|
operator fun <T : Any> set(key: PropertiesCollection.Key<in T>, value: T) {
|
||||||
|
data[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
operator fun <T : Any> get(key: PropertiesCollection.Key<in T>): T? = data[key]?.let { it as T }
|
||||||
|
|
||||||
|
// appenders to list and map properties
|
||||||
|
|
||||||
|
@JvmName("appendToList")
|
||||||
|
fun <V> PropertiesCollection.Key<in List<V>>.append(values: Iterable<V>) {
|
||||||
|
val newValues = get(this)?.let { it + values } ?: values.toList()
|
||||||
|
data[this] = newValues
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <V> PropertiesCollection.Key<in List<V>>.append(vararg values: V) {
|
||||||
|
val newValues = get(this)?.let { it + values } ?: values.toList()
|
||||||
|
data[this] = newValues
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <K, V> PropertiesCollection.Key<in Map<K, V>>.append(values: Map<K, V>) {
|
||||||
|
val newValues = get(this)?.let { it + values } ?: values
|
||||||
|
data[this] = newValues
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("appendToMap")
|
||||||
|
fun <K, V> PropertiesCollection.Key<in Map<K, V>>.append(values: Iterable<Pair<K, V>>) {
|
||||||
|
val newValues = get(this)?.let { it + values } ?: values
|
||||||
|
data[this] = newValues
|
||||||
|
}
|
||||||
|
|
||||||
|
// include other properties
|
||||||
|
fun include(other: PropertiesCollection?) {
|
||||||
|
other?.properties?.let { data.putAll(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// include another builder
|
||||||
|
operator fun <T : Builder> T.invoke(body: T.() -> Unit) {
|
||||||
|
this.body()
|
||||||
|
this@Builder.data.putAll(this.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <T> PropertiesCollection.getOrNull(key: PropertiesCollection.Key<T>): T? =
|
||||||
|
properties[key]?.let { it as T } ?: key.defaultValue
|
||||||
|
|
||||||
|
fun <T> PropertiesCollection.getOrError(key: PropertiesCollection.Key<T>): T =
|
||||||
|
getOrNull(key) ?: throw IllegalArgumentException("Unknown key $key")
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <T> getFirstFromChainOrNull(key: PropertiesCollection.Key<T>, vararg propertyCollections: PropertiesCollection?): T? {
|
||||||
|
for (collection in propertyCollections) {
|
||||||
|
val value = collection?.properties?.get(key)
|
||||||
|
if (value != null) return value as T
|
||||||
|
}
|
||||||
|
return key.defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun <T> getMergedFromChainOrNull(key: PropertiesCollection.Key<List<T>>, vararg propertyCollections: PropertiesCollection?): List<T>? {
|
||||||
|
var found = false
|
||||||
|
val res = ArrayList<T>()
|
||||||
|
for (collection in propertyCollections) {
|
||||||
|
val value = collection?.properties?.get(key)
|
||||||
|
if (value != null) {
|
||||||
|
found = true
|
||||||
|
res.addAll(value as List<T>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (found) res else key.defaultValue
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:Suppress("unused")
|
|
||||||
|
|
||||||
package kotlin.script.experimental.util
|
|
||||||
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
data class TypedKey<T>(val name: String, val defaultValue: T? = null)
|
|
||||||
|
|
||||||
class TypedKeyDelegate<T>(val defaultValue: T? = null) {
|
|
||||||
operator fun getValue(thisRef: Any?, property: KProperty<*>): TypedKey<T> = TypedKey(property.name, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> typedKey(defaultValue: T? = null) = TypedKeyDelegate(defaultValue)
|
|
||||||
|
|
||||||
open class ChainedPropertyBag internal constructor(private val parent: ChainedPropertyBag?, internal val data: Map<TypedKey<*>, Any?>) {
|
|
||||||
constructor(parent: ChainedPropertyBag? = null, pairs: Iterable<Pair<TypedKey<*>, Any?>>) :
|
|
||||||
this(parent, HashMap<TypedKey<*>, Any?>().also { it.putAll(pairs) })
|
|
||||||
|
|
||||||
constructor(pairs: Iterable<Pair<TypedKey<*>, Any?>>) : this(null, pairs)
|
|
||||||
constructor(parent: ChainedPropertyBag, vararg pairs: Pair<TypedKey<*>, Any?>) : this(parent, pairs.asIterable())
|
|
||||||
constructor(vararg pairs: Pair<TypedKey<*>, Any?>) : this(null, pairs.asIterable())
|
|
||||||
|
|
||||||
fun cloneWithNewParent(newParent: ChainedPropertyBag?): ChainedPropertyBag = when {
|
|
||||||
this == newParent -> this
|
|
||||||
newParent == null -> this
|
|
||||||
parent == null -> createOptimized(newParent, data)
|
|
||||||
else -> createOptimized(parent.cloneWithNewParent(newParent), data)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator fun <reified T> get(key: TypedKey<T>): T = getRaw(key) as T
|
|
||||||
|
|
||||||
fun <T> getRaw(key: TypedKey<T>): Any? = getOrNullRaw(key) ?: throw IllegalArgumentException("Unknown key $key")
|
|
||||||
|
|
||||||
inline fun <reified T> getOrNull(key: TypedKey<T>): T? = getOrNullRaw(key)?.let { it as T }
|
|
||||||
|
|
||||||
fun <T> getOrNullRaw(key: TypedKey<T>): Any? = data[key] ?: parent?.getOrNullRaw(key) ?: key.defaultValue
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun createOptimized(parent: ChainedPropertyBag?, data: Map<TypedKey<*>, Any?>): ChainedPropertyBag = when {
|
|
||||||
parent != null && data.isEmpty() -> parent
|
|
||||||
parent != null && parent.data.isEmpty() -> createOptimized(parent.parent, data)
|
|
||||||
else -> ChainedPropertyBag(parent, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun chainPropertyBags(propertyBags: Iterable<ChainedPropertyBag?>): ChainedPropertyBag =
|
|
||||||
propertyBags.fold(ChainedPropertyBag()) { res, next -> if (next == null) res else res.cloneWithNewParent(next) }
|
|
||||||
|
|
||||||
fun chainPropertyBags(vararg propertyBags: ChainedPropertyBag?): ChainedPropertyBag = chainPropertyBags(propertyBags.asIterable())
|
|
||||||
+33
-29
@@ -40,21 +40,28 @@ import kotlin.script.experimental.api.*
|
|||||||
import kotlin.script.experimental.dependencies.DependenciesResolver
|
import kotlin.script.experimental.dependencies.DependenciesResolver
|
||||||
import kotlin.script.experimental.host.getMergedScriptText
|
import kotlin.script.experimental.host.getMergedScriptText
|
||||||
import kotlin.script.experimental.jvm.JvmDependency
|
import kotlin.script.experimental.jvm.JvmDependency
|
||||||
import kotlin.script.experimental.jvm.JvmScriptCompileConfigurationProperties
|
import kotlin.script.experimental.jvm.JvmScriptCompilationConfiguration
|
||||||
import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver
|
import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver
|
||||||
import kotlin.script.experimental.jvmhost.JvmScriptEvaluationEnvironmentProperties
|
import kotlin.script.experimental.jvm.javaHome
|
||||||
|
import kotlin.script.experimental.jvmhost.JvmScriptEvaluationEnvironment
|
||||||
import kotlin.script.experimental.jvmhost.KJvmCompilerProxy
|
import kotlin.script.experimental.jvmhost.KJvmCompilerProxy
|
||||||
import kotlin.script.experimental.util.chainPropertyBags
|
import kotlin.script.experimental.jvmhost.baseClassLoader
|
||||||
|
import kotlin.script.experimental.util.getFirstFromChainOrNull
|
||||||
|
import kotlin.script.experimental.util.getMergedFromChainOrNull
|
||||||
|
import kotlin.script.experimental.util.getOrError
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
class KJvmCompiledScript<out ScriptBase : Any>(
|
class KJvmCompiledScript<out ScriptBase : Any>(
|
||||||
override val configuration: ScriptCompileConfiguration,
|
override val definition: ScriptDefinition,
|
||||||
val generationState: GenerationState,
|
override val additionalConfiguration: ScriptCompileConfiguration?,
|
||||||
val scriptClassFQName: String
|
private val generationState: GenerationState,
|
||||||
|
private val scriptClassFQName: String
|
||||||
) : CompiledScript<ScriptBase> {
|
) : CompiledScript<ScriptBase> {
|
||||||
|
|
||||||
override suspend fun instantiate(scriptEvaluationEnvironment: ScriptEvaluationEnvironment): ResultWithDiagnostics<ScriptBase> = try {
|
override suspend fun instantiate(scriptEvaluationEnvironment: ScriptEvaluationEnvironment?): ResultWithDiagnostics<ScriptBase> = try {
|
||||||
val baseClassLoader = scriptEvaluationEnvironment.getOrNull(JvmScriptEvaluationEnvironmentProperties.baseClassLoader)
|
val baseClassLoader = scriptEvaluationEnvironment?.getOrNull(JvmScriptEvaluationEnvironment.baseClassLoader)
|
||||||
val dependencies = configuration.getOrNull(ScriptDefinitionProperties.dependencies)
|
?: Thread.currentThread().contextClassLoader
|
||||||
|
val dependencies = additionalConfiguration?.getOrNull(ScriptDefinition.dependencies)
|
||||||
?.flatMap { (it as? JvmDependency)?.classpath?.map { it.toURI().toURL() } ?: emptyList() }
|
?.flatMap { (it as? JvmDependency)?.classpath?.map { it.toURI().toURL() } ?: emptyList() }
|
||||||
// TODO: previous dependencies and classloaders should be taken into account here
|
// TODO: previous dependencies and classloaders should be taken into account here
|
||||||
val classLoaderWithDeps =
|
val classLoaderWithDeps =
|
||||||
@@ -75,7 +82,7 @@ class KJvmCompilerImpl(val hostEnvironment: ScriptingEnvironment) : KJvmCompiler
|
|||||||
override fun compile(
|
override fun compile(
|
||||||
script: ScriptSource,
|
script: ScriptSource,
|
||||||
scriptDefinition: ScriptDefinition,
|
scriptDefinition: ScriptDefinition,
|
||||||
additionalConfiguration: ScriptCompileConfiguration
|
additionalConfiguration: ScriptCompileConfiguration?
|
||||||
): ResultWithDiagnostics<CompiledScript<*>> {
|
): ResultWithDiagnostics<CompiledScript<*>> {
|
||||||
val messageCollector = ScriptDiagnosticsMessageCollector()
|
val messageCollector = ScriptDiagnosticsMessageCollector()
|
||||||
|
|
||||||
@@ -85,37 +92,35 @@ class KJvmCompilerImpl(val hostEnvironment: ScriptingEnvironment) : KJvmCompiler
|
|||||||
try {
|
try {
|
||||||
setIdeaIoUseFallback()
|
setIdeaIoUseFallback()
|
||||||
|
|
||||||
val scriptCompileConfiguration = chainPropertyBags(additionalConfiguration, scriptDefinition)
|
|
||||||
var environment: KotlinCoreEnvironment? = null
|
var environment: KotlinCoreEnvironment? = null
|
||||||
var updatedScriptCompileConfiguration = scriptCompileConfiguration
|
var updatedScriptCompileConfiguration = additionalConfiguration
|
||||||
|
|
||||||
fun updateClasspath(classpath: List<File>) {
|
fun updateClasspath(classpath: List<File>) {
|
||||||
environment!!.updateClasspath(classpath.map(::JvmClasspathRoot))
|
environment!!.updateClasspath(classpath.map(::JvmClasspathRoot))
|
||||||
val updatedDeps = updatedScriptCompileConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)?.plus(
|
if (classpath.isNotEmpty()) {
|
||||||
JvmDependency(classpath)
|
updatedScriptCompileConfiguration = ScriptCompileConfiguration.create {
|
||||||
) ?: listOf(JvmDependency(classpath))
|
include(updatedScriptCompileConfiguration)
|
||||||
updatedScriptCompileConfiguration = ScriptCompileConfiguration(
|
dependencies.append(JvmDependency(classpath))
|
||||||
updatedScriptCompileConfiguration,
|
}
|
||||||
ScriptDefinitionProperties.dependencies to updatedDeps
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val disposable = Disposer.newDisposable()
|
val disposable = Disposer.newDisposable()
|
||||||
val kotlinCompilerConfiguration = org.jetbrains.kotlin.config.CompilerConfiguration().apply {
|
val kotlinCompilerConfiguration = org.jetbrains.kotlin.config.CompilerConfiguration().apply {
|
||||||
add(
|
add(
|
||||||
JVMConfigurationKeys.SCRIPT_DEFINITIONS,
|
JVMConfigurationKeys.SCRIPT_DEFINITIONS,
|
||||||
BridgeScriptDefinition(scriptDefinition, scriptCompileConfiguration, hostEnvironment, ::updateClasspath)
|
BridgeScriptDefinition(scriptDefinition, additionalConfiguration, hostEnvironment, ::updateClasspath)
|
||||||
)
|
)
|
||||||
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
||||||
put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
||||||
|
|
||||||
var isModularJava = false
|
var isModularJava = false
|
||||||
scriptCompileConfiguration.getOrNull(JvmScriptCompileConfigurationProperties.javaHomeDir)?.let {
|
getFirstFromChainOrNull(JvmScriptCompilationConfiguration.javaHome, updatedScriptCompileConfiguration, hostEnvironment)?.let {
|
||||||
put(JVMConfigurationKeys.JDK_HOME, it)
|
put(JVMConfigurationKeys.JDK_HOME, it)
|
||||||
isModularJava = CoreJrtFileSystem.isModularJdk(it)
|
isModularJava = CoreJrtFileSystem.isModularJdk(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
scriptCompileConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)?.let {
|
getMergedFromChainOrNull(ScriptDefinition.dependencies, scriptDefinition, updatedScriptCompileConfiguration)?.let {
|
||||||
addJvmClasspathRoots(
|
addJvmClasspathRoots(
|
||||||
it.flatMap {
|
it.flatMap {
|
||||||
(it as JvmDependency).classpath
|
(it as JvmDependency).classpath
|
||||||
@@ -147,7 +152,7 @@ class KJvmCompilerImpl(val hostEnvironment: ScriptingEnvironment) : KJvmCompiler
|
|||||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector, environment.configuration.languageVersionSettings)
|
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(messageCollector, environment.configuration.languageVersionSettings)
|
||||||
|
|
||||||
val psiFileFactory: PsiFileFactoryImpl = PsiFileFactory.getInstance(environment.project) as PsiFileFactoryImpl
|
val psiFileFactory: PsiFileFactoryImpl = PsiFileFactory.getInstance(environment.project) as PsiFileFactoryImpl
|
||||||
val scriptText = getMergedScriptText(script, scriptCompileConfiguration)
|
val scriptText = getMergedScriptText(script, updatedScriptCompileConfiguration)
|
||||||
val scriptFileName = "script" // TODO: extract from file/url if available
|
val scriptFileName = "script" // TODO: extract from file/url if available
|
||||||
val virtualFile = LightVirtualFile(
|
val virtualFile = LightVirtualFile(
|
||||||
"$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}",
|
"$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}",
|
||||||
@@ -192,7 +197,7 @@ class KJvmCompilerImpl(val hostEnvironment: ScriptingEnvironment) : KJvmCompiler
|
|||||||
org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION
|
org.jetbrains.kotlin.codegen.CompilationErrorHandler.THROW_EXCEPTION
|
||||||
)
|
)
|
||||||
|
|
||||||
val res = KJvmCompiledScript<Any>(updatedScriptCompileConfiguration, generationState, scriptFileName.capitalize())
|
val res = KJvmCompiledScript<Any>(scriptDefinition, updatedScriptCompileConfiguration, generationState, scriptFileName.capitalize())
|
||||||
|
|
||||||
return ResultWithDiagnostics.Success(res, messageCollector.diagnostics)
|
return ResultWithDiagnostics.Success(res, messageCollector.diagnostics)
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
@@ -238,23 +243,22 @@ class ScriptDiagnosticsMessageCollector : MessageCollector {
|
|||||||
|
|
||||||
internal class BridgeScriptDefinition(
|
internal class BridgeScriptDefinition(
|
||||||
scriptDefinition: ScriptDefinition,
|
scriptDefinition: ScriptDefinition,
|
||||||
calculatedScriptCompilerConfiguration: ScriptCompileConfiguration,
|
additionalCompilationConfiguration: ScriptCompileConfiguration?,
|
||||||
hostEnvironment: ScriptingEnvironment,
|
hostEnvironment: ScriptingEnvironment,
|
||||||
updateClasspath: (List<File>) -> Unit
|
updateClasspath: (List<File>) -> Unit
|
||||||
) : KotlinScriptDefinition(
|
) : KotlinScriptDefinition(
|
||||||
hostEnvironment.getScriptingClass(
|
hostEnvironment.getScriptingClass(
|
||||||
scriptDefinition[ScriptDefinitionProperties.baseClass],
|
scriptDefinition.getOrError(ScriptDefinition.baseClass),
|
||||||
BridgeScriptDefinition::class
|
BridgeScriptDefinition::class
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override val acceptedAnnotations = run {
|
override val acceptedAnnotations = run {
|
||||||
val cl = this::class.java.classLoader
|
val cl = this::class.java.classLoader
|
||||||
calculatedScriptCompilerConfiguration.getOrNull(ScriptDefinitionProperties.refineConfigurationOnAnnotations)
|
additionalCompilationConfiguration?.getOrNull(ScriptDefinition.refineConfigurationOnAnnotations)
|
||||||
?.map { (cl.loadClass(it.typeName) as Class<out Annotation>).kotlin }
|
?.map { (cl.loadClass(it.typeName) as Class<out Annotation>).kotlin }
|
||||||
?: emptyList()
|
?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val dependencyResolver: DependenciesResolver =
|
override val dependencyResolver: DependenciesResolver =
|
||||||
BridgeDependenciesResolver(scriptDefinition, calculatedScriptCompilerConfiguration, updateClasspath)
|
BridgeDependenciesResolver(scriptDefinition, additionalCompilationConfiguration, updateClasspath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-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.jvmhost.impl
|
||||||
|
|
||||||
|
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||||
|
import kotlin.script.experimental.api.ScriptingEnvironment
|
||||||
|
import kotlin.script.experimental.jvm.defaultJvmScriptingEnvironment
|
||||||
|
|
||||||
|
internal fun mergeConfigurations(vararg configurations: ScriptCompileConfiguration?): ScriptCompileConfiguration? {
|
||||||
|
val nonEmptyConfigurations = configurations.filter { it != null && it.properties.isNotEmpty() }
|
||||||
|
return when {
|
||||||
|
nonEmptyConfigurations.isEmpty() -> null
|
||||||
|
nonEmptyConfigurations.size == 1 -> nonEmptyConfigurations.first()!!
|
||||||
|
else -> ScriptCompileConfiguration.create {
|
||||||
|
for (configuration in nonEmptyConfigurations) {
|
||||||
|
include(configuration!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ScriptingEnvironment.withDefaults(): ScriptingEnvironment =
|
||||||
|
if (this == defaultJvmScriptingEnvironment || defaultJvmScriptingEnvironment.properties.all {
|
||||||
|
this.properties.containsKey(it.key)
|
||||||
|
}) {
|
||||||
|
this
|
||||||
|
} else {
|
||||||
|
ScriptingEnvironment.create {
|
||||||
|
include(defaultJvmScriptingEnvironment)
|
||||||
|
include(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
-15
@@ -10,21 +10,29 @@ package kotlin.script.experimental.jvmhost
|
|||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.jvm.defaultJvmScriptingEnvironment
|
import kotlin.script.experimental.jvm.defaultJvmScriptingEnvironment
|
||||||
import kotlin.script.experimental.jvmhost.impl.KJvmCompilerImpl
|
import kotlin.script.experimental.jvmhost.impl.KJvmCompilerImpl
|
||||||
import kotlin.script.experimental.util.chainPropertyBags
|
import kotlin.script.experimental.jvmhost.impl.mergeConfigurations
|
||||||
|
import kotlin.script.experimental.jvmhost.impl.withDefaults
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
interface CompiledJvmScriptsCache {
|
interface CompiledJvmScriptsCache {
|
||||||
fun get(script: ScriptSource, configuration: ScriptCompileConfiguration): CompiledScript<*>?
|
fun get(script: ScriptSource, scriptDefinition: ScriptDefinition, configuration: ScriptCompileConfiguration?): CompiledScript<*>?
|
||||||
fun store(compiledScript: CompiledScript<*>, configuration: ScriptCompileConfiguration)
|
fun store(compiledScript: CompiledScript<*>, scriptDefinition: ScriptDefinition, configuration: ScriptCompileConfiguration?)
|
||||||
|
|
||||||
object NoCache : CompiledJvmScriptsCache {
|
object NoCache : CompiledJvmScriptsCache {
|
||||||
override fun get(script: ScriptSource, configuration: ScriptCompileConfiguration): CompiledScript<*>? = null
|
override fun get(
|
||||||
override fun store(compiledScript: CompiledScript<*>, configuration: ScriptCompileConfiguration) {}
|
script: ScriptSource, scriptDefinition: ScriptDefinition, configuration: ScriptCompileConfiguration?
|
||||||
|
): CompiledScript<*>? = null
|
||||||
|
|
||||||
|
override fun store(
|
||||||
|
compiledScript: CompiledScript<*>, scriptDefinition: ScriptDefinition, configuration: ScriptCompileConfiguration?
|
||||||
|
) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class JvmScriptCompiler(
|
open class JvmScriptCompiler(
|
||||||
hostEnvironment: ScriptingEnvironment = defaultJvmScriptingEnvironment,
|
hostEnvironment: ScriptingEnvironment = defaultJvmScriptingEnvironment,
|
||||||
val compilerProxy: KJvmCompilerProxy = KJvmCompilerImpl(hostEnvironment.cloneWithNewParent(defaultJvmScriptingEnvironment)),
|
val compilerProxy: KJvmCompilerProxy = KJvmCompilerImpl(hostEnvironment.withDefaults()),
|
||||||
val cache: CompiledJvmScriptsCache = CompiledJvmScriptsCache.NoCache
|
val cache: CompiledJvmScriptsCache = CompiledJvmScriptsCache.NoCache
|
||||||
) : ScriptCompiler {
|
) : ScriptCompiler {
|
||||||
|
|
||||||
@@ -33,29 +41,29 @@ open class JvmScriptCompiler(
|
|||||||
scriptDefinition: ScriptDefinition,
|
scriptDefinition: ScriptDefinition,
|
||||||
additionalConfiguration: ScriptCompileConfiguration?
|
additionalConfiguration: ScriptCompileConfiguration?
|
||||||
): ResultWithDiagnostics<CompiledScript<*>> {
|
): ResultWithDiagnostics<CompiledScript<*>> {
|
||||||
val baseConfiguration = chainPropertyBags(additionalConfiguration, scriptDefinition)
|
val refineConfigurationFn = scriptDefinition.getOrNull(ScriptDefinition.refineConfigurationHandler)
|
||||||
val refineConfigurationFn = baseConfiguration.getOrNull(ScriptDefinitionProperties.refineConfigurationHandler)
|
|
||||||
val refinedConfiguration =
|
val refinedConfiguration =
|
||||||
if (baseConfiguration.getOrNull(ScriptDefinitionProperties.refineConfigurationBeforeParsing) == true) {
|
if (scriptDefinition.getOrNull(ScriptDefinition.refineConfigurationBeforeParsing) == true) {
|
||||||
if (refineConfigurationFn == null) {
|
if (refineConfigurationFn == null) {
|
||||||
return ResultWithDiagnostics.Failure("Non-null configurator expected".asErrorDiagnostics())
|
return ResultWithDiagnostics.Failure("Non-null configurator expected".asErrorDiagnostics())
|
||||||
}
|
}
|
||||||
refineConfigurationFn(script, baseConfiguration).let {
|
refineConfigurationFn(script, scriptDefinition, additionalConfiguration).let {
|
||||||
when (it) {
|
when (it) {
|
||||||
is ResultWithDiagnostics.Failure -> return it
|
is ResultWithDiagnostics.Failure -> return it
|
||||||
is ResultWithDiagnostics.Success -> it.value
|
is ResultWithDiagnostics.Success -> it.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
baseConfiguration
|
null
|
||||||
}
|
}
|
||||||
val cached = cache.get(script, refinedConfiguration)
|
val actualConfiguration = mergeConfigurations(additionalConfiguration, refinedConfiguration)
|
||||||
|
val cached = cache.get(script, scriptDefinition, actualConfiguration)
|
||||||
|
|
||||||
if (cached != null) return cached.asSuccess()
|
if (cached != null) return cached.asSuccess()
|
||||||
|
|
||||||
return compilerProxy.compile(script, scriptDefinition, refinedConfiguration).also {
|
return compilerProxy.compile(script, scriptDefinition, actualConfiguration).also {
|
||||||
if (it is ResultWithDiagnostics.Success) {
|
if (it is ResultWithDiagnostics.Success) {
|
||||||
cache.store(it.value, refinedConfiguration)
|
cache.store(it.value, scriptDefinition, actualConfiguration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +73,7 @@ interface KJvmCompilerProxy {
|
|||||||
fun compile(
|
fun compile(
|
||||||
script: ScriptSource,
|
script: ScriptSource,
|
||||||
scriptDefinition: ScriptDefinition,
|
scriptDefinition: ScriptDefinition,
|
||||||
additionalConfiguration: ScriptCompileConfiguration
|
additionalConfiguration: ScriptCompileConfiguration?
|
||||||
): ResultWithDiagnostics<CompiledScript<*>>
|
): ResultWithDiagnostics<CompiledScript<*>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -8,17 +8,23 @@
|
|||||||
package kotlin.script.experimental.jvmhost
|
package kotlin.script.experimental.jvmhost
|
||||||
|
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
import kotlin.script.experimental.util.typedKey
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
object JvmScriptEvaluationEnvironmentProperties {
|
open class JvmScriptEvaluationEnvironment : PropertiesCollection.Builder() {
|
||||||
val baseClassLoader by typedKey<ClassLoader?>(Thread.currentThread().contextClassLoader)
|
|
||||||
|
companion object : JvmScriptEvaluationEnvironment()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val JvmScriptEvaluationEnvironment.baseClassLoader by PropertiesCollection.key<ClassLoader?>(Thread.currentThread().contextClassLoader)
|
||||||
|
|
||||||
|
val ScriptEvaluationEnvironment.jvm get() = JvmScriptEvaluationEnvironment()
|
||||||
|
|
||||||
open class BasicJvmScriptEvaluator : ScriptEvaluator {
|
open class BasicJvmScriptEvaluator : ScriptEvaluator {
|
||||||
|
|
||||||
override suspend operator fun invoke(
|
override suspend operator fun invoke(
|
||||||
compiledScript: CompiledScript<*>,
|
compiledScript: CompiledScript<*>,
|
||||||
scriptEvaluationEnvironment: ScriptEvaluationEnvironment
|
scriptEvaluationEnvironment: ScriptEvaluationEnvironment?
|
||||||
): ResultWithDiagnostics<EvaluationResult> =
|
): ResultWithDiagnostics<EvaluationResult> =
|
||||||
try {
|
try {
|
||||||
val obj = compiledScript.instantiate(scriptEvaluationEnvironment)
|
val obj = compiledScript.instantiate(scriptEvaluationEnvironment)
|
||||||
@@ -32,7 +38,7 @@ open class BasicJvmScriptEvaluator : ScriptEvaluator {
|
|||||||
if (scriptObject !is Class<*>)
|
if (scriptObject !is Class<*>)
|
||||||
ResultWithDiagnostics.Failure(ScriptDiagnostic("expecting class in this implementation, got ${scriptObject?.javaClass}"))
|
ResultWithDiagnostics.Failure(ScriptDiagnostic("expecting class in this implementation, got ${scriptObject?.javaClass}"))
|
||||||
else {
|
else {
|
||||||
val receivers = scriptEvaluationEnvironment.getOrNull(ScriptEvaluationEnvironmentParams.implicitReceivers)
|
val receivers = scriptEvaluationEnvironment?.getOrNull(ScriptEvaluationEnvironment.implicitReceivers)
|
||||||
val instance = if (receivers == null) {
|
val instance = if (receivers == null) {
|
||||||
scriptObject.getConstructor().newInstance()
|
scriptObject.getConstructor().newInstance()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+21
-12
@@ -18,10 +18,12 @@ import kotlin.script.experimental.host.toScriptSource
|
|||||||
import kotlin.script.experimental.jvm.JvmDependency
|
import kotlin.script.experimental.jvm.JvmDependency
|
||||||
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportPosition
|
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportPosition
|
||||||
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportSeverity
|
import kotlin.script.experimental.jvm.compat.mapToLegacyScriptReportSeverity
|
||||||
|
import kotlin.script.experimental.util.getFirstFromChainOrNull
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
class BridgeDependenciesResolver(
|
class BridgeDependenciesResolver(
|
||||||
val scriptDefinition: ScriptDefinition,
|
val scriptDefinition: ScriptDefinition,
|
||||||
val calculatedBaseScriptCompilerConfiguration: ScriptCompileConfiguration,
|
private val additionalConfiguration: ScriptCompileConfiguration?,
|
||||||
val onClasspathUpdated: (List<File>) -> Unit = {}
|
val onClasspathUpdated: (List<File>) -> Unit = {}
|
||||||
) : AsyncDependenciesResolver {
|
) : AsyncDependenciesResolver {
|
||||||
|
|
||||||
@@ -34,14 +36,19 @@ class BridgeDependenciesResolver(
|
|||||||
return try {
|
return try {
|
||||||
|
|
||||||
val diagnostics = arrayListOf<ScriptReport>()
|
val diagnostics = arrayListOf<ScriptReport>()
|
||||||
val processedScriptData =
|
val processedScriptData = object : ProcessedScriptData {
|
||||||
ProcessedScriptData(ProcessedScriptDataProperties.foundAnnotations to scriptContents.annotations)
|
override val properties = properties {
|
||||||
|
foundAnnotations.append(scriptContents.annotations)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val refineFn = scriptDefinition.getOrNull(ScriptDefinitionProperties.refineConfigurationHandler)
|
val refineFn = scriptDefinition.getOrNull(ScriptDefinition.refineConfigurationHandler)
|
||||||
val refinedConfiguration =
|
val refinedConfiguration =
|
||||||
if (refineFn == null) calculatedBaseScriptCompilerConfiguration
|
if (refineFn == null) null
|
||||||
else {
|
else {
|
||||||
val res = refineFn(scriptContents.toScriptSource(), calculatedBaseScriptCompilerConfiguration, processedScriptData)
|
val res = refineFn(
|
||||||
|
scriptContents.toScriptSource(), scriptDefinition, additionalConfiguration, processedScriptData
|
||||||
|
)
|
||||||
when (res) {
|
when (res) {
|
||||||
is ResultWithDiagnostics.Failure ->
|
is ResultWithDiagnostics.Failure ->
|
||||||
return@resolveAsync DependenciesResolver.ResolveResult.Failure(res.reports.mapScriptReportsToDiagnostics())
|
return@resolveAsync DependenciesResolver.ResolveResult.Failure(res.reports.mapScriptReportsToDiagnostics())
|
||||||
@@ -52,11 +59,12 @@ class BridgeDependenciesResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newClasspath = refinedConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)
|
val newClasspath = refinedConfiguration?.getOrNull(ScriptDefinition.dependencies)
|
||||||
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
||||||
if (refinedConfiguration != calculatedBaseScriptCompilerConfiguration) {
|
if (newClasspath.isNotEmpty()) {
|
||||||
val oldClasspath = calculatedBaseScriptCompilerConfiguration.getOrNull(ScriptDefinitionProperties.dependencies)
|
val oldClasspath =
|
||||||
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
getFirstFromChainOrNull(ScriptDefinition.dependencies, additionalConfiguration, scriptDefinition)
|
||||||
|
?.flatMap { (it as JvmDependency).classpath } ?: emptyList()
|
||||||
if (newClasspath != oldClasspath) {
|
if (newClasspath != oldClasspath) {
|
||||||
onClasspathUpdated(newClasspath)
|
onClasspathUpdated(newClasspath)
|
||||||
}
|
}
|
||||||
@@ -64,8 +72,9 @@ class BridgeDependenciesResolver(
|
|||||||
DependenciesResolver.ResolveResult.Success(
|
DependenciesResolver.ResolveResult.Success(
|
||||||
ScriptDependencies(
|
ScriptDependencies(
|
||||||
classpath = newClasspath, // TODO: maybe it should return only increment from the initial config
|
classpath = newClasspath, // TODO: maybe it should return only increment from the initial config
|
||||||
imports = refinedConfiguration.getOrNull(ScriptDefinitionProperties.defaultImports)?.toList()
|
imports = getFirstFromChainOrNull(
|
||||||
?: emptyList()
|
ScriptDefinition.defaultImports, refinedConfiguration, additionalConfiguration, scriptDefinition
|
||||||
|
)?.toList() ?: emptyList()
|
||||||
),
|
),
|
||||||
diagnostics
|
diagnostics
|
||||||
)
|
)
|
||||||
|
|||||||
+8
-7
@@ -7,13 +7,14 @@
|
|||||||
|
|
||||||
package kotlin.script.experimental.jvm
|
package kotlin.script.experimental.jvm
|
||||||
|
|
||||||
import java.io.File
|
import kotlin.script.experimental.api.ScriptCompileConfiguration
|
||||||
import kotlin.script.experimental.api.PropertiesGroup
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
import kotlin.script.experimental.api.ScriptingProperties
|
|
||||||
import kotlin.script.experimental.util.typedKey
|
|
||||||
|
|
||||||
object JvmScriptCompileConfigurationProperties : PropertiesGroup {
|
open class JvmScriptCompilationConfiguration : JvmScriptDefinition() {
|
||||||
val javaHomeDir by typedKey<File>(File(System.getProperty("java.home")))
|
|
||||||
|
companion object : JvmScriptCompilationConfiguration()
|
||||||
}
|
}
|
||||||
|
|
||||||
val ScriptingProperties.jvmCompileConfiguration get() = JvmScriptCompileConfigurationProperties
|
val JvmScriptCompilationConfiguration.javaHome by PropertiesCollection.keyCopy(JvmScriptingEnvironment.javaHome)
|
||||||
|
|
||||||
|
val ScriptCompileConfiguration.jvm get() = JvmScriptCompilationConfiguration()
|
||||||
|
|||||||
+15
-8
@@ -7,26 +7,33 @@ package kotlin.script.experimental.jvm
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.script.util.scriptCompilationClasspathFromContext
|
import org.jetbrains.kotlin.script.util.scriptCompilationClasspathFromContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.script.experimental.api.ScriptDefinitionProperties
|
import kotlin.script.experimental.api.ScriptDefinition
|
||||||
import kotlin.script.experimental.api.ScriptDependency
|
import kotlin.script.experimental.api.ScriptDependency
|
||||||
import kotlin.script.experimental.api.ScriptingProperties
|
import kotlin.script.experimental.api.dependencies
|
||||||
import kotlin.script.experimental.api.addToListProperty
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
|
|
||||||
|
open class JvmScriptDefinition : PropertiesCollection.Builder() {
|
||||||
|
|
||||||
|
companion object : JvmScriptDefinition()
|
||||||
|
}
|
||||||
|
|
||||||
|
val ScriptDefinition.jvm get() = JvmScriptDefinition()
|
||||||
|
|
||||||
|
|
||||||
class JvmDependency(val classpath: List<File>) : ScriptDependency {
|
class JvmDependency(val classpath: List<File>) : ScriptDependency {
|
||||||
constructor(vararg classpathEntries: File) : this(classpathEntries.asList())
|
constructor(vararg classpathEntries: File) : this(classpathEntries.asList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ScriptingProperties.jvmDependenciesFromCurrentContext(vararg libraries: String, wholeClasspath: Boolean = false) {
|
fun JvmScriptDefinition.dependenciesFromCurrentContext(vararg libraries: String, wholeClasspath: Boolean = false) {
|
||||||
jvmDependenciesFromClassloader(*libraries, wholeClasspath = wholeClasspath)
|
dependenciesFromClassloader(*libraries, wholeClasspath = wholeClasspath)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ScriptingProperties.jvmDependenciesFromClassloader(
|
fun JvmScriptDefinition.dependenciesFromClassloader(
|
||||||
vararg libraries: String,
|
vararg libraries: String,
|
||||||
classLoader: ClassLoader = Thread.currentThread().contextClassLoader,
|
classLoader: ClassLoader = Thread.currentThread().contextClassLoader,
|
||||||
wholeClasspath: Boolean = false
|
wholeClasspath: Boolean = false
|
||||||
) {
|
) {
|
||||||
data.addToListProperty(
|
ScriptDefinition.dependencies.append(
|
||||||
ScriptDefinitionProperties.dependencies,
|
|
||||||
JvmDependency(scriptCompilationClasspathFromContext(*libraries, classLoader = classLoader, wholeClasspath = wholeClasspath))
|
JvmDependency(scriptCompilationClasspathFromContext(*libraries, classLoader = classLoader, wholeClasspath = wholeClasspath))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+16
-10
@@ -5,18 +5,24 @@
|
|||||||
|
|
||||||
package kotlin.script.experimental.jvm
|
package kotlin.script.experimental.jvm
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.script.experimental.api.*
|
import kotlin.script.experimental.api.*
|
||||||
|
import kotlin.script.experimental.util.PropertiesCollection
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
private object DefaultJvmScriptingEnvironmentPropertiesBuilder : ScriptingProperties() {
|
open class JvmScriptingEnvironment : PropertiesCollection.Builder() {
|
||||||
init {
|
companion object : JvmScriptingEnvironment()
|
||||||
ScriptingEnvironmentProperties.getScriptingClass(JvmGetScriptingClass())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val defaultJvmScriptingEnvironment = DefaultJvmScriptingEnvironmentPropertiesBuilder.build()
|
val JvmScriptingEnvironment.javaHome by PropertiesCollection.key<File>(File(System.getProperty("java.home")))
|
||||||
|
|
||||||
|
val ScriptingEnvironment.jvm get() = JvmScriptingEnvironment()
|
||||||
|
|
||||||
|
val defaultJvmScriptingEnvironment = ScriptingEnvironment.create {
|
||||||
|
getScriptingClass(JvmGetScriptingClass())
|
||||||
|
}
|
||||||
|
|
||||||
class JvmGetScriptingClass : GetScriptingClass {
|
class JvmGetScriptingClass : GetScriptingClass {
|
||||||
|
|
||||||
@@ -37,7 +43,7 @@ class JvmGetScriptingClass : GetScriptingClass {
|
|||||||
if (actualClassLoadersChain.any { it == fromClass.java.classLoader }) return fromClass
|
if (actualClassLoadersChain.any { it == fromClass.java.classLoader }) return fromClass
|
||||||
}
|
}
|
||||||
|
|
||||||
val newDeps = environment.getOrNull(ScriptingEnvironmentProperties.configurationDependencies)
|
val newDeps = environment.getOrNull(ScriptingEnvironment.configurationDependencies)
|
||||||
if (dependencies == null) {
|
if (dependencies == null) {
|
||||||
dependencies = newDeps
|
dependencies = newDeps
|
||||||
} else {
|
} else {
|
||||||
@@ -55,10 +61,10 @@ class JvmGetScriptingClass : GetScriptingClass {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (classLoader == null) {
|
if (classLoader == null) {
|
||||||
val classpath = dependencies?.flatMap {
|
val classpath = dependencies?.flatMap { dependency ->
|
||||||
when(it) {
|
when(dependency) {
|
||||||
is JvmDependency -> it.classpath.map { it.toURI().toURL() }
|
is JvmDependency -> dependency.classpath.map { it.toURI().toURL() }
|
||||||
else -> throw IllegalArgumentException("unknown dependency type $it")
|
else -> throw IllegalArgumentException("unknown dependency type $dependency")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
classLoader =
|
classLoader =
|
||||||
|
|||||||
@@ -8,47 +8,47 @@ package kotlin.script.experimental.misc
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
import kotlin.script.experimental.api.KotlinType
|
import kotlin.script.experimental.api.KotlinType
|
||||||
import kotlin.script.experimental.util.TypedKey
|
import kotlin.script.experimental.util.PropertyKey
|
||||||
|
|
||||||
|
|
||||||
inline operator fun <reified T> TypedKey<T>.invoke(v: T): Pair<TypedKey<T>, T> = this to v
|
inline operator fun <reified T> PropertyKey<T>.invoke(v: T): Pair<PropertyKey<T>, T> = this to v
|
||||||
|
|
||||||
inline operator fun <reified K> TypedKey<KotlinType>.invoke(): Pair<TypedKey<KotlinType>, KotlinType> =
|
inline operator fun <reified K> PropertyKey<KotlinType>.invoke(): Pair<PropertyKey<KotlinType>, KotlinType> =
|
||||||
this to KotlinType(K::class)
|
this to KotlinType(K::class)
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(kclass: KClass<*>): Pair<TypedKey<KotlinType>, KotlinType> =
|
operator fun PropertyKey<KotlinType>.invoke(kclass: KClass<*>): Pair<PropertyKey<KotlinType>, KotlinType> =
|
||||||
this to KotlinType(kclass)
|
this to KotlinType(kclass)
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(ktype: KType): Pair<TypedKey<KotlinType>, KotlinType> =
|
operator fun PropertyKey<KotlinType>.invoke(ktype: KType): Pair<PropertyKey<KotlinType>, KotlinType> =
|
||||||
this to KotlinType(ktype)
|
this to KotlinType(ktype)
|
||||||
|
|
||||||
operator fun TypedKey<KotlinType>.invoke(fqname: String): Pair<TypedKey<KotlinType>, KotlinType> =
|
operator fun PropertyKey<KotlinType>.invoke(fqname: String): Pair<PropertyKey<KotlinType>, KotlinType> =
|
||||||
this to KotlinType(fqname)
|
this to KotlinType(fqname)
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg classes: KClass<*>): Pair<TypedKey<List<KotlinType>>, List<KotlinType>> =
|
operator fun PropertyKey<List<KotlinType>>.invoke(vararg classes: KClass<*>): Pair<PropertyKey<List<KotlinType>>, List<KotlinType>> =
|
||||||
this to classes.map { KotlinType(it) }
|
this to classes.map { KotlinType(it) }
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg types: KType): Pair<TypedKey<List<KotlinType>>, List<KotlinType>> =
|
operator fun PropertyKey<List<KotlinType>>.invoke(vararg types: KType): Pair<PropertyKey<List<KotlinType>>, List<KotlinType>> =
|
||||||
this to types.map { KotlinType(it) }
|
this to types.map { KotlinType(it) }
|
||||||
|
|
||||||
operator fun TypedKey<List<KotlinType>>.invoke(vararg fqnames: String): Pair<TypedKey<List<KotlinType>>, List<KotlinType>> =
|
operator fun PropertyKey<List<KotlinType>>.invoke(vararg fqnames: String): Pair<PropertyKey<List<KotlinType>>, List<KotlinType>> =
|
||||||
this to fqnames.map { KotlinType(it) }
|
this to fqnames.map { KotlinType(it) }
|
||||||
|
|
||||||
inline operator fun <reified E> TypedKey<List<E>>.invoke(vararg vs: E): Pair<TypedKey<List<E>>, List<E>> = this to vs.toList()
|
inline operator fun <reified E> PropertyKey<List<E>>.invoke(vararg vs: E): Pair<PropertyKey<List<E>>, List<E>> = this to vs.toList()
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_kclass")
|
@JvmName("invoke_kotlintype_map_from_kclass")
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg classes: Pair<K, KClass<*>>): Pair<TypedKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
inline operator fun <reified K> PropertyKey<Map<K, KotlinType>>.invoke(vararg classes: Pair<K, KClass<*>>): Pair<PropertyKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
||||||
this to LinkedHashMap<K, KotlinType>().also { it.putAll(classes.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
this to LinkedHashMap<K, KotlinType>().also { it.putAll(classes.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_ktype")
|
@JvmName("invoke_kotlintype_map_from_ktype")
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg types: Pair<K, KType>): Pair<TypedKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
inline operator fun <reified K> PropertyKey<Map<K, KotlinType>>.invoke(vararg types: Pair<K, KType>): Pair<PropertyKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
||||||
this to LinkedHashMap<K, KotlinType>().also { it.putAll(types.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
this to LinkedHashMap<K, KotlinType>().also { it.putAll(types.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
|
||||||
@JvmName("invoke_kotlintype_map_from_fqname")
|
@JvmName("invoke_kotlintype_map_from_fqname")
|
||||||
inline operator fun <reified K> TypedKey<Map<K, KotlinType>>.invoke(vararg fqnames: Pair<K, String>): Pair<TypedKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
inline operator fun <reified K> PropertyKey<Map<K, KotlinType>>.invoke(vararg fqnames: Pair<K, String>): Pair<PropertyKey<Map<K, KotlinType>>, Map<K, KotlinType>> =
|
||||||
this to LinkedHashMap<K, KotlinType>().also { it.putAll(fqnames.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
this to LinkedHashMap<K, KotlinType>().also { it.putAll(fqnames.asSequence().map { (k, v) -> k to KotlinType(v) }) }
|
||||||
|
|
||||||
inline operator fun <reified K, reified V> TypedKey<Map<K, V>>.invoke(vararg vs: Pair<K, V>): Pair<TypedKey<Map<K, V>>, Map<K, V>> =
|
inline operator fun <reified K, reified V> PropertyKey<Map<K, V>>.invoke(vararg vs: Pair<K, V>): Pair<PropertyKey<Map<K, V>>, Map<K, V>> =
|
||||||
this to mapOf(*vs)
|
this to mapOf(*vs)
|
||||||
|
|
||||||
// TODO: make tests from examples below
|
// TODO: make tests from examples below
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ dependencies {
|
|||||||
compileOnly(project(":compiler:cli"))
|
compileOnly(project(":compiler:cli"))
|
||||||
compile(project(":kotlin-scripting-common"))
|
compile(project(":kotlin-scripting-common"))
|
||||||
compile(project(":kotlin-scripting-jvm"))
|
compile(project(":kotlin-scripting-jvm"))
|
||||||
compile(project(":kotlin-scripting-misc"))
|
|
||||||
compileOnly(project(":kotlin-reflect-api"))
|
compileOnly(project(":kotlin-reflect-api"))
|
||||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
compileOnly(intellijDep()) { includeJars("asm-all") }
|
compileOnly(intellijDep()) { includeJars("asm-all") }
|
||||||
|
|||||||
+15
-13
@@ -18,6 +18,8 @@ import kotlin.script.experimental.api.*
|
|||||||
import kotlin.script.experimental.dependencies.DependenciesResolver
|
import kotlin.script.experimental.dependencies.DependenciesResolver
|
||||||
import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver
|
import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver
|
||||||
import kotlin.script.experimental.location.ScriptExpectedLocation
|
import kotlin.script.experimental.location.ScriptExpectedLocation
|
||||||
|
import kotlin.script.experimental.util.getOrError
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
// temporary trick with passing Any as a template and overwriting it below, TODO: fix after introducing new script definitions hierarchy
|
// temporary trick with passing Any as a template and overwriting it below, TODO: fix after introducing new script definitions hierarchy
|
||||||
abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinition(Any::class) {
|
abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinition(Any::class) {
|
||||||
@@ -29,13 +31,13 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit
|
|||||||
abstract val scriptFileExtensionWithDot: String
|
abstract val scriptFileExtensionWithDot: String
|
||||||
|
|
||||||
open val baseClass: KClass<*> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
open val baseClass: KClass<*> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
getScriptingClass(scriptDefinition[ScriptDefinitionProperties.baseClass])
|
getScriptingClass(scriptDefinition.getOrError(ScriptDefinition.baseClass))
|
||||||
}
|
}
|
||||||
|
|
||||||
override val template: KClass<*> get() = baseClass
|
override val template: KClass<*> get() = baseClass
|
||||||
|
|
||||||
override val name: String
|
override val name: String
|
||||||
get() = scriptDefinition.getOrNull(ScriptDefinitionProperties.name) ?: "Kotlin Script"
|
get() = scriptDefinition.getOrNull(ScriptDefinition.name) ?: "Kotlin Script"
|
||||||
|
|
||||||
override val fileType: LanguageFileType = KotlinFileType.INSTANCE
|
override val fileType: LanguageFileType = KotlinFileType.INSTANCE
|
||||||
|
|
||||||
@@ -51,28 +53,28 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit
|
|||||||
get() = emptyList()
|
get() = emptyList()
|
||||||
|
|
||||||
override val dependencyResolver: DependenciesResolver by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val dependencyResolver: DependenciesResolver by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
BridgeDependenciesResolver(scriptDefinition, scriptDefinition)
|
BridgeDependenciesResolver(scriptDefinition, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val acceptedAnnotations: List<KClass<out Annotation>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val acceptedAnnotations: List<KClass<out Annotation>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
scriptDefinition.getOrNull(ScriptDefinitionProperties.refineConfigurationOnAnnotations)
|
scriptDefinition.getOrNull(ScriptDefinition.refineConfigurationOnAnnotations)
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.map { getScriptingClass(it) as KClass<out Annotation> }
|
.map { getScriptingClass(it) as KClass<out Annotation> }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val implicitReceivers: List<KType> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val implicitReceivers: List<KType> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
scriptDefinition.getOrNull(ScriptDefinitionProperties.scriptImplicitReceivers)
|
scriptDefinition.getOrNull(ScriptDefinition.scriptImplicitReceivers)
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.map { getScriptingClass(it).starProjectedType }
|
.map { getScriptingClass(it).starProjectedType }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val environmentVariables: List<Pair<String, KType>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val environmentVariables: List<Pair<String, KType>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
scriptDefinition.getOrNull(ScriptDefinitionProperties.contextVariables)
|
scriptDefinition.getOrNull(ScriptDefinition.contextVariables)
|
||||||
?.map { (k, v) -> k to getScriptingClass(v).starProjectedType }.orEmpty()
|
?.map { (k, v) -> k to getScriptingClass(v).starProjectedType }.orEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
override val additionalCompilerArguments: List<String>
|
override val additionalCompilerArguments: List<String>
|
||||||
get() = scriptDefinition.getOrNull(ScriptDefinitionProperties.compilerOptions)
|
get() = scriptDefinition.getOrNull(ScriptDefinition.compilerOptions)
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
override val scriptExpectedLocations: List<ScriptExpectedLocation> =
|
override val scriptExpectedLocations: List<ScriptExpectedLocation> =
|
||||||
@@ -82,15 +84,15 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit
|
|||||||
)
|
)
|
||||||
|
|
||||||
override val targetClassAnnotations: List<Annotation>
|
override val targetClassAnnotations: List<Annotation>
|
||||||
get() = scriptDefinition.getOrNull(ScriptDefinitionProperties.generatedClassAnnotations)
|
get() = scriptDefinition.getOrNull(ScriptDefinition.generatedClassAnnotations)
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
override val targetMethodAnnotations: List<Annotation>
|
override val targetMethodAnnotations: List<Annotation>
|
||||||
get() = scriptDefinition.getOrNull(ScriptDefinitionProperties.generatedMethodAnnotations)
|
get() = scriptDefinition.getOrNull(ScriptDefinition.generatedMethodAnnotations)
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
|
|
||||||
private val scriptingClassGetter by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
private val scriptingClassGetter by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
hostEnvironment.getOrNull(ScriptingEnvironmentProperties.getScriptingClass)
|
hostEnvironment.getOrNull(ScriptingEnvironment.getScriptingClass)
|
||||||
?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment")
|
?: throw IllegalArgumentException("Expecting 'getScriptingClass' property in the scripting environment")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ abstract class KotlinScriptDefinitionAdapterFromNewAPIBase : KotlinScriptDefinit
|
|||||||
scriptingClassGetter(
|
scriptingClassGetter(
|
||||||
type,
|
type,
|
||||||
KotlinScriptDefinition::class, // Assuming that the KotlinScriptDefinition class is loaded in the proper classloader
|
KotlinScriptDefinition::class, // Assuming that the KotlinScriptDefinition class is loaded in the proper classloader
|
||||||
scriptDefinition
|
hostEnvironment
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +110,8 @@ class KotlinScriptDefinitionAdapterFromNewAPI(
|
|||||||
override val hostEnvironment: ScriptingEnvironment
|
override val hostEnvironment: ScriptingEnvironment
|
||||||
) : KotlinScriptDefinitionAdapterFromNewAPIBase() {
|
) : KotlinScriptDefinitionAdapterFromNewAPIBase() {
|
||||||
|
|
||||||
override val name: String get() = scriptDefinition.getOrNull(ScriptDefinitionProperties.name) ?: super.name
|
override val name: String get() = scriptDefinition.getOrNull(ScriptDefinition.name) ?: super.name
|
||||||
|
|
||||||
override val scriptFileExtensionWithDot =
|
override val scriptFileExtensionWithDot =
|
||||||
"." + (scriptDefinition.getOrNull(ScriptDefinitionProperties.fileExtension) ?: "kts")
|
"." + (scriptDefinition.getOrNull(ScriptDefinition.fileExtension) ?: "kts")
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-6
@@ -19,6 +19,7 @@ import kotlin.script.experimental.api.*
|
|||||||
import kotlin.script.experimental.definitions.createScriptDefinitionFromAnnotatedBaseClass
|
import kotlin.script.experimental.definitions.createScriptDefinitionFromAnnotatedBaseClass
|
||||||
import kotlin.script.experimental.jvm.JvmDependency
|
import kotlin.script.experimental.jvm.JvmDependency
|
||||||
import kotlin.script.experimental.jvm.defaultJvmScriptingEnvironment
|
import kotlin.script.experimental.jvm.defaultJvmScriptingEnvironment
|
||||||
|
import kotlin.script.experimental.util.getOrNull
|
||||||
|
|
||||||
class LazyScriptDefinitionFromDiscoveredClass internal constructor(
|
class LazyScriptDefinitionFromDiscoveredClass internal constructor(
|
||||||
private val annotationsFromAsm: ArrayList<BinAnnData>,
|
private val annotationsFromAsm: ArrayList<BinAnnData>,
|
||||||
@@ -35,10 +36,10 @@ class LazyScriptDefinitionFromDiscoveredClass internal constructor(
|
|||||||
) : this(loadAnnotationsFromClass(classBytes), className, classpath, messageCollector)
|
) : this(loadAnnotationsFromClass(classBytes), className, classpath, messageCollector)
|
||||||
|
|
||||||
override val hostEnvironment: ScriptingEnvironment by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val hostEnvironment: ScriptingEnvironment by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
ScriptingEnvironment(
|
ScriptingEnvironment.create {
|
||||||
defaultJvmScriptingEnvironment,
|
include(defaultJvmScriptingEnvironment)
|
||||||
ScriptingEnvironmentProperties.configurationDependencies to listOf(JvmDependency(classpath))
|
configurationDependencies(JvmDependency(classpath))
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val scriptDefinition: ScriptDefinition by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
override val scriptDefinition: ScriptDefinition by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||||
@@ -69,7 +70,7 @@ class LazyScriptDefinitionFromDiscoveredClass internal constructor(
|
|||||||
// TODO: check whether it actually works
|
// TODO: check whether it actually works
|
||||||
?: annotationsFromAsm.find { it.name == KotlinScript::class.simpleName }?.args?.get(1)
|
?: annotationsFromAsm.find { it.name == KotlinScript::class.simpleName }?.args?.get(1)
|
||||||
?: scriptDefinition.let {
|
?: scriptDefinition.let {
|
||||||
it.getOrNull(ScriptDefinitionProperties.fileExtension) ?: "kts"
|
it.getOrNull(ScriptDefinition.fileExtension) ?: "kts"
|
||||||
}
|
}
|
||||||
".$ext"
|
".$ext"
|
||||||
}
|
}
|
||||||
@@ -80,4 +81,4 @@ class LazyScriptDefinitionFromDiscoveredClass internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object InvalidScriptDefinition : ScriptDefinition()
|
object InvalidScriptDefinition : ScriptDefinition
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
|||||||
|
|
||||||
val compilerClasspath = listOf(kotlinPaths.compilerPath)
|
val compilerClasspath = listOf(kotlinPaths.compilerPath)
|
||||||
val runtimeClasspath = listOf( kotlinPaths.stdlibPath, kotlinPaths.scriptRuntimePath, kotlinPaths.reflectPath)
|
val runtimeClasspath = listOf( kotlinPaths.stdlibPath, kotlinPaths.scriptRuntimePath, kotlinPaths.reflectPath)
|
||||||
val scriptingClasspath = listOf("kotlin-scripting-common.jar", "kotlin-scripting-misc.jar").map { File(kotlinPaths.libPath, it) }
|
val scriptingClasspath = listOf("kotlin-scripting-common.jar").map { File(kotlinPaths.libPath, it) }
|
||||||
|
|
||||||
private fun createEnvironment(
|
private fun createEnvironment(
|
||||||
sources: List<String>, destDir: File, messageCollector: MessageCollector, confBody: CompilerConfiguration.() -> Unit
|
sources: List<String>, destDir: File, messageCollector: MessageCollector, confBody: CompilerConfiguration.() -> Unit
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ val packedJars by configurations.creating
|
|||||||
dependencies {
|
dependencies {
|
||||||
packedJars(project(":kotlin-scripting-compiler")) { isTransitive = false }
|
packedJars(project(":kotlin-scripting-compiler")) { isTransitive = false }
|
||||||
packedJars(project(":kotlin-scripting-common")) { isTransitive = false }
|
packedJars(project(":kotlin-scripting-common")) { isTransitive = false }
|
||||||
packedJars(project(":kotlin-scripting-misc")) { isTransitive = false }
|
|
||||||
packedJars(project(":kotlin-scripting-jvm")) { isTransitive = false }
|
packedJars(project(":kotlin-scripting-jvm")) { isTransitive = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ include ":kotlin-build-common",
|
|||||||
":kotlin-annotations-jvm",
|
":kotlin-annotations-jvm",
|
||||||
":kotlin-annotations-android",
|
":kotlin-annotations-android",
|
||||||
":kotlin-scripting-common",
|
":kotlin-scripting-common",
|
||||||
":kotlin-scripting-misc",
|
|
||||||
":kotlin-scripting-jvm",
|
":kotlin-scripting-jvm",
|
||||||
":kotlin-scripting-jvm-host",
|
":kotlin-scripting-jvm-host",
|
||||||
":kotlin-scripting-compiler",
|
":kotlin-scripting-compiler",
|
||||||
@@ -274,7 +273,6 @@ project(':examples:kotlin-jsr223-daemon-local-eval-example').projectDir = "$root
|
|||||||
project(':kotlin-annotations-jvm').projectDir = "$rootDir/libraries/tools/kotlin-annotations-jvm" as File
|
project(':kotlin-annotations-jvm').projectDir = "$rootDir/libraries/tools/kotlin-annotations-jvm" as File
|
||||||
project(':kotlin-annotations-android').projectDir = "$rootDir/libraries/tools/kotlin-annotations-android" as File
|
project(':kotlin-annotations-android').projectDir = "$rootDir/libraries/tools/kotlin-annotations-android" as File
|
||||||
project(':kotlin-scripting-common').projectDir = "$rootDir/libraries/scripting/common" as File
|
project(':kotlin-scripting-common').projectDir = "$rootDir/libraries/scripting/common" as File
|
||||||
project(':kotlin-scripting-misc').projectDir = "$rootDir/libraries/scripting/misc" as File
|
|
||||||
project(':kotlin-scripting-jvm').projectDir = "$rootDir/libraries/scripting/jvm" as File
|
project(':kotlin-scripting-jvm').projectDir = "$rootDir/libraries/scripting/jvm" as File
|
||||||
project(':kotlin-scripting-jvm-host').projectDir = "$rootDir/libraries/scripting/jvm-host" as File
|
project(':kotlin-scripting-jvm-host').projectDir = "$rootDir/libraries/scripting/jvm-host" as File
|
||||||
project(':kotlin-scripting-compiler').projectDir = "$rootDir/plugins/scripting/scripting-cli" as File
|
project(':kotlin-scripting-compiler').projectDir = "$rootDir/plugins/scripting/scripting-cli" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user