Drop long deprecated legacy script annotations and resolvers support

This commit is contained in:
Ilya Chernikov
2019-02-22 19:17:50 +01:00
parent 4f135a5fe5
commit f71cc4e480
7 changed files with 64 additions and 254 deletions
@@ -54,20 +54,9 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
override val dependencyResolver: DependenciesResolver by lazy(LazyThreadSafetyMode.PUBLICATION) {
resolverFromAnnotation(template) ?:
resolverFromLegacyAnnotation(template) ?:
DependenciesResolver.NoDependencies
}
private fun resolverFromLegacyAnnotation(template: KClass<out Any>): DependenciesResolver? {
val legacyDefAnn = takeUnlessError {
template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>()
} ?: return null
log.warn("[kts] Deprecated annotations on the script template are used, please update the provider")
return instantiateResolver(legacyDefAnn.resolver)?.let(::LegacyPackageDependencyResolverWrapper)
}
private fun resolverFromAnnotation(template: KClass<out Any>): DependenciesResolver? {
val defAnn = takeUnlessError {
template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>()
@@ -101,7 +90,6 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
private val samWithReceiverAnnotations: List<String>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.extensions.SamWithReceiverAnnotations>()?.annotations?.toList() }
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.SamWithReceiverAnnotations>()?.annotations?.toList() }
}
override val acceptedAnnotations: List<KClass<out Annotation>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
@@ -1,119 +0,0 @@
/*
* 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("DEPRECATION")
package org.jetbrains.kotlin.script
import java.io.File
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.dependencies.Environment
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.dependencies.ScriptReport
interface LegacyResolverWrapper
// NOTE: not implementing resolver wrapper since it was not implemented initially and this is deprecated API
@Deprecated("Compatibility with deprecated API")
internal class LegacyPackageDependencyResolverWrapper(
val legacyResolver: ScriptDependenciesResolver
) : kotlin.script.experimental.dependencies.DependenciesResolver, LegacyResolverWrapper {
private var previousDependencies: org.jetbrains.kotlin.script.KotlinScriptExternalDependencies? = null
override fun resolve(
scriptContents: kotlin.script.dependencies.ScriptContents,
environment: Environment
): DependenciesResolver.ResolveResult {
val reports = ArrayList<ScriptReport>()
val legacyDeps = legacyResolver.resolve(
object : ScriptContents {
override val file: File? get() = scriptContents.file
override val annotations: Iterable<Annotation> get() = scriptContents.annotations
override val text: CharSequence? get() = scriptContents.text
},
environment,
{ sev, msg, pos ->
reports.add(ScriptReport(msg, sev.convertSeverity(), pos?.convertPosition()))
},
previousDependencies
).get() ?: return DependenciesResolver.ResolveResult.Failure(reports)
val dependencies = ScriptDependencies(
javaHome = legacyDeps.javaHome?.let(::File),
classpath = legacyDeps.classpath.toList(),
imports = legacyDeps.imports.toList(),
sources = legacyDeps.sources.toList(),
scripts = legacyDeps.scripts.toList()
)
previousDependencies = legacyDeps
return DependenciesResolver.ResolveResult.Success(dependencies, reports)
}
private fun ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when(this) {
ScriptDependenciesResolver.ReportSeverity.FATAL -> ScriptReport.Severity.FATAL
ScriptDependenciesResolver.ReportSeverity.ERROR -> ScriptReport.Severity.ERROR
ScriptDependenciesResolver.ReportSeverity.WARNING -> ScriptReport.Severity.WARNING
ScriptDependenciesResolver.ReportSeverity.INFO -> ScriptReport.Severity.INFO
ScriptDependenciesResolver.ReportSeverity.DEBUG -> ScriptReport.Severity.DEBUG
}
private fun ScriptContents.Position.convertPosition(): ScriptReport.Position = ScriptReport.Position(line, col)
}
internal class ApiChangeDependencyResolverWrapper(
override val delegate: kotlin.script.dependencies.ScriptDependenciesResolver
) : kotlin.script.experimental.dependencies.DependenciesResolver,
DependencyResolverWrapper<kotlin.script.dependencies.ScriptDependenciesResolver>,
LegacyResolverWrapper {
private var previousDependencies: kotlin.script.dependencies.KotlinScriptExternalDependencies? = null
override fun resolve(
scriptContents: kotlin.script.dependencies.ScriptContents,
environment: Environment
): DependenciesResolver.ResolveResult {
val reports = ArrayList<ScriptReport>()
val legacyDeps = delegate.resolve(
scriptContents,
environment,
{ sev, msg, pos ->
reports.add(ScriptReport(msg, sev.convertSeverity(), pos?.convertPosition()))
},
previousDependencies
).get() ?: return DependenciesResolver.ResolveResult.Failure(reports)
val dependencies = ScriptDependencies(
javaHome = legacyDeps.javaHome?.let(::File),
classpath = legacyDeps.classpath.toList(),
imports = legacyDeps.imports.toList(),
sources = legacyDeps.sources.toList(),
scripts = legacyDeps.scripts.toList()
)
previousDependencies = legacyDeps
return DependenciesResolver.ResolveResult.Success(dependencies, reports)
}
private fun kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when (this) {
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.FATAL -> ScriptReport.Severity.FATAL
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.ERROR -> ScriptReport.Severity.ERROR
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.WARNING -> ScriptReport.Severity.WARNING
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.INFO -> ScriptReport.Severity.INFO
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.DEBUG -> ScriptReport.Severity.DEBUG
}
private fun kotlin.script.dependencies.ScriptContents.Position.convertPosition(): ScriptReport.Position = ScriptReport.Position(line, col)
}
@@ -1,117 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.script
import java.io.File
import java.util.concurrent.Future
import java.util.concurrent.TimeUnit
import kotlin.reflect.KClass
const val DEFAULT_SCRIPT_FILE_PATTERN = ".*\\.kts"
// TODO: remove this file and all the usages after releasing GSK 1.0
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.templatesScriptTemplateDefinition instead",
replaceWith = ReplaceWith("kotlin.script.templates.ScriptTemplateDefinition"))
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class ScriptTemplateDefinition(val resolver: KClass<out ScriptDependenciesResolver>,
val scriptFilePattern: String = DEFAULT_SCRIPT_FILE_PATTERN)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.extensions.SamWithReceiverAnnotations instead",
replaceWith = ReplaceWith("kotlin.script.extensions.SamWithReceiverAnnotations"))
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class SamWithReceiverAnnotations(vararg val annotations: String)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptContents instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptContents"))
interface ScriptContents {
data class Position(val line: Int, val col: Int)
val file: File?
val annotations: Iterable<Annotation>
val text: CharSequence?
}
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.PseudoFuture instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.PseudoFuture"))
class PseudoFuture<T>(private val value: T): Future<T> {
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
}
fun KotlinScriptExternalDependencies?.asFuture(): PseudoFuture<KotlinScriptExternalDependencies?> = PseudoFuture(this)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
interface ScriptDependenciesResolver {
enum class ReportSeverity { FATAL, ERROR, WARNING, INFO, DEBUG }
fun resolve(script: ScriptContents,
environment: Map<String, Any?>?,
report: (ReportSeverity, String, ScriptContents.Position?) -> Unit,
previousDependencies: KotlinScriptExternalDependencies?
): Future<KotlinScriptExternalDependencies?> = PseudoFuture(null)
}
@Suppress("unused")
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
interface ScriptDependenciesResolverEx {
fun resolve(script: ScriptContents,
environment: Map<String, Any?>?,
previousDependencies: KotlinScriptExternalDependencies?
): KotlinScriptExternalDependencies? = null
}
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.KotlinScriptExternalDependencies instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.KotlinScriptExternalDependencies"))
interface KotlinScriptExternalDependencies : Comparable<KotlinScriptExternalDependencies> {
val javaHome: String? get() = null
val classpath: Iterable<File> get() = emptyList()
val imports: Iterable<String> get() = emptyList()
val sources: Iterable<File> get() = emptyList()
val scripts: Iterable<File> 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) }
}
private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>): 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
}
}
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()
@@ -239,8 +239,7 @@ fun loadDefinitionsFromTemplates(
// as a compatibility measure, the asm based reading of annotations should be implemented to filter classes before classloading
val template = loader.loadClass(templateClassName).kotlin
when {
template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>() != null ||
template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() != null -> {
template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() != null -> {
KotlinScriptDefinitionFromAnnotatedTemplate(
template,
environment,
@@ -40,10 +40,8 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.LegacyResolverWrapper
import org.jetbrains.kotlin.scripting.shared.definitions.findScriptDefinition
import org.jetbrains.kotlin.scripting.shared.definitions.scriptDefinition
import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
import kotlin.script.experimental.dependencies.ScriptDependencies
class ScriptDependenciesUpdater(
@@ -16,7 +16,6 @@ import kotlinx.coroutines.Runnable
import kotlinx.coroutines.runBlocking
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.LegacyResolverWrapper
import org.jetbrains.kotlin.script.asResolveFailure
import org.jetbrains.kotlin.scripting.shared.definitions.findScriptDefinition
import java.util.concurrent.ConcurrentLinkedQueue
@@ -89,7 +88,7 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr
return if (dependenciesResolver is AsyncDependenciesResolver) {
dependenciesResolver.resolveAsync(scriptContents, environment)
} else {
assert(dependenciesResolver is LegacyResolverWrapper)
// TODO: shouldn't come here after dropping legacy resolvers, refactor accordingly
dependenciesResolver.resolve(scriptContents, environment)
}
}
@@ -0,0 +1,62 @@
/*
* Copyright 2010-2019 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("DEPRECATION")
package org.jetbrains.kotlin.scripting.shared.resolve
import org.jetbrains.kotlin.script.DependencyResolverWrapper
import java.io.File
import kotlin.script.dependencies.Environment
import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.dependencies.ScriptReport
interface LegacyResolverWrapper
class ApiChangeDependencyResolverWrapper(
override val delegate: kotlin.script.dependencies.ScriptDependenciesResolver
) : kotlin.script.experimental.dependencies.DependenciesResolver,
DependencyResolverWrapper<ScriptDependenciesResolver>,
LegacyResolverWrapper {
private var previousDependencies: kotlin.script.dependencies.KotlinScriptExternalDependencies? = null
override fun resolve(
scriptContents: kotlin.script.dependencies.ScriptContents,
environment: Environment
): DependenciesResolver.ResolveResult {
val reports = ArrayList<ScriptReport>()
val legacyDeps = delegate.resolve(
scriptContents,
environment,
{ sev, msg, pos ->
reports.add(ScriptReport(msg, sev.convertSeverity(), pos?.convertPosition()))
},
previousDependencies
).get() ?: return DependenciesResolver.ResolveResult.Failure(reports)
val dependencies = ScriptDependencies(
javaHome = legacyDeps.javaHome?.let(::File),
classpath = legacyDeps.classpath.toList(),
imports = legacyDeps.imports.toList(),
sources = legacyDeps.sources.toList(),
scripts = legacyDeps.scripts.toList()
)
previousDependencies = legacyDeps
return DependenciesResolver.ResolveResult.Success(dependencies, reports)
}
private fun kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when (this) {
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.FATAL -> ScriptReport.Severity.FATAL
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.ERROR -> ScriptReport.Severity.ERROR
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.WARNING -> ScriptReport.Severity.WARNING
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.INFO -> ScriptReport.Severity.INFO
kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.DEBUG -> ScriptReport.Severity.DEBUG
}
private fun kotlin.script.dependencies.ScriptContents.Position.convertPosition(): ScriptReport.Position = ScriptReport.Position(line, col)
}