.gradle.kts, changes notifier: process events async and on pooled thread

#KT-36401 Fixed
This commit is contained in:
Sergey Rostov
2020-02-21 12:08:34 +03:00
parent 5393074d61
commit 5e16373af6
2 changed files with 47 additions and 36 deletions
@@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.core.script.configuration.DefaultScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.configuration.DefaultScriptConfigurationManager
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
/** /**
@@ -29,8 +30,10 @@ abstract class ScriptChangeListener(protected val project: Project) {
protected fun getAnalyzableKtFileForScript(vFile: VirtualFile): KtFile? { protected fun getAnalyzableKtFileForScript(vFile: VirtualFile): KtFile? {
if (project.isDisposed) return null if (project.isDisposed) return null
return (PsiManager.getInstance(project).findFile(vFile) as? KtFile)?.takeIf { return runReadAction {
ProjectRootsUtil.isInProjectSource(it, includeScriptsOutsideSourceRoots = true) (PsiManager.getInstance(project).findFile(vFile) as? KtFile)?.takeIf {
ProjectRootsUtil.isInProjectSource(it, includeScriptsOutsideSourceRoots = true)
}
} }
} }
@@ -16,15 +16,16 @@ import com.intellij.openapi.fileEditor.FileEditorManagerListener
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.Alarm import com.intellij.util.Alarm
import com.intellij.util.concurrency.AppExecutorUtil
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptChangeListener.Companion.LISTENER import org.jetbrains.kotlin.idea.core.script.configuration.listener.ScriptChangeListener.Companion.LISTENER
import org.jetbrains.kotlin.idea.core.script.isScriptChangesNotifierDisabled import org.jetbrains.kotlin.idea.core.script.isScriptChangesNotifierDisabled
internal class ScriptChangesNotifier( internal class ScriptChangesNotifier(
private val project: Project, private val project: Project,
private val updater: ScriptConfigurationUpdater private val updater: ScriptConfigurationUpdater,
) { ) {
private val scriptsQueue = Alarm(Alarm.ThreadToUse.SWING_THREAD, project) private val scriptsQueue = Alarm(Alarm.ThreadToUse.POOLED_THREAD, project)
private val scriptChangesListenerDelay = 1400 private val scriptChangesListenerDelay = 1400
init { init {
@@ -32,39 +33,45 @@ internal class ScriptChangesNotifier(
} }
private fun listenForChangesInScripts() { private fun listenForChangesInScripts() {
project.messageBus.connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener { project.messageBus.connect().subscribe(
override fun fileOpened(source: FileEditorManager, file: VirtualFile) { FileEditorManagerListener.FILE_EDITOR_MANAGER,
runScriptDependenciesUpdateIfNeeded(file) object : FileEditorManagerListener {
} override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
runScriptDependenciesUpdateIfNeeded(file)
override fun selectionChanged(event: FileEditorManagerEvent) {
event.newFile?.let { runScriptDependenciesUpdateIfNeeded(it) }
}
private fun runScriptDependenciesUpdateIfNeeded(file: VirtualFile) {
getListener(project, file)?.editorActivated(file, updater)
}
})
EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener {
override fun documentChanged(event: DocumentEvent) {
val document = event.document
val file = FileDocumentManager.getInstance().getFile(document)?.takeIf { it.isInLocalFileSystem } ?: return
val listener = getListener(project, file) ?: return
if (ApplicationManager.getApplication().isUnitTestMode) {
listener.documentChanged(file, updater)
} }
scriptsQueue.cancelAllRequests() override fun selectionChanged(event: FileEditorManagerEvent) {
scriptsQueue.addRequest( event.newFile?.let { runScriptDependenciesUpdateIfNeeded(it) }
{ listener.documentChanged(file, updater) }, }
scriptChangesListenerDelay,
true private fun runScriptDependenciesUpdateIfNeeded(file: VirtualFile) {
) AppExecutorUtil.getAppExecutorService().submit {
} getListener(project, file)?.editorActivated(file, updater)
}, project.messageBus.connect()) }
}
},
)
EditorFactory.getInstance().eventMulticaster.addDocumentListener(
object : DocumentListener {
override fun documentChanged(event: DocumentEvent) {
val document = event.document
val file = FileDocumentManager.getInstance().getFile(document)?.takeIf { it.isInLocalFileSystem } ?: return
if (ApplicationManager.getApplication().isUnitTestMode) {
getListener(project, file)?.documentChanged(file, updater)
} else {
scriptsQueue.cancelAllRequests()
scriptsQueue.addRequest(
{ getListener(project, file)?.documentChanged(file, updater) },
scriptChangesListenerDelay,
true,
)
}
}
},
project.messageBus.connect(),
)
} }
private val defaultListener = DefaultScriptChangeListener(project) private val defaultListener = DefaultScriptChangeListener(project)
@@ -83,6 +90,7 @@ internal class ScriptChangesNotifier(
} }
private fun areListenersDisabled(): Boolean { private fun areListenersDisabled(): Boolean {
return ApplicationManager.getApplication().isUnitTestMode && ApplicationManager.getApplication().isScriptChangesNotifierDisabled == true return ApplicationManager.getApplication().isUnitTestMode && ApplicationManager.getApplication()
.isScriptChangesNotifierDisabled == true
} }
} }