Fire one 'roots changed' event after all scripts dependencies loaded
^KT-29474
This commit is contained in:
+3
-1
@@ -77,7 +77,9 @@ class ScriptDependenciesManager internal constructor(
|
||||
@TestOnly
|
||||
fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) {
|
||||
val scriptDefinition = virtualFile.findScriptDefinition(project)!!
|
||||
SyncScriptDependenciesLoader(project).updateDependencies(virtualFile, scriptDefinition)
|
||||
val loader = SyncScriptDependenciesLoader(project)
|
||||
loader.updateDependencies(virtualFile, scriptDefinition)
|
||||
loader.notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ class ScriptDependenciesUpdater(
|
||||
|
||||
updateDependencies(file, scriptDef)
|
||||
|
||||
makeRootsChangeIfNeeded()
|
||||
|
||||
return cache[file] ?: ScriptDependencies.Empty
|
||||
}
|
||||
|
||||
@@ -80,6 +82,12 @@ class ScriptDependenciesUpdater(
|
||||
loader.updateDependencies(file, scriptDef)
|
||||
}
|
||||
|
||||
private fun makeRootsChangeIfNeeded() {
|
||||
if (fileAttributeLoader.notifyRootsChanged()) return
|
||||
if (syncLoader.notifyRootsChanged()) return
|
||||
if (asyncLoader.notifyRootsChanged()) return
|
||||
}
|
||||
|
||||
private fun listenForChangesInScripts() {
|
||||
project.messageBus.connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, object : FileEditorManagerListener {
|
||||
override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
|
||||
|
||||
+35
-3
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.idea.core.script.dependencies
|
||||
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.progress.util.BackgroundTaskUtil
|
||||
@@ -25,11 +26,13 @@ import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
|
||||
import kotlin.script.experimental.dependencies.DependenciesResolver
|
||||
|
||||
class AsyncScriptDependenciesLoader internal constructor(project: Project) : ScriptDependenciesLoader(project) {
|
||||
private val backgroundTaskLock = ReentrantReadWriteLock()
|
||||
private val lock = ReentrantReadWriteLock()
|
||||
|
||||
private var notifyRootChange: Boolean = false
|
||||
private var backgroundTasksQueue: LoaderBackgroundTask? = null
|
||||
|
||||
override fun loadDependencies(file: VirtualFile, scriptDef: KotlinScriptDefinition) {
|
||||
backgroundTaskLock.write {
|
||||
lock.write {
|
||||
if (backgroundTasksQueue == null) {
|
||||
backgroundTasksQueue = LoaderBackgroundTask()
|
||||
backgroundTasksQueue!!.addTask(file)
|
||||
@@ -42,6 +45,28 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr
|
||||
|
||||
override fun shouldShowNotification(): Boolean = !KotlinScriptingSettings.getInstance(project).isAutoReloadEnabled
|
||||
|
||||
override fun notifyRootsChanged(): Boolean {
|
||||
lock.write {
|
||||
if (notifyRootChange) return false
|
||||
|
||||
if (backgroundTasksQueue == null) {
|
||||
submitMakeRootsChange()
|
||||
return true
|
||||
}
|
||||
|
||||
notifyRootChange = true
|
||||
|
||||
backgroundTasksQueue!!.addOnFinishTask {
|
||||
lock.write {
|
||||
notifyRootChange = false
|
||||
}
|
||||
submitMakeRootsChange()
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun runDependenciesUpdate(file: VirtualFile) {
|
||||
val scriptDef = runReadAction { file.findScriptDefinition(project) } ?: return
|
||||
// runBlocking is using there to avoid loading dependencies asynchronously
|
||||
@@ -72,6 +97,8 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr
|
||||
private inner class LoaderBackgroundTask {
|
||||
private val sequenceOfFiles: ConcurrentLinkedQueue<VirtualFile> = ConcurrentLinkedQueue()
|
||||
|
||||
private var onFinish: (() -> Unit)? = null
|
||||
|
||||
fun start() {
|
||||
if (shouldShowNotification()) {
|
||||
BackgroundTaskUtil.executeOnPooledThread(project, Runnable {
|
||||
@@ -91,10 +118,15 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr
|
||||
sequenceOfFiles.add(file)
|
||||
}
|
||||
|
||||
fun addOnFinishTask(task: () -> Unit) {
|
||||
onFinish = task
|
||||
}
|
||||
|
||||
private fun loadDependencies(indicator: ProgressIndicator?) {
|
||||
while (true) {
|
||||
if (indicator?.isCanceled == true || sequenceOfFiles.isEmpty()) {
|
||||
backgroundTaskLock.write {
|
||||
lock.write {
|
||||
onFinish?.invoke()
|
||||
backgroundTasksQueue = null
|
||||
}
|
||||
return
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ class FromFileAttributeScriptDependenciesLoader(project: Project) : ScriptDepend
|
||||
val rootsChanged = cache.hasNotCachedRoots(deserialized)
|
||||
cache.save(file, deserialized)
|
||||
if (rootsChanged) {
|
||||
notifyRootsChanged()
|
||||
shouldNotifyRootsChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -37,6 +37,8 @@ abstract class ScriptDependenciesLoader(protected val project: Project) {
|
||||
protected abstract fun loadDependencies(file: VirtualFile, scriptDef: KotlinScriptDefinition)
|
||||
protected abstract fun shouldShowNotification(): Boolean
|
||||
|
||||
protected var shouldNotifyRootsChanged = false
|
||||
|
||||
protected val contentLoader = ScriptContentLoader(project)
|
||||
protected val cache: ScriptDependenciesCache = ServiceManager.getService(project, ScriptDependenciesCache::class.java)
|
||||
|
||||
@@ -87,15 +89,20 @@ abstract class ScriptDependenciesLoader(protected val project: Project) {
|
||||
}
|
||||
|
||||
if (rootsChanged) {
|
||||
notifyRootsChanged()
|
||||
shouldNotifyRootsChanged = true
|
||||
}
|
||||
}
|
||||
|
||||
protected fun notifyRootsChanged() {
|
||||
open fun notifyRootsChanged(): Boolean = submitMakeRootsChange()
|
||||
|
||||
protected fun submitMakeRootsChange(): Boolean {
|
||||
if (!shouldNotifyRootsChanged) return false
|
||||
|
||||
val doNotifyRootsChanged = Runnable {
|
||||
runWriteAction {
|
||||
if (project.isDisposed) return@runWriteAction
|
||||
|
||||
shouldNotifyRootsChanged = false
|
||||
ProjectRootManagerEx.getInstanceEx(project)?.makeRootsChange(EmptyRunnable.getInstance(), false, true)
|
||||
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
|
||||
}
|
||||
@@ -106,5 +113,7 @@ abstract class ScriptDependenciesLoader(protected val project: Project) {
|
||||
} else {
|
||||
TransactionGuard.getInstance().submitTransactionLater(project, doNotifyRootsChanged)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user