Add a delay to reload script dependencies

^KT-23616
This commit is contained in:
Natalia Selezneva
2018-04-28 13:35:24 +03:00
parent 3eac391793
commit d422eb6833
2 changed files with 53 additions and 30 deletions
@@ -18,14 +18,16 @@ package org.jetbrains.kotlin.idea.core.script
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.EditorFactory
import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.FileEditorManagerListener
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.isProjectOrWorkspaceFile
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Key
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.util.Alarm
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.core.script.dependencies.FromFileAttributeScriptDependenciesLoader
import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependenciesLoader
@@ -41,9 +43,11 @@ class ScriptDependenciesUpdater(
private val scriptDefinitionProvider: ScriptDefinitionProvider
) {
private val modifiedScripts = mutableSetOf<VirtualFile>()
private val scriptsQueue = Alarm(Alarm.ThreadToUse.SWING_THREAD, project)
private val scriptChangesListenerDelay = 1400
init {
listenToVfsChanges()
listenForChangesInScripts()
}
fun getCurrentDependencies(file: VirtualFile): ScriptDependencies {
@@ -75,32 +79,39 @@ class ScriptDependenciesUpdater(
}
}
private fun listenToVfsChanges() {
project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
val projectFileIndex = ProjectRootManager.getInstance(project).fileIndex
val application = ApplicationManager.getApplication()
override fun after(events: List<VFileEvent>) {
if (application.isUnitTestMode && application.isScriptDependenciesUpdaterDisabled == true) {
return
}
val modifiedScripts = events.mapNotNull {
// The check is partly taken from the BuildManager.java
it.file?.takeIf {
// the isUnitTestMode check fixes ScriptConfigurationHighlighting & Navigation tests, since they are not trigger proper update mechanims
// TODO: find out the reason, then consider to fix tests and remove this check
(application.isUnitTestMode ||
scriptDefinitionProvider.isScript(it.name) && projectFileIndex.isInContent(it)) && !isProjectOrWorkspaceFile(it)
}
}
requestUpdate(modifiedScripts)
if (KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled) {
reloadModifiedScripts()
}
private fun listenForChangesInScripts() {
project.messageBus.connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener {
override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return
ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = true)
}
})
EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener {
override fun documentChanged(event: DocumentEvent) {
if (project.isDisposed) return
if (ApplicationManager.getApplication().isUnitTestMode && ApplicationManager.getApplication().isScriptDependenciesUpdaterDisabled == true) return
val document = event.document
val file = FileDocumentManager.getInstance().getFile(document)?.takeIf { it.isInLocalFileSystem } ?: return
scriptsQueue.cancelAllRequests()
scriptsQueue.addRequest(
{
FileDocumentManager.getInstance().saveDocument(document)
requestUpdate(listOf(file))
if (KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled) {
reloadModifiedScripts()
}
},
scriptChangesListenerDelay,
true
)
}
}, project.messageBus.connect())
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea.script
import com.intellij.codeInsight.highlighting.HighlightUsagesHandler
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.module.JavaModuleType
import com.intellij.openapi.module.Module
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.idea.completion.test.KotlinCompletionTestCase
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionContributor
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager.Companion.updateScriptDependenciesSynchronously
import org.jetbrains.kotlin.idea.core.script.isScriptDependenciesUpdaterDisabled
import org.jetbrains.kotlin.idea.navigation.GotoCheck
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.test.InTextDirectivesUtils
@@ -61,6 +63,16 @@ abstract class AbstractScriptConfigurationHighlightingTest : AbstractScriptConfi
InTextDirectivesUtils.isDirectiveDefined(file.text, "// CHECK_WARNINGS"),
InTextDirectivesUtils.isDirectiveDefined(file.text, "// CHECK_INFOS"))
}
override fun setUp() {
super.setUp()
ApplicationManager.getApplication().isScriptDependenciesUpdaterDisabled = true
}
override fun tearDown() {
ApplicationManager.getApplication().isScriptDependenciesUpdaterDisabled = false
super.tearDown()
}
}
abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigurationTest() {