Send roots changed iff combined dependencies of all scripts changed
This reduces total number of reindex requests when working with scripts ScriptDependenciesCache::onChange logic is independent from ScriptDependenciesUpdater::onChange
This commit is contained in:
+43
-5
@@ -16,11 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.script
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.NonClasspathDirectoriesScope
|
||||
import kotlinx.coroutines.experimental.launch
|
||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
@@ -49,7 +54,7 @@ internal class ScriptDependenciesCache(private val project: Project) {
|
||||
NonClasspathDirectoriesScope(allLibrarySourcesCache.get())
|
||||
}
|
||||
|
||||
fun onChange() {
|
||||
private fun onChange(file: VirtualFile?) {
|
||||
allScriptsClasspathCache.clear()
|
||||
allScriptsClasspathScope.clear()
|
||||
allLibrarySourcesCache.clear()
|
||||
@@ -61,11 +66,33 @@ internal class ScriptDependenciesCache(private val project: Project) {
|
||||
.single()
|
||||
|
||||
kotlinScriptDependenciesClassFinder.clearCache()
|
||||
updateHighlighting(file)
|
||||
}
|
||||
|
||||
private fun updateHighlighting(file: VirtualFile?) {
|
||||
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
|
||||
|
||||
launch(EDT) {
|
||||
if (file != null) {
|
||||
file.let { PsiManager.getInstance(project).findFile(it) }?.let { psiFile ->
|
||||
DaemonCodeAnalyzer.getInstance(project).restart(psiFile)
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(ApplicationManager.getApplication().isUnitTestMode)
|
||||
DaemonCodeAnalyzer.getInstance(project).restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hasNotCachedRoots(scriptDependencies: ScriptDependencies): Boolean {
|
||||
return !allScriptsClasspathCache.get().containsAll(ScriptDependenciesManager.toVfsRoots(scriptDependencies.classpath)) ||
|
||||
!allLibrarySourcesCache.get().containsAll(ScriptDependenciesManager.toVfsRoots(scriptDependencies.sources))
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
cacheLock.write(cache::clear)
|
||||
onChange()
|
||||
onChange(null)
|
||||
}
|
||||
|
||||
fun save(virtualFile: VirtualFile, new: ScriptDependencies): Boolean {
|
||||
@@ -75,11 +102,22 @@ internal class ScriptDependenciesCache(private val project: Project) {
|
||||
cache[path] = new
|
||||
old
|
||||
}
|
||||
return new != old
|
||||
val changed = new != old
|
||||
if (changed) {
|
||||
onChange(virtualFile)
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
fun delete(virtualFile: VirtualFile): Boolean = cacheLock.write {
|
||||
cache.remove(virtualFile.path) != null
|
||||
fun delete(virtualFile: VirtualFile): Boolean {
|
||||
val changed = cacheLock.write {
|
||||
cache.remove(virtualFile.path) != null
|
||||
}
|
||||
if (changed) {
|
||||
onChange(virtualFile)
|
||||
}
|
||||
return changed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -89,9 +89,8 @@ class ScriptDependenciesManager internal constructor(
|
||||
fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) {
|
||||
with(getInstance(project)) {
|
||||
val scriptDefinition = KotlinScriptDefinitionProvider.getInstance(project)!!.findScriptDefinition(virtualFile)!!
|
||||
val updated = cacheUpdater.updateSync(virtualFile, scriptDefinition)
|
||||
assert(updated)
|
||||
cacheUpdater.onChange()
|
||||
cacheUpdater.updateSync(virtualFile, scriptDefinition)
|
||||
cacheUpdater.notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-15
@@ -80,8 +80,11 @@ internal class ScriptDependenciesUpdater(
|
||||
|
||||
private fun tryLoadingFromDisk(file: VirtualFile) {
|
||||
ScriptDependenciesFileAttribute.read(file)?.let { deserialized ->
|
||||
val rootsChanged = cache.hasNotCachedRoots(deserialized)
|
||||
cache.save(file, deserialized)
|
||||
onChange()
|
||||
if (rootsChanged) {
|
||||
notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,8 +189,8 @@ internal class ScriptDependenciesUpdater(
|
||||
}
|
||||
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
|
||||
val resultingDependencies = (result.dependencies ?: ScriptDependencies.Empty).adjustByDefinition(scriptDef)
|
||||
if (cache(resultingDependencies, file)) {
|
||||
onChange()
|
||||
if (saveNewDependencies(resultingDependencies, file)) {
|
||||
notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,26 +198,21 @@ internal class ScriptDependenciesUpdater(
|
||||
|
||||
fun updateSync(file: VirtualFile, scriptDef: KotlinScriptDefinition): Boolean {
|
||||
val newDeps = contentLoader.loadContentsAndResolveDependencies(scriptDef, file) ?: ScriptDependencies.Empty
|
||||
return cache(newDeps, file)
|
||||
return saveNewDependencies(newDeps, file)
|
||||
}
|
||||
|
||||
private fun cache(
|
||||
private fun saveNewDependencies(
|
||||
new: ScriptDependencies,
|
||||
file: VirtualFile
|
||||
): Boolean {
|
||||
val updated = cache.save(file, new)
|
||||
if (updated) {
|
||||
val rootsChanged = cache.hasNotCachedRoots(new)
|
||||
if (cache.save(file, new)) {
|
||||
ScriptDependenciesFileAttribute.write(file, new)
|
||||
}
|
||||
return updated
|
||||
return rootsChanged
|
||||
}
|
||||
|
||||
fun onChange() {
|
||||
cache.onChange()
|
||||
notifyRootsChanged()
|
||||
}
|
||||
|
||||
private fun notifyRootsChanged() {
|
||||
fun notifyRootsChanged() {
|
||||
val rootsChangesRunnable = {
|
||||
runWriteAction {
|
||||
if (project.isDisposed) return@runWriteAction
|
||||
@@ -248,7 +246,7 @@ internal class ScriptDependenciesUpdater(
|
||||
(application.isUnitTestMode || projectFileIndex.isInContent(it)) && !ProjectUtil.isProjectOrWorkspaceFile(it)
|
||||
}
|
||||
})) {
|
||||
onChange()
|
||||
notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user