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 b2efb62feae..3209de4e0bc 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 @@ -124,6 +124,8 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit updateDefinitions() } + fun getAllDefinitions() = currentDefinitions + override fun getDefaultScriptDefinition(): KotlinScriptDefinition { return StandardIdeScriptDefinition(project) } @@ -154,6 +156,12 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit // TODO: clear by script type/definition ServiceManager.getService(project, ScriptDependenciesCache::class.java).clear() + + ApplicationManager.getApplication().invokeLater { + if (!project.isDisposed) { + EditorNotifications.getInstance(project).updateAllNotifications() + } + } } private fun ScriptDefinitionContributor.safeGetDefinitions(): List { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt index 6594b569350..189ae41d17f 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/settings/KotlinScriptingSettings.kt @@ -19,6 +19,11 @@ import com.intellij.util.xmlb.XmlSerializerUtil class KotlinScriptingSettings : PersistentStateComponent { var isAutoReloadEnabled = false + /** + * true if notification about multiple script definition applicable for one script file is suppressed + */ + var suppressDefinitionsCheck = false + override fun loadState(state: KotlinScriptingSettings) { XmlSerializerUtil.copyBean(state, this) } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 3f93b5d4322..b3512a3f87e 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -417,6 +417,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.173 b/idea/src/META-INF/plugin.xml.173 index 399ebb0ef3c..256b1e38a3b 100644 --- a/idea/src/META-INF/plugin.xml.173 +++ b/idea/src/META-INF/plugin.xml.173 @@ -415,6 +415,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.181 b/idea/src/META-INF/plugin.xml.181 index 7f9845bcb5c..0e9e809ede4 100644 --- a/idea/src/META-INF/plugin.xml.181 +++ b/idea/src/META-INF/plugin.xml.181 @@ -416,6 +416,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.183 b/idea/src/META-INF/plugin.xml.183 index 44c890a5623..5a50fccd254 100644 --- a/idea/src/META-INF/plugin.xml.183 +++ b/idea/src/META-INF/plugin.xml.183 @@ -417,6 +417,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.as31 b/idea/src/META-INF/plugin.xml.as31 index adf5bfbfcf9..a640de6f8b8 100644 --- a/idea/src/META-INF/plugin.xml.as31 +++ b/idea/src/META-INF/plugin.xml.as31 @@ -415,6 +415,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.as32 b/idea/src/META-INF/plugin.xml.as32 index ac1f7040445..470fadb80cb 100644 --- a/idea/src/META-INF/plugin.xml.as32 +++ b/idea/src/META-INF/plugin.xml.as32 @@ -415,6 +415,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/META-INF/plugin.xml.as33 b/idea/src/META-INF/plugin.xml.as33 index 21ab89b6a6e..ad0da1a23ca 100644 --- a/idea/src/META-INF/plugin.xml.as33 +++ b/idea/src/META-INF/plugin.xml.as33 @@ -416,6 +416,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + diff --git a/idea/src/org/jetbrains/kotlin/idea/script/configutation/MultipleScriptDefinitionsChecker.kt b/idea/src/org/jetbrains/kotlin/idea/script/configutation/MultipleScriptDefinitionsChecker.kt new file mode 100644 index 00000000000..d770514bcc7 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/script/configutation/MultipleScriptDefinitionsChecker.kt @@ -0,0 +1,96 @@ +/* + * 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.configutation + +import com.intellij.openapi.fileEditor.FileEditor +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.popup.JBPopupFactory +import com.intellij.openapi.ui.popup.util.BaseListPopupStep +import com.intellij.openapi.util.Key +import com.intellij.openapi.util.Ref +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiManager +import com.intellij.ui.EditorNotificationPanel +import com.intellij.ui.EditorNotifications +import com.intellij.ui.HyperlinkLabel +import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager +import org.jetbrains.kotlin.idea.core.script.StandardIdeScriptDefinition +import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings +import org.jetbrains.kotlin.parsing.KotlinParserDefinition +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.script.KotlinScriptDefinition +import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate +import org.jetbrains.kotlin.scripting.compiler.plugin.KotlinScriptDefinitionAdapterFromNewAPIBase + +class MultipleScriptDefinitionsChecker(private val project: Project) : EditorNotifications.Provider() { + + override fun getKey(): Key = + KEY + + override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor): EditorNotificationPanel? { + if (file.fileType != KotlinFileType.INSTANCE) return null + + val ktFile = PsiManager.getInstance(project).findFile(file) as? KtFile ?: return null + + if (!ktFile.isScript()) return null + if (KotlinScriptingSettings.getInstance(ktFile.project).suppressDefinitionsCheck) return null + + val allApplicableDefinitions = ScriptDefinitionsManager.getInstance(project) + .getAllDefinitions() + .filter { it !is StandardIdeScriptDefinition && it.isScript(ktFile.name) } + .toList() + if (allApplicableDefinitions.size < 2) return null + + return createNotification( + ktFile, + allApplicableDefinitions + ) + } + + companion object { + private val KEY = Key.create("MultipleScriptDefinitionsChecker") + + private fun createNotification(psiFile: KtFile, defs: List): EditorNotificationPanel { + return EditorNotificationPanel().apply { + setText("Multiple script definitions are applicable for this script. ${defs.first().name} is used") + createComponentActionLabel("Show all") { + val list = JBPopupFactory.getInstance().createListPopup( + object : BaseListPopupStep(null, defs) { + override fun getTextFor(value: KotlinScriptDefinition): String { + return when (value) { + is KotlinScriptDefinitionFromAnnotatedTemplate -> { + value.name + " (${value.scriptFilePattern})" + } + is KotlinScriptDefinitionAdapterFromNewAPIBase -> { + value.name + " (${value.fileExtension})" + } + is StandardIdeScriptDefinition -> { + value.name + " (${KotlinParserDefinition.STD_SCRIPT_EXT})" + } + else -> value.name + } + } + } + ) + list.showUnderneathOf(it) + } + + createComponentActionLabel("Ignore") { + KotlinScriptingSettings.getInstance(psiFile.project).suppressDefinitionsCheck = true + EditorNotifications.getInstance(psiFile.project).updateAllNotifications() + } + } + } + + private fun EditorNotificationPanel.createComponentActionLabel(labelText: String, callback: (HyperlinkLabel) -> Unit) { + val label: Ref = Ref.create() + label.set(createActionLabel(labelText) { + callback(label.get()) + }) + } + } +} \ No newline at end of file