diff --git a/core/script.runtime/src/kotlin/script/dependencies/dependencies.kt b/core/script.runtime/src/kotlin/script/dependencies/dependencies.kt index 6f6600ec3a7..7e60c35c3c0 100644 --- a/core/script.runtime/src/kotlin/script/dependencies/dependencies.kt +++ b/core/script.runtime/src/kotlin/script/dependencies/dependencies.kt @@ -19,43 +19,15 @@ package kotlin.script.dependencies import java.io.File -import java.util.Collections.emptyList -interface KotlinScriptExternalDependencies : Comparable { - val javaHome: String? get() = null - val classpath: Iterable get() = emptyList() - val imports: Iterable get() = emptyList() - val sources: Iterable get() = emptyList() - val scripts: Iterable get() = emptyList() - - override fun compareTo(other: KotlinScriptExternalDependencies): Int = - compareValues(javaHome, other.javaHome) - .chainCompare { compareIterables(classpath, other.classpath) } - .chainCompare { compareIterables(imports, other.imports) } - .chainCompare { compareIterables(sources, other.sources) } - .chainCompare { compareIterables(scripts, other.scripts) } -} - -// copied form Comparisons.kt to resolve temporary build issues with dependency on stdlib -private fun > compareValues(a: T?, b: T?): Int { - if (a === b) return 0 - if (a == null) return -1 - if (b == null) return 1 - - @Suppress("UNCHECKED_CAST") - return (a as Comparable).compareTo(b) -} - -private fun> compareIterables(a: Iterable, b: Iterable): Int { - val ia = a.iterator() - val ib = b.iterator() - while (true) { - if (ia.hasNext() && !ib.hasNext()) return 1 - if (!ia.hasNext() && !ib.hasNext()) return 0 - if (!ia.hasNext()) return -1 - val compRes = compareValues(ia.next(), ib.next()) - if (compRes != 0) return compRes +data class ScriptDependencies( + val javaHome: File? = null, + val classpath: List = emptyList(), + val imports: List = emptyList(), + val sources: List = emptyList(), + val scripts: List = emptyList() +) { + companion object { + val Empty = ScriptDependencies() } -} - -private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn() \ No newline at end of file +} \ No newline at end of file diff --git a/core/script.runtime/src/kotlin/script/dependencies/experimental/AsyncDependenciesResolver.kt b/core/script.runtime/src/kotlin/script/dependencies/experimental/AsyncDependenciesResolver.kt new file mode 100644 index 00000000000..304b7cd8328 --- /dev/null +++ b/core/script.runtime/src/kotlin/script/dependencies/experimental/AsyncDependenciesResolver.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:Suppress("unused") + +package kotlin.script.dependencies.experimental + +import kotlin.script.dependencies.DependenciesResolver +import kotlin.script.dependencies.DependenciesResolver.ResolveResult +import kotlin.script.dependencies.Environment +import kotlin.script.dependencies.ScriptContents + +interface AsyncDependenciesResolver : DependenciesResolver { + suspend fun resolveAsync( + scriptContents: ScriptContents, environment: Environment + ): ResolveResult + + /* 'resolve' implementation is supposed to invoke resolveAsync in a blocking manner + * To avoid dependency on kotlinx-coroutines-core we leave this method unimplemented + * and provide 'resolve' implementation when loading resolver. + */ + override fun resolve(scriptContents: ScriptContents, environment: Environment): ResolveResult + = /*runBlocking { resolveAsync(scriptContents, environment) } */ throw NotImplementedError() +} diff --git a/core/script.runtime/src/kotlin/script/dependencies/resolvers.kt b/core/script.runtime/src/kotlin/script/dependencies/resolvers.kt index 9fd9cfc3ba6..d566a48db7f 100644 --- a/core/script.runtime/src/kotlin/script/dependencies/resolvers.kt +++ b/core/script.runtime/src/kotlin/script/dependencies/resolvers.kt @@ -19,36 +19,43 @@ package kotlin.script.dependencies import java.io.File -import java.util.concurrent.Future -import java.util.concurrent.TimeUnit +import kotlin.script.dependencies.DependenciesResolver.ResolveResult -interface ScriptDependenciesResolver { +typealias Environment = Map - enum class ReportSeverity { ERROR, WARNING, INFO, DEBUG } +interface DependenciesResolver { + fun resolve(scriptContents: ScriptContents, environment: Environment): ResolveResult - fun resolve(script: ScriptContents, - environment: Map?, - report: (ReportSeverity, String, ScriptContents.Position?) -> Unit, - previousDependencies: KotlinScriptExternalDependencies? - ): Future = PseudoFuture(null) + object NoDependencies : DependenciesResolver { + override fun resolve(scriptContents: ScriptContents, environment: Environment) = ScriptDependencies.Empty.asSuccess() + } + + sealed class ResolveResult { + abstract val dependencies: ScriptDependencies? + abstract val reports: List + + data class Success( + override val dependencies: ScriptDependencies, + override val reports: List = listOf() + ) : ResolveResult() + + data class Failure(override val reports: List) : ResolveResult() { + constructor(vararg reports: ScriptReport) : this(reports.asList()) + + override val dependencies: ScriptDependencies? get() = null + } + } } -class BasicScriptDependenciesResolver : ScriptDependenciesResolver interface ScriptContents { - - data class Position(val line: Int, val col: Int) - val file: File? val annotations: Iterable val text: CharSequence? } -fun KotlinScriptExternalDependencies?.asFuture(): PseudoFuture = PseudoFuture(this) - -class PseudoFuture(private val value: T): Future { - override fun get(): T = value - override fun get(p0: Long, p1: TimeUnit): T = value - override fun cancel(p0: Boolean): Boolean = false - override fun isDone(): Boolean = true - override fun isCancelled(): Boolean = false +data class ScriptReport(val message: String, val severity: Severity = ScriptReport.Severity.ERROR, val position: Position? = null) { + data class Position(val startLine: Int, val startColumn: Int, val endLine: Int? = null, val endColumn: Int? = null) + enum class Severity { ERROR, WARNING, INFO, DEBUG } } + +fun ScriptDependencies.asSuccess(): ResolveResult.Success = ResolveResult.Success(this) \ No newline at end of file diff --git a/core/script.runtime/src/kotlin/script/templates/annotations.kt b/core/script.runtime/src/kotlin/script/templates/annotations.kt index 8e31165a318..43392b340f5 100644 --- a/core/script.runtime/src/kotlin/script/templates/annotations.kt +++ b/core/script.runtime/src/kotlin/script/templates/annotations.kt @@ -19,14 +19,13 @@ package kotlin.script.templates import kotlin.reflect.KClass -import kotlin.script.dependencies.BasicScriptDependenciesResolver -import kotlin.script.dependencies.ScriptDependenciesResolver +import kotlin.script.dependencies.DependenciesResolver const val DEFAULT_SCRIPT_FILE_PATTERN = ".*\\.kts" @Target(AnnotationTarget.CLASS) @Retention(AnnotationRetention.RUNTIME) -annotation class ScriptTemplateDefinition(val resolver: KClass = BasicScriptDependenciesResolver::class, +annotation class ScriptTemplateDefinition(val resolver: KClass = DependenciesResolver.NoDependencies::class, val scriptFilePattern: String = DEFAULT_SCRIPT_FILE_PATTERN) @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)