diff --git a/compiler/frontend.script/build.gradle.kts b/compiler/frontend.script/build.gradle.kts index 733e344f803..f3a8ecc328c 100644 --- a/compiler/frontend.script/build.gradle.kts +++ b/compiler/frontend.script/build.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.gradle.dsl.Coroutines plugins { kotlin("jvm") @@ -9,6 +10,8 @@ jvmTarget = "1.6" dependencies { compile(project(":compiler:util")) compile(project(":compiler:frontend")) + compile(project(":kotlin-scripting-common")) + compile(project(":kotlin-scripting-jvm")) compile(projectDist(":kotlin-stdlib")) compileOnly(project(":kotlin-reflect-api")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } @@ -21,3 +24,6 @@ sourceSets { "test" {} } +kotlin { + experimental.coroutines = Coroutines.ENABLE +} \ No newline at end of file diff --git a/compiler/frontend.script/src/org/jetbrains/kotlin/script/experimental/scriptDefinitions.kt b/compiler/frontend.script/src/org/jetbrains/kotlin/script/experimental/scriptDefinitions.kt new file mode 100644 index 00000000000..a373224c76d --- /dev/null +++ b/compiler/frontend.script/src/org/jetbrains/kotlin/script/experimental/scriptDefinitions.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.script.experimental + +import com.intellij.openapi.fileTypes.LanguageFileType +import kotlinx.coroutines.experimental.runBlocking +import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.NameUtils +import org.jetbrains.kotlin.psi.KtScript +import org.jetbrains.kotlin.script.KotlinScriptDefinition +import kotlin.reflect.KClass +import kotlin.script.experimental.api.ScriptCompileConfigurationParams +import kotlin.script.experimental.api.ScriptDefinition +import kotlin.script.experimental.api.getOrNull +import kotlin.script.experimental.api.resultOrNull +import kotlin.script.experimental.dependencies.DependenciesResolver +import kotlin.script.experimental.jvm.impl.BridgeDependenciesResolver + +class KotlinScriptDefinitionAdapterFromNewAPI(val scriptDefinition: ScriptDefinition) : KotlinScriptDefinition(scriptDefinition.baseClass) { + + override val name: String get() = scriptDefinition.selector.name + + // TODO: consider creating separate type (subtype? for kotlin scripts) + override val fileType: LanguageFileType = KotlinFileType.INSTANCE + + override val annotationsForSamWithReceivers: List + get() = emptyList() + + override fun isScript(fileName: String): Boolean = + fileName.endsWith("." + scriptDefinition.selector.fileExtension) + + override fun getScriptName(script: KtScript): Name { + val fileBasedName = NameUtils.getScriptNameForFile(script.containingKtFile.name) + return Name.identifier(scriptDefinition.selector.makeScriptName(fileBasedName.identifier)) + } + + override val dependencyResolver: DependenciesResolver by lazy { + BridgeDependenciesResolver(scriptDefinition.configurator) + } + + override val acceptedAnnotations: List> by lazy { + runBlocking { + scriptDefinition.configurator.baseConfiguration(null) + }.resultOrNull()?.getOrNull(ScriptCompileConfigurationParams.updateConfigurationOnAnnotations)?.toList() + ?: emptyList() + } +} + + diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt index b4a1149e18f..668dd776b5d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDefinitionsManager.kt @@ -28,7 +28,9 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.script.ScriptDefinitionProvider import org.jetbrains.kotlin.script.ScriptTemplatesProvider +import org.jetbrains.kotlin.script.experimental.KotlinScriptDefinitionAdapterFromNewAPI import org.jetbrains.kotlin.utils.PathUtil +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.flattenTo import java.io.File import java.net.URLClassLoader @@ -37,6 +39,7 @@ import kotlin.concurrent.read import kotlin.concurrent.write import kotlin.script.dependencies.Environment import kotlin.script.dependencies.ScriptContents +import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass import kotlin.script.experimental.dependencies.DependenciesResolver import kotlin.script.experimental.dependencies.ScriptDependencies import kotlin.script.experimental.dependencies.asSuccess @@ -139,18 +142,31 @@ fun loadDefinitionsFromTemplates( * i.e. gradle resolver may depend on some jars that 'built.gradle.kts' files should not depend on. */ additionalResolverClasspath: List = emptyList() -): List = try { +): List = try { val classpath = templateClasspath + additionalResolverClasspath LOG.info("[kts] loading script definitions $templateClassNames using cp: ${classpath.joinToString(File.pathSeparator)}") val baseLoader = ScriptDefinitionContributor::class.java.classLoader val loader = if (classpath.isEmpty()) baseLoader else URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), baseLoader) - templateClassNames.map { - KotlinScriptDefinitionFromAnnotatedTemplate( - loader.loadClass(it).kotlin, - environment, - templateClasspath - ) + templateClassNames.mapNotNull { + val template = loader.loadClass(it).kotlin + when { + template.annotations.firstIsInstanceOrNull() != null || + template.annotations.firstIsInstanceOrNull() != null -> { + KotlinScriptDefinitionFromAnnotatedTemplate( + template, + environment, + templateClasspath + ) + } + template.annotations.firstIsInstanceOrNull() != null -> { + KotlinScriptDefinitionAdapterFromNewAPI(ScriptDefinitionFromAnnotatedBaseClass(template)) + } + else -> { + LOG.error("[kts] cannot find a valid script definition annotation on the class $template") + null + } + } } } catch (ex: Throwable) { @@ -208,4 +224,3 @@ class BundledKotlinScriptDependenciesResolver(private val project: Project) : De return jdk?.homePath } } - diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/GradleScriptTemplateProvider.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/GradleScriptTemplateProvider.kt index ea66d98dce2..96afa51278d 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/GradleScriptTemplateProvider.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/GradleScriptTemplateProvider.kt @@ -210,7 +210,10 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD additionalResolverClasspath(gradleLibDir) ).map { // Expand scope for old gradle script definition - if (!it.scriptExpectedLocations.contains(ScriptExpectedLocation.Project)) GradleKotlinScriptDefinitionFromAnnotatedTemplate(it) else it + if (it is KotlinScriptDefinitionFromAnnotatedTemplate && !it.scriptExpectedLocations.contains(ScriptExpectedLocation.Project)) + GradleKotlinScriptDefinitionFromAnnotatedTemplate(it) + else + it } }