Show notification "Gradle projects need to be imported" when build.gradle.kts file changed
^KT-19165 Fixed
This commit is contained in:
@@ -62,6 +62,16 @@ class ScriptDefinitionsManager(private val project: Project): ScriptDefinitionPr
|
||||
updateDefinitions()
|
||||
}
|
||||
|
||||
fun getDefinitionsBy(contributor: ScriptDefinitionContributor): List<KotlinScriptDefinition> = lock.write {
|
||||
val notLoadedYet = definitions.isEmpty()
|
||||
if (notLoadedYet) return emptyList()
|
||||
|
||||
if (contributor !in definitionsByContributor) error("Unknown contributor: ${contributor.id}")
|
||||
|
||||
if (contributor.isError()) return emptyList()
|
||||
return definitionsByContributor[contributor] ?: emptyList()
|
||||
}
|
||||
|
||||
private fun currentDefinitions(): List<KotlinScriptDefinition> {
|
||||
val hasDefinitions = definitions.isNotEmpty()
|
||||
when {
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ class ScriptDependenciesUpdater(
|
||||
}
|
||||
}
|
||||
|
||||
private fun requestUpdate(files: Iterable<VirtualFile>) {
|
||||
fun requestUpdate(files: Iterable<VirtualFile>) {
|
||||
files.forEach { file ->
|
||||
if (!file.isValid) {
|
||||
cache.delete(file)
|
||||
|
||||
+2
@@ -71,6 +71,8 @@ class GradleScriptDefinitionsContributor(private val project: Project): ScriptDe
|
||||
}
|
||||
}
|
||||
project.messageBus.connect(project).subscribe(GradleSettingsListener.TOPIC, listener)
|
||||
|
||||
ServiceManager.getService(project, ScriptModificationListener::class.java)
|
||||
}
|
||||
|
||||
override fun getDefinitions(): List<KotlinScriptDefinition> {
|
||||
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* 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.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<Document>()
|
||||
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<VFileEvent>) {
|
||||
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)) {
|
||||
synchronized(changedDocuments) {
|
||||
changedDocuments.add(doc)
|
||||
}
|
||||
|
||||
changedDocumentsQueue.queue(object : Update(this) {
|
||||
override fun run() {
|
||||
var copy: Array<Document> = emptyArray()
|
||||
|
||||
synchronized(changedDocuments) {
|
||||
copy = changedDocuments.toTypedArray()
|
||||
changedDocuments.clear()
|
||||
}
|
||||
|
||||
ExternalSystemUtil.invokeLater(project) {
|
||||
object : WriteAction<Any>() {
|
||||
override fun run(result: Result<Any>) {
|
||||
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<GradleScriptDefinitionsContributor>(project) ?: return false
|
||||
return ScriptDefinitionsManager.getInstance(project).getDefinitionsBy(contributor).any {
|
||||
it.isScript(file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -341,6 +341,9 @@
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.util.ProjectJob"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.core.util.ProjectJob"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
|
||||
|
||||
<errorHandler implementation="org.jetbrains.kotlin.idea.reporter.KotlinReportSubmitter"/>
|
||||
|
||||
<internalFileTemplate name="Kotlin File"/>
|
||||
|
||||
Reference in New Issue
Block a user