Update project code to use new script.runtime APIs

This commit is contained in:
Pavel V. Talanov
2017-06-22 23:14:16 +03:00
parent 375b058a28
commit 65dba3615c
14 changed files with 191 additions and 241 deletions
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.script
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.psi.KtScript
@@ -28,15 +26,13 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.primaryConstructor
import kotlin.script.dependencies.BasicScriptDependenciesResolver
import kotlin.script.dependencies.KotlinScriptExternalDependencies
import kotlin.script.dependencies.ScriptContents
import kotlin.script.dependencies.DependenciesResolver
import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.templates.AcceptedAnnotations
open class KotlinScriptDefinitionFromAnnotatedTemplate(
template: KClass<out Any>,
providedResolver: ScriptDependenciesResolver? = null,
providedResolver: DependenciesResolver? = null,
providedScriptFilePattern: String? = null,
val environment: Map<String, Any?>? = null
) : KotlinScriptDefinition(template) {
@@ -48,38 +44,45 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
?: DEFAULT_SCRIPT_FILE_PATTERN
}
override val dependencyResolver: ScriptDependenciesResolver by lazy {
override val dependencyResolver: DependenciesResolver by lazy {
computeResolver(template, providedResolver)
}
private fun computeResolver(
template: KClass<out Any>,
providedResolver: DependenciesResolver?
): @Suppress("DEPRECATION") DependenciesResolver {
val defAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() } }
val legacyDefAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>() } }
when {
providedResolver != null -> providedResolver
// TODO: logScriptDefMessage missing or invalid constructor
defAnn != null ->
try {
defAnn.resolver.primaryConstructor?.call() ?: null.apply {
log.warn("[kts] No default constructor found for ${defAnn.resolver.qualifiedName}")
}
}
catch (ex: ClassCastException) {
log.warn("[kts] Script def error ${ex.message}")
null
}
legacyDefAnn != null ->
try {
log.warn("[kts] Deprecated annotations on the script template are used, please update the provider")
legacyDefAnn.resolver.primaryConstructor?.call()?.let {
LegacyScriptDependenciesResolverWrapper(it)
}
?: null.apply {
log.warn("[kts] No default constructor found for ${legacyDefAnn.resolver.qualifiedName}")
}
}
catch (ex: ClassCastException) {
log.warn("[kts] Script def error ${ex.message}")
null
}
else -> null
} ?: BasicScriptDependenciesResolver()
val legacyDefAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>() } }
return when {
providedResolver != null -> providedResolver
// TODO: logScriptDefMessage missing or invalid constructor
defAnn != null ->
try {
defAnn.resolver.primaryConstructor?.call() as? DependenciesResolver ?: null.apply {
log.warn("[kts] No default constructor found for ${defAnn.resolver.qualifiedName}")
}
}
catch (ex: ClassCastException) {
log.warn("[kts] Script def error ${ex.message}")
null
}
legacyDefAnn != null ->
try {
log.warn("[kts] Deprecated annotations on the script template are used, please update the provider")
legacyDefAnn.resolver.primaryConstructor?.call()?.let {
LegacyScriptDependenciesResolverWrapper(it)
}
?: null.apply {
log.warn("[kts] No default constructor found for ${legacyDefAnn.resolver.qualifiedName}")
}
}
catch (ex: ClassCastException) {
log.warn("[kts] Script def error ${ex.message}")
null
}
else -> null
} ?: DependenciesResolver.NoDependencies
}
val samWithReceiverAnnotations: List<String>? by lazy {
@@ -116,8 +119,6 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
// TODO: implement other strategy - e.g. try to extract something from match with ScriptFilePattern
override fun getScriptName(script: KtScript): Name = NameUtils.getScriptNameForFile(script.containingKtFile.name)
override fun getDependenciesFor(file: VirtualFile, project: Project, previousDependencies: KotlinScriptExternalDependencies?) = error("Should not be called")
override fun toString(): String = "KotlinScriptDefinitionFromAnnotatedTemplate - ${template.simpleName}"
override val annotationsForSamWithReceivers: List<String>
@@ -140,21 +141,4 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
companion object {
internal val log = Logger.getInstance(KotlinScriptDefinitionFromAnnotatedTemplate::class.java)
}
}
internal fun logScriptDefMessage(reportSeverity: ScriptDependenciesResolver.ReportSeverity, s: String, position: ScriptContents.Position?): Unit {
val msg = (position?.run { "[at $line:$col]" } ?: "") + s
when (reportSeverity) {
ScriptDependenciesResolver.ReportSeverity.ERROR -> KotlinScriptDefinitionFromAnnotatedTemplate.log.error(msg)
ScriptDependenciesResolver.ReportSeverity.WARNING -> KotlinScriptDefinitionFromAnnotatedTemplate.log.warn(msg)
ScriptDependenciesResolver.ReportSeverity.INFO -> KotlinScriptDefinitionFromAnnotatedTemplate.log.info(msg)
ScriptDependenciesResolver.ReportSeverity.DEBUG -> KotlinScriptDefinitionFromAnnotatedTemplate.log.debug(msg)
}
}
internal fun sameSignature(left: KFunction<*>, right: KFunction<*>): Boolean =
left.parameters.size == right.parameters.size &&
left.parameters.zip(right.parameters).all {
it.first.kind == KParameter.Kind.INSTANCE ||
it.first.type == it.second.type
}
}
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
import kotlin.reflect.KClass
import kotlin.script.dependencies.KotlinScriptExternalDependencies
import kotlin.script.dependencies.ScriptContents
import kotlin.script.dependencies.ScriptDependencies
abstract class KotlinScriptExternalImportsProviderBase(private val project: Project): KotlinScriptExternalImportsProvider {
fun getScriptContents(scriptDefinition: KotlinScriptDefinition, file: VirtualFile)
@@ -58,16 +58,13 @@ abstract class KotlinScriptExternalImportsProviderBase(private val project: Proj
fun resolveDependencies(
scriptDef: KotlinScriptDefinition,
file: VirtualFile,
oldDependencies: KotlinScriptExternalDependencies? = null
): KotlinScriptExternalDependencies? {
file: VirtualFile
): ScriptDependencies? {
val scriptContents = getScriptContents(scriptDef, file)
return scriptDef.dependencyResolver.resolve(
scriptContents,
(scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.environment,
{ _, _, _ -> Unit }, // TODO_R:
oldDependencies
).get()
(scriptDef as? KotlinScriptDefinitionFromAnnotatedTemplate)?.environment ?: emptyMap()
).dependencies
}
}
@@ -20,6 +20,9 @@ import java.io.File
import java.util.concurrent.Future
import java.util.concurrent.TimeUnit
import kotlin.reflect.KClass
import kotlin.script.dependencies.DependenciesResolver.ResolveResult
import kotlin.script.dependencies.ScriptDependencies
import kotlin.script.dependencies.ScriptReport
const val DEFAULT_SCRIPT_FILE_PATTERN = ".*\\.kts"
@@ -115,41 +118,42 @@ private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>):
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()
class LegacyScriptDependenciesResolverWrapper(val legacyResolver: ScriptDependenciesResolver) : kotlin.script.dependencies.ScriptDependenciesResolver {
@Suppress("DEPRECATION")
class LegacyScriptDependenciesResolverWrapper(val legacyResolver: ScriptDependenciesResolver) : kotlin.script.dependencies.DependenciesResolver {
override fun resolve(script: kotlin.script.dependencies.ScriptContents,
environment: Map<String, Any?>?,
report: (kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity, String, kotlin.script.dependencies.ScriptContents.Position?) -> Unit,
previousDependencies: kotlin.script.dependencies.KotlinScriptExternalDependencies?
): Future<kotlin.script.dependencies.KotlinScriptExternalDependencies?> {
override fun resolve(
scriptContents: kotlin.script.dependencies.ScriptContents,
environment: Map<String, Any?>
): ResolveResult {
val reports = ArrayList<ScriptReport>()
val legacyDeps = legacyResolver.resolve(
object : ScriptContents {
override val file: File? get() = script.file
override val annotations: Iterable<Annotation> get() = script.annotations
override val text: CharSequence? get() = script.text
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 -> report(kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.values()[sev.ordinal],
msg,
pos?.let { kotlin.script.dependencies.ScriptContents.Position(it.line, it.col) }) },
previousDependencies?.let {
object : KotlinScriptExternalDependencies {
override val javaHome get() = it.javaHome
override val classpath get() = it.classpath
override val imports get() = it.imports
override val sources get() = it.sources
override val scripts get() = it.scripts
}
}
).get()
return kotlin.script.dependencies.PseudoFuture(legacyDeps?.let {
object : kotlin.script.dependencies.KotlinScriptExternalDependencies {
override val javaHome get() = it.javaHome
override val classpath get() = it.classpath
override val imports get() = it.imports
override val sources get() = it.sources
override val scripts get() = it.scripts
}
})
{ sev, msg, pos ->
reports.add(ScriptReport(msg, sev.convertSeverity(), pos?.convertPosition()))
}, null
).get() ?: return ResolveResult.Failure()
val dependencies = ScriptDependencies(
javaHome = legacyDeps.javaHome?.let(::File),
classpath = legacyDeps.classpath.toList(),
imports = legacyDeps.imports.toList(),
sources = legacyDeps.sources.toList(),
scripts = legacyDeps.scripts.toList()
)
return ResolveResult.Success(dependencies, reports)
}
private fun ScriptDependenciesResolver.ReportSeverity.convertSeverity(): ScriptReport.Severity = when(this) {
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)
}
@@ -22,7 +22,7 @@ import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import java.io.File
import java.net.URLClassLoader
import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.dependencies.DependenciesResolver
interface ScriptTemplatesProvider {
@@ -38,7 +38,7 @@ interface ScriptTemplatesProvider {
val templateClassNames: Iterable<String>
val resolver: ScriptDependenciesResolver? get() = null
val resolver: DependenciesResolver? get() = null
val filePattern: String? get() = null