mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-23 15:51:59 +00:00
GradleScriptInputsWatcher: move long running operation out of EDT
^KT-36502
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.externalSystem.service.project.autoimport.AsyncFileChangeListenerBase
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
|
||||
fun addVfsListener(watcher: GradleScriptInputsWatcher) {
|
||||
VirtualFileManager.getInstance().addAsyncFileListener(
|
||||
object : AsyncFileChangeListenerBase() {
|
||||
override fun isRelevant(path: String): Boolean {
|
||||
val files = getAffectedGradleProjectFiles(watcher.project)
|
||||
return isInAffectedGradleProjectFiles(files, path)
|
||||
}
|
||||
|
||||
override fun updateFile(file: VirtualFile, event: VFileEvent) {
|
||||
watcher.fileChanged(event.path, file.timeStamp)
|
||||
}
|
||||
|
||||
// do nothing
|
||||
override fun prepareFileDeletion(file: VirtualFile) {}
|
||||
override fun apply() {}
|
||||
override fun reset() {}
|
||||
|
||||
},
|
||||
watcher.project,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
|
||||
fun addVfsListener(watcher: GradleScriptInputsWatcher) {
|
||||
watcher.project.messageBus.connect().subscribe(
|
||||
VirtualFileManager.VFS_CHANGES,
|
||||
object : BulkFileListener {
|
||||
override fun after(events: List<VFileEvent>) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
if (watcher.project.isDisposed) return@executeOnPooledThread
|
||||
val files = getAffectedGradleProjectFiles(watcher.project)
|
||||
for (event in events) {
|
||||
val file = event.file ?: return@executeOnPooledThread
|
||||
if (isInAffectedGradleProjectFiles(files, event.path)) {
|
||||
watcher.fileChanged(event.path, file.timeStamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.externalSystem.autoimport.AsyncFileChangeListenerBase
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
|
||||
fun addVfsListener(watcher: GradleScriptInputsWatcher) {
|
||||
VirtualFileManager.getInstance().addAsyncFileListener(
|
||||
object : AsyncFileChangeListenerBase() {
|
||||
override fun isRelevant(path: String): Boolean {
|
||||
val files = getAffectedGradleProjectFiles(watcher.project)
|
||||
return isInAffectedGradleProjectFiles(files, path)
|
||||
}
|
||||
|
||||
override fun updateFile(file: VirtualFile, event: VFileEvent) {
|
||||
watcher.fileChanged(event.path, file.timeStamp)
|
||||
}
|
||||
|
||||
// do nothing
|
||||
override fun apply() {}
|
||||
override fun init() {}
|
||||
|
||||
},
|
||||
watcher.project,
|
||||
)
|
||||
}
|
||||
@@ -7,15 +7,8 @@ package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
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.PathUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
@State(
|
||||
name = "KotlinBuildScriptsModificationInfo",
|
||||
@@ -25,43 +18,22 @@ class GradleScriptInputsWatcher(val project: Project) : PersistentStateComponent
|
||||
private var storage = Storage()
|
||||
|
||||
fun startWatching() {
|
||||
project.messageBus.connect().subscribe(
|
||||
VirtualFileManager.VFS_CHANGES,
|
||||
object : BulkFileListener {
|
||||
override fun after(events: List<VFileEvent>) {
|
||||
if (project.isDisposed) return
|
||||
|
||||
val files = getAffectedGradleProjectFiles(project)
|
||||
for (event in events) {
|
||||
val file = event.file ?: return
|
||||
if (isInAffectedGradleProjectFiles(files, event.path)) {
|
||||
storage.fileChanged(file, file.timeStamp)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
addVfsListener(this)
|
||||
}
|
||||
|
||||
fun areRelatedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
||||
return storage.lastModifiedTimeStampExcept(file) < timeStamp
|
||||
return storage.lastModifiedTimeStampExcept(file.path) < timeStamp
|
||||
}
|
||||
|
||||
class Storage {
|
||||
private val lastModifiedFiles = LastModifiedFiles()
|
||||
|
||||
fun lastModifiedTimeStampExcept(file: VirtualFile): Long {
|
||||
val fileId = getFileId(file)
|
||||
return lastModifiedFiles.lastModifiedTimeStampExcept(fileId)
|
||||
fun lastModifiedTimeStampExcept(filePath: String): Long {
|
||||
return lastModifiedFiles.lastModifiedTimeStampExcept(filePath)
|
||||
}
|
||||
|
||||
fun fileChanged(file: VirtualFile, ts: Long) {
|
||||
val fileId = getFileId(file)
|
||||
lastModifiedFiles.fileChanged(ts, fileId)
|
||||
}
|
||||
|
||||
private fun getFileId(file: VirtualFile): String {
|
||||
val canonized = PathUtil.getCanonicalPath(file.path)
|
||||
return FileUtil.toSystemIndependentName(canonized)
|
||||
fun fileChanged(filePath: String, ts: Long) {
|
||||
lastModifiedFiles.fileChanged(ts, filePath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,13 +45,12 @@ class GradleScriptInputsWatcher(val project: Project) : PersistentStateComponent
|
||||
this.storage = state
|
||||
}
|
||||
|
||||
fun fileChanged(filePath: String, ts: Long) {
|
||||
storage.fileChanged(filePath, ts)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun clearAndRefillState() {
|
||||
loadState(project.service<GradleScriptInputsWatcher>().state)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun fileChanged(file: VirtualFile, ts: Long) {
|
||||
storage.fileChanged(file, ts)
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationLoadingTest
|
||||
@@ -194,8 +195,8 @@ open class GradleScriptInputsWatcherTest : AbstractScriptConfigurationLoadingTes
|
||||
changeSettingsKtsOutsideSections()
|
||||
|
||||
val ts = System.currentTimeMillis()
|
||||
project.service<GradleScriptInputsWatcher>().fileChanged(testFiles.buildKts.virtualFile, ts)
|
||||
project.service<GradleScriptInputsWatcher>().fileChanged(testFiles.settings.virtualFile, ts)
|
||||
markFileChanged(testFiles.buildKts.virtualFile, ts)
|
||||
markFileChanged(testFiles.settings.virtualFile, ts)
|
||||
|
||||
assertConfigurationUpdateWasDone(testFiles.settings)
|
||||
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||
@@ -206,8 +207,8 @@ open class GradleScriptInputsWatcherTest : AbstractScriptConfigurationLoadingTes
|
||||
assertAndLoadInitialConfiguration(testFiles.settings)
|
||||
|
||||
val ts = System.currentTimeMillis()
|
||||
project.service<GradleScriptInputsWatcher>().fileChanged(testFiles.buildKts.virtualFile, ts)
|
||||
project.service<GradleScriptInputsWatcher>().fileChanged(testFiles.settings.virtualFile, ts)
|
||||
markFileChanged(testFiles.buildKts.virtualFile, ts)
|
||||
markFileChanged(testFiles.settings.virtualFile, ts)
|
||||
|
||||
changePropertiesFile()
|
||||
|
||||
@@ -215,6 +216,10 @@ open class GradleScriptInputsWatcherTest : AbstractScriptConfigurationLoadingTes
|
||||
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||
}
|
||||
|
||||
private fun markFileChanged(virtualFile: VirtualFile, ts: Long) {
|
||||
project.service<GradleScriptInputsWatcher>().fileChanged(virtualFile.path, ts)
|
||||
}
|
||||
|
||||
fun testLoadedConfigurationWhenExternalFileChanged() {
|
||||
assertAndLoadInitialConfiguration(testFiles.buildKts)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user