From 0e66c64a17ba63d07b9f05d3727602a43c7544f7 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Mon, 8 Oct 2018 15:01:49 +0200 Subject: [PATCH] Implement new minimal extension point for providing (new) script definitions to idea #KT-27817 fixed --- idea/build.gradle.kts | 1 + idea/build.gradle.kts.173 | 1 + idea/build.gradle.kts.as31 | 1 + idea/build.gradle.kts.as32 | 1 + idea/build.gradle.kts.as33 | 1 + idea/src/META-INF/extensions/ide.xml | 8 +++ idea/src/META-INF/extensions/ide.xml.as33 | 8 +++ .../script/BridgeDefinitionsContributor.kt | 62 +++++++++++++++++++ libraries/scripting/intellij/build.gradle.kts | 26 ++++++++ .../intellij/scriptDefinitionProvider.kt | 27 ++++++++ .../scripting/scripting-idea/build.gradle.kts | 1 + settings.gradle | 2 + 12 files changed, 139 insertions(+) create mode 100644 idea/src/org/jetbrains/kotlin/idea/script/BridgeDefinitionsContributor.kt create mode 100644 libraries/scripting/intellij/build.gradle.kts create mode 100644 libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptDefinitionProvider.kt diff --git a/idea/build.gradle.kts b/idea/build.gradle.kts index a6e03876ba3..d65db545f01 100644 --- a/idea/build.gradle.kts +++ b/idea/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":kotlin-script-util")) { isTransitive = false } + compile(project(":kotlin-scripting-intellij")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } diff --git a/idea/build.gradle.kts.173 b/idea/build.gradle.kts.173 index c36ffc32100..5d98846ecc4 100644 --- a/idea/build.gradle.kts.173 +++ b/idea/build.gradle.kts.173 @@ -40,6 +40,7 @@ dependencies { compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":kotlin-script-util")) { isTransitive = false } + compile(project(":kotlin-scripting-intellij")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } diff --git a/idea/build.gradle.kts.as31 b/idea/build.gradle.kts.as31 index 519ba238a8f..cdc92ab3e0a 100644 --- a/idea/build.gradle.kts.as31 +++ b/idea/build.gradle.kts.as31 @@ -40,6 +40,7 @@ dependencies { compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":kotlin-script-util")) { isTransitive = false } + compile(project(":kotlin-scripting-intellij")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } diff --git a/idea/build.gradle.kts.as32 b/idea/build.gradle.kts.as32 index 14d84220a30..90db9b4d759 100644 --- a/idea/build.gradle.kts.as32 +++ b/idea/build.gradle.kts.as32 @@ -40,6 +40,7 @@ dependencies { compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":kotlin-script-util")) { isTransitive = false } + compile(project(":kotlin-scripting-intellij")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } diff --git a/idea/build.gradle.kts.as33 b/idea/build.gradle.kts.as33 index e7f3bc5e079..b7a7e7639b2 100644 --- a/idea/build.gradle.kts.as33 +++ b/idea/build.gradle.kts.as33 @@ -40,6 +40,7 @@ dependencies { compile(project(":plugins:uast-kotlin")) compile(project(":plugins:uast-kotlin-idea")) compile(project(":kotlin-script-util")) { isTransitive = false } + compile(project(":kotlin-scripting-intellij")) compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false } diff --git a/idea/src/META-INF/extensions/ide.xml b/idea/src/META-INF/extensions/ide.xml index dab08bc7768..0b7d11f1236 100644 --- a/idea/src/META-INF/extensions/ide.xml +++ b/idea/src/META-INF/extensions/ide.xml @@ -46,6 +46,10 @@ + + @@ -56,6 +60,10 @@ id="ScriptTemplatesFromCompilerSettingsProvider" implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromCompilerSettingsProvider"/> + + diff --git a/idea/src/META-INF/extensions/ide.xml.as33 b/idea/src/META-INF/extensions/ide.xml.as33 index f26b1fcd33b..d7fa2a47c4a 100644 --- a/idea/src/META-INF/extensions/ide.xml.as33 +++ b/idea/src/META-INF/extensions/ide.xml.as33 @@ -38,6 +38,10 @@ + + @@ -48,6 +52,10 @@ id="ScriptTemplatesFromCompilerSettingsProvider" implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromCompilerSettingsProvider"/> + + diff --git a/idea/src/org/jetbrains/kotlin/idea/script/BridgeDefinitionsContributor.kt b/idea/src/org/jetbrains/kotlin/idea/script/BridgeDefinitionsContributor.kt new file mode 100644 index 00000000000..1ef330fd845 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/script/BridgeDefinitionsContributor.kt @@ -0,0 +1,62 @@ +/* + * 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 org.jetbrains.kotlin.idea.script + +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor +import org.jetbrains.kotlin.idea.core.script.loadDefinitionsFromTemplates +import org.jetbrains.kotlin.script.KotlinScriptDefinition +import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptDefinitionsFromClasspathDiscoverySource +import kotlin.script.experimental.intellij.ScriptDefinitionsProvider + +class BridgeScriptDefinitionsContributor(private val project: Project) : ScriptDefinitionContributor { + override val id: String = "BridgeScriptDefinitionsContributor" + + override fun getDefinitions(): List { + val extensions = Extensions.getArea(project).getExtensionPoint(ScriptDefinitionsProvider.EP_NAME).extensions + val messageCollector = LoggingMessageCollector() + return extensions.flatMap { provider -> + val explicitClasses = provider.getDefinitionClasses().toList() + val classPath = provider.getDefinitionsClassPath().toList() + val explicitDefinitions = + if (explicitClasses.isNotEmpty()) loadDefinitionsFromTemplates(explicitClasses, classPath) + else emptyList() + val discoveredDefinitions = + if (provider.useDiscovery()) emptySequence() + else ScriptDefinitionsFromClasspathDiscoverySource(classPath, emptyMap(), messageCollector).definitions + explicitDefinitions + discoveredDefinitions + } + } +} + +private class LoggingMessageCollector : MessageCollector { + + private val log = Logger.getInstance("ScriptDefinitionsProviders") + + private var hasErrors = false + + override fun clear() { + hasErrors = false + } + + override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) { + when (severity) { + CompilerMessageSeverity.ERROR, CompilerMessageSeverity.EXCEPTION -> { + log.error(message) + hasErrors = true + } + CompilerMessageSeverity.WARNING, CompilerMessageSeverity.STRONG_WARNING -> log.warn(message) + else -> log.info(message) + } + } + + override fun hasErrors(): Boolean = hasErrors +} diff --git a/libraries/scripting/intellij/build.gradle.kts b/libraries/scripting/intellij/build.gradle.kts new file mode 100644 index 00000000000..2a0c4a390c7 --- /dev/null +++ b/libraries/scripting/intellij/build.gradle.kts @@ -0,0 +1,26 @@ + +plugins { + kotlin("jvm") + id("jps-compatible") +} + +jvmTarget = "1.6" + +dependencies { + compile(project(":kotlin-script-runtime")) + compile(project(":kotlin-stdlib")) + compile(project(":kotlin-scripting-common")) + compileOnly(intellijCoreDep()) { includeJars("intellij-core") } +} + +sourceSets { + "main" { projectDefault() } + "test" { } +} + +standardPublicJars() + +ideaPlugin() + +publish() + diff --git a/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptDefinitionProvider.kt b/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptDefinitionProvider.kt new file mode 100644 index 00000000000..b2ef64cbabf --- /dev/null +++ b/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptDefinitionProvider.kt @@ -0,0 +1,27 @@ +/* + * 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.intellij + +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.extensions.Extensions +import com.intellij.openapi.project.Project +import java.io.File + +interface ScriptDefinitionsProvider { + val id: String + + fun getDefinitionClasses(): Iterable + + fun getDefinitionsClassPath(): Iterable + + fun useDiscovery(): Boolean + + companion object { + val EP_NAME: ExtensionPointName = + ExtensionPointName.create("org.jetbrains.kotlin.scriptDefinitionsProvider") + } + +} diff --git a/plugins/scripting/scripting-idea/build.gradle.kts b/plugins/scripting/scripting-idea/build.gradle.kts index 241f6e32f2d..0509fa7da37 100644 --- a/plugins/scripting/scripting-idea/build.gradle.kts +++ b/plugins/scripting/scripting-idea/build.gradle.kts @@ -8,6 +8,7 @@ plugins { dependencies { compile(project(":kotlin-scripting-compiler")) + compile(project(":kotlin-scripting-intellij")) compileOnly(project(":idea:idea-gradle")) compileOnly(project(":idea:idea-core")) compileOnly(intellijDep()) diff --git a/settings.gradle b/settings.gradle index ba57fae5bdf..ac8e42fc6a2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -172,6 +172,7 @@ include ":kotlin-build-common", ":kotlin-scripting-common", ":kotlin-scripting-jvm", ":kotlin-scripting-jvm-host", + ":kotlin-scripting-intellij", ":kotlin-scripting-compiler", ":kotlin-scripting-idea", ":kotlin-scripting-compiler-embeddable", @@ -293,6 +294,7 @@ project(':kotlin-annotations-android').projectDir = "$rootDir/libraries/tools/ko project(':kotlin-scripting-common').projectDir = "$rootDir/libraries/scripting/common" 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-intellij').projectDir = "$rootDir/libraries/scripting/intellij" as File project(':kotlin-scripting-compiler').projectDir = "$rootDir/plugins/scripting/scripting-cli" as File project(':kotlin-scripting-compiler-embeddable').projectDir = "$rootDir/plugins/scripting/scripting-embeddable" as File project(':kotlin-scripting-idea').projectDir = "$rootDir/plugins/scripting/scripting-idea" as File