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 119f2aba54b..e180791f3e7 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 @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.idea.core.script import com.intellij.execution.configurations.CommandLineTokenizer -import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskNotificationListenerAdapter import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType @@ -82,7 +81,7 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD } project.messageBus.connect(project).subscribe(GradleSettingsListener.TOPIC, listener) - ServiceManager.getService(project, ScriptModificationListener::class.java) + initializeScriptModificationListener(project) } override fun getDefinitions(): List { diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt index 268f4ff0850..69463033783 100644 --- a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt @@ -5,111 +5,13 @@ package org.jetbrains.kotlin.idea.core.script -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.application.Result -import com.intellij.openapi.application.WriteAction -import com.intellij.openapi.editor.Document -import com.intellij.openapi.editor.EditorFactory -import com.intellij.openapi.editor.event.DocumentEvent -import com.intellij.openapi.editor.event.DocumentListener -import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager -import com.intellij.openapi.externalSystem.util.ExternalSystemUtil -import com.intellij.openapi.fileEditor.FileDocumentManager -import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl import com.intellij.openapi.project.Project -import com.intellij.openapi.roots.ProjectRootManager -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.VirtualFileManager -import com.intellij.openapi.vfs.newvfs.BulkFileListener -import com.intellij.openapi.vfs.newvfs.events.VFileEvent -import com.intellij.psi.PsiDocumentManager -import com.intellij.util.ui.update.MergingUpdateQueue -import com.intellij.util.ui.update.MergingUpdateQueue.ANY_COMPONENT -import com.intellij.util.ui.update.Update -import org.jetbrains.plugins.gradle.service.project.GradleAutoImportAware -class ScriptModificationListener(private val project: Project) { - private val changedDocuments = HashSet() - private val changedDocumentsQueue = MergingUpdateQueue("ScriptModificationListener: Scripts queue", 1000, false, ANY_COMPONENT, project) +// BUNCH: 182 +fun initializeScriptModificationListener(project: Project) { - init { - showNotificationIfScriptChangedListener() - - saveScriptAfterModificationListener() - } - - private fun showNotificationIfScriptChangedListener() { - project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() { - override fun after(events: List) { - if (ApplicationManager.getApplication().isUnitTestMode) return - - val modifiedScripts = events.mapNotNull { - it.file?.takeIf { isGradleScript(it) } - } - - // Workaround for IDEA-182367 (fixed in IDEA 181.3666) - if (modifiedScripts.isNotEmpty()) { - if (modifiedScripts.any { - GradleAutoImportAware().getAffectedExternalProjectPath(it.path, project) != null - }) { - return - } - ExternalProjectsManager.getInstance(project).externalProjectsWatcher.markDirty(project.basePath) - } - } - }) - } - - private fun saveScriptAfterModificationListener() { - // partially copied from ExternalSystemProjectsWatcherImpl before fix will be implemented in IDEA: - // "Gradle projects need to be imported" notification should be shown when kotlin script is modified - val busConnection = project.messageBus.connect(changedDocumentsQueue) - changedDocumentsQueue.activate() - - EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener { - override fun documentChanged(event: DocumentEvent) { - if (project.isDisposed) return - - val doc = event.document - val file = FileDocumentManager.getInstance().getFile(doc) ?: return - - if (isGradleScript(file) && event.newFragment.isNotBlank()) { - synchronized(changedDocuments) { - changedDocuments.add(doc) - } - - changedDocumentsQueue.queue(object : Update(this) { - override fun run() { - var copy: Array = emptyArray() - - synchronized(changedDocuments) { - copy = changedDocuments.toTypedArray() - changedDocuments.clear() - } - - ExternalSystemUtil.invokeLater(project) { - object : WriteAction() { - override fun run(result: Result) { - for (each in copy) { - PsiDocumentManager.getInstance(project).commitDocument(each) - (FileDocumentManager.getInstance() as? FileDocumentManagerImpl)?.saveDocument(each, false) - } - } - }.execute() - } - } - }) - } - } - }, busConnection) - } - - private fun isGradleScript(file: VirtualFile): Boolean { - if (!ProjectRootManager.getInstance(project).fileIndex.isInContent(file)) return false - - val contributor = ScriptDefinitionContributor.find(project) ?: return false - return ScriptDefinitionsManager.getInstance(project).getDefinitionsBy(contributor).any { - it.isScript(file.name) - } - } } + +// This service was a workaround for the bug in the platform: the notification 'Gradle project needs to be imported' wasn't shown +// after the changes in .gradle.kts files +// It was fixed in >183 (see GradleAutoImportAware.getAffectedExternalProjectFiles) \ No newline at end of file diff --git a/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt.182 b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt.182 new file mode 100644 index 00000000000..3fc61959504 --- /dev/null +++ b/idea/idea-gradle/src/org/jetbrains/kotlin/idea/core/script/ScriptModificationListener.kt.182 @@ -0,0 +1,120 @@ +/* + * 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.idea.core.script + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.application.Result +import com.intellij.openapi.application.WriteAction +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.EditorFactory +import com.intellij.openapi.editor.event.DocumentEvent +import com.intellij.openapi.editor.event.DocumentListener +import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager +import com.intellij.openapi.externalSystem.util.ExternalSystemUtil +import com.intellij.openapi.fileEditor.FileDocumentManager +import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.ProjectRootManager +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileManager +import com.intellij.openapi.vfs.newvfs.BulkFileListener +import com.intellij.openapi.vfs.newvfs.events.VFileEvent +import com.intellij.psi.PsiDocumentManager +import com.intellij.util.ui.update.MergingUpdateQueue +import com.intellij.util.ui.update.MergingUpdateQueue.ANY_COMPONENT +import com.intellij.util.ui.update.Update +import org.jetbrains.plugins.gradle.service.project.GradleAutoImportAware + +fun initializeScriptModificationListener(project: Project) { + ServiceManager.getService(project, ScriptModificationListener::class.java) +} + +class ScriptModificationListener(private val project: Project) { + private val changedDocuments = HashSet() + private val changedDocumentsQueue = MergingUpdateQueue("ScriptModificationListener: Scripts queue", 1000, false, ANY_COMPONENT, project) + + init { + showNotificationIfScriptChangedListener() + + saveScriptAfterModificationListener() + } + + private fun showNotificationIfScriptChangedListener() { + project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() { + override fun after(events: List) { + if (ApplicationManager.getApplication().isUnitTestMode) return + + val modifiedScripts = events.mapNotNull { + it.file?.takeIf { isGradleScript(it) } + } + + // Workaround for IDEA-182367 (fixed in IDEA 181.3666) + if (modifiedScripts.isNotEmpty()) { + if (modifiedScripts.any { + GradleAutoImportAware().getAffectedExternalProjectPath(it.path, project) != null + }) { + return + } + ExternalProjectsManager.getInstance(project).externalProjectsWatcher.markDirty(project.basePath) + } + } + }) + } + + private fun saveScriptAfterModificationListener() { + // partially copied from ExternalSystemProjectsWatcherImpl before fix will be implemented in IDEA: + // "Gradle projects need to be imported" notification should be shown when kotlin script is modified + val busConnection = project.messageBus.connect(changedDocumentsQueue) + changedDocumentsQueue.activate() + + EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener { + override fun documentChanged(event: DocumentEvent) { + if (project.isDisposed) return + + val doc = event.document + val file = FileDocumentManager.getInstance().getFile(doc) ?: return + + if (isGradleScript(file) && event.newFragment.isNotBlank()) { + synchronized(changedDocuments) { + changedDocuments.add(doc) + } + + changedDocumentsQueue.queue(object : Update(this) { + override fun run() { + var copy: Array = emptyArray() + + synchronized(changedDocuments) { + copy = changedDocuments.toTypedArray() + changedDocuments.clear() + } + + ExternalSystemUtil.invokeLater(project) { + object : WriteAction() { + override fun run(result: Result) { + for (each in copy) { + PsiDocumentManager.getInstance(project).commitDocument(each) + (FileDocumentManager.getInstance() as? FileDocumentManagerImpl)?.saveDocument(each, false) + } + } + }.execute() + } + } + }) + } + } + }, busConnection) + } + + private fun isGradleScript(file: VirtualFile): Boolean { + if (!ProjectRootManager.getInstance(project).fileIndex.isInContent(file)) return false + + val contributor = ScriptDefinitionContributor.find(project) ?: return false + return ScriptDefinitionsManager.getInstance(project).getDefinitionsBy(contributor).any { + it.isScript(file.name) + } + } +} \ No newline at end of file diff --git a/idea/resources/META-INF/plugin-common.xml b/idea/resources/META-INF/plugin-common.xml index d2fbf3c8423..f93e8218984 100644 --- a/idea/resources/META-INF/plugin-common.xml +++ b/idea/resources/META-INF/plugin-common.xml @@ -334,9 +334,6 @@ - - diff --git a/idea/resources/META-INF/plugin.xml.173 b/idea/resources/META-INF/plugin.xml.173 index 26a92861521..62452139416 100644 --- a/idea/resources/META-INF/plugin.xml.173 +++ b/idea/resources/META-INF/plugin.xml.173 @@ -64,5 +64,10 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/> + + + + diff --git a/idea/resources/META-INF/plugin.xml.181 b/idea/resources/META-INF/plugin.xml.181 index b5c8527a85c..c5d35c6ddbf 100644 --- a/idea/resources/META-INF/plugin.xml.181 +++ b/idea/resources/META-INF/plugin.xml.181 @@ -65,5 +65,10 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/> - + + + + + diff --git a/idea/resources/META-INF/plugin.xml.182 b/idea/resources/META-INF/plugin.xml.182 index 56b53dbdf1d..82fcab1eeeb 100644 --- a/idea/resources/META-INF/plugin.xml.182 +++ b/idea/resources/META-INF/plugin.xml.182 @@ -74,4 +74,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/resources/META-INF/plugin.xml.as31 b/idea/resources/META-INF/plugin.xml.as31 index 26898b65dd7..8b48d742c15 100644 --- a/idea/resources/META-INF/plugin.xml.as31 +++ b/idea/resources/META-INF/plugin.xml.as31 @@ -65,4 +65,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/resources/META-INF/plugin.xml.as32 b/idea/resources/META-INF/plugin.xml.as32 index ff289cfbf37..b0a7b2e3c4b 100644 --- a/idea/resources/META-INF/plugin.xml.as32 +++ b/idea/resources/META-INF/plugin.xml.as32 @@ -73,4 +73,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + + diff --git a/idea/resources/META-INF/plugin.xml.as33 b/idea/resources/META-INF/plugin.xml.as33 index 6148093e926..38628b1d8d0 100644 --- a/idea/resources/META-INF/plugin.xml.as33 +++ b/idea/resources/META-INF/plugin.xml.as33 @@ -78,4 +78,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio. + + + +