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.Application
import com.intellij.openapi.application.ApplicationManager 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.Project
import com.intellij.openapi.project.isProjectOrWorkspaceFile
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.util.Alarm
import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.core.script.dependencies.FromFileAttributeScriptDependenciesLoader import org.jetbrains.kotlin.idea.core.script.dependencies.FromFileAttributeScriptDependenciesLoader
import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependenciesLoader import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptDependenciesLoader
@@ -41,9 +43,11 @@ class ScriptDependenciesUpdater(
private val scriptDefinitionProvider: ScriptDefinitionProvider private val scriptDefinitionProvider: ScriptDefinitionProvider
) { ) {
private val modifiedScripts = mutableSetOf<VirtualFile>() private val modifiedScripts = mutableSetOf<VirtualFile>()
private val scriptsQueue = Alarm(Alarm.ThreadToUse.SWING_THREAD, project)
private val scriptChangesListenerDelay = 1400
init { init {
listenToVfsChanges() listenForChangesInScripts()
} }
fun getCurrentDependencies(file: VirtualFile): ScriptDependencies { fun getCurrentDependencies(file: VirtualFile): ScriptDependencies {
@@ -75,32 +79,39 @@ class ScriptDependenciesUpdater(
} }
} }
private fun listenToVfsChanges() { private fun listenForChangesInScripts() {
project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() { project.messageBus.connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener {
val projectFileIndex = ProjectRootManager.getInstance(project).fileIndex override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
val application = ApplicationManager.getApplication() val scriptDef = scriptDefinitionProvider.findScriptDefinition(file) ?: return
ScriptDependenciesLoader.updateDependencies(file, scriptDef, project, shouldNotifyRootsChanged = true)
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()
}
} }
}) })
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 package org.jetbrains.kotlin.idea.script
import com.intellij.codeInsight.highlighting.HighlightUsagesHandler import com.intellij.codeInsight.highlighting.HighlightUsagesHandler
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.Extensions import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.module.JavaModuleType import com.intellij.openapi.module.JavaModuleType
import com.intellij.openapi.module.Module 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.ScriptDefinitionContributor
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager 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.ScriptDependenciesManager.Companion.updateScriptDependenciesSynchronously
import org.jetbrains.kotlin.idea.core.script.isScriptDependenciesUpdaterDisabled
import org.jetbrains.kotlin.idea.navigation.GotoCheck import org.jetbrains.kotlin.idea.navigation.GotoCheck
import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.test.InTextDirectivesUtils 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_WARNINGS"),
InTextDirectivesUtils.isDirectiveDefined(file.text, "// CHECK_INFOS")) 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() { abstract class AbstractScriptConfigurationNavigationTest : AbstractScriptConfigurationTest() {