Scripting: do not start multiple request when related file was changed
This commit is contained in:
+21
-4
@@ -11,13 +11,30 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
/**
|
||||
* Up to date of gradle script depends on following factors:
|
||||
* 1. It is out of date when essential [sections] are changed
|
||||
* @see getGradleScriptInputsStamp
|
||||
* 2. When some related file is changed (other gradle script, gradle.properties file)
|
||||
* @see GradleScriptInputsWatcher.areRelatedFilesUpToDate
|
||||
*
|
||||
* [inputsTimeStamp] is needed to check if some related file was changed between updates
|
||||
* [relatedFilesTimeStamp] is needed to check if we already loaded a configuration after the last related file change
|
||||
*
|
||||
* In case when [relatedFilesTimeStamp]s are equal there is no needs to check if related files were changed
|
||||
*/
|
||||
data class GradleKotlinScriptConfigurationInputs(
|
||||
val buildScriptAndPluginsSections: String,
|
||||
val timeStamp: Long
|
||||
val sections: String,
|
||||
val inputsTimeStamp: Long,
|
||||
val relatedFilesTimeStamp: Long
|
||||
) : CachedConfigurationInputs {
|
||||
override fun isUpToDate(project: Project, file: VirtualFile, ktFile: KtFile?): Boolean {
|
||||
val actualStamp = getGradleScriptInputsStamp(project, file, ktFile) ?: return false
|
||||
return actualStamp.buildScriptAndPluginsSections == this.buildScriptAndPluginsSections
|
||||
&& project.service<GradleScriptInputsWatcher>().areAffectedFilesUpToDate(file, timeStamp)
|
||||
|
||||
if (actualStamp.sections != this.sections) return false
|
||||
|
||||
if (actualStamp.relatedFilesTimeStamp == this.relatedFilesTimeStamp) return true
|
||||
|
||||
return project.service<GradleScriptInputsWatcher>().areRelatedFilesUpToDate(file, inputsTimeStamp)
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -35,6 +35,12 @@ class GradleScriptInputsWatcher(val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
fun lastModifiedFileTimeStamp(file: VirtualFile): Long = lastModifiedRelatedFile(file)?.timeStamp ?: 0
|
||||
|
||||
fun areRelatedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
||||
return lastModifiedFileTimeStamp(file) <= timeStamp
|
||||
}
|
||||
|
||||
fun addToStorage(file: VirtualFile) {
|
||||
if (storage.contains(file)) {
|
||||
storage.remove(file)
|
||||
@@ -42,19 +48,19 @@ class GradleScriptInputsWatcher(val project: Project) {
|
||||
storage.add(file)
|
||||
}
|
||||
|
||||
fun areAffectedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
||||
if (storage.isEmpty()) return true
|
||||
private fun lastModifiedRelatedFile(file: VirtualFile): VirtualFile? {
|
||||
if (storage.isEmpty()) return null
|
||||
|
||||
val iterator = storage.descendingIterator()
|
||||
if (!iterator.hasNext()) return true
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var lastModifiedFile = iterator.next()
|
||||
while (lastModifiedFile == file && iterator.hasNext()) {
|
||||
lastModifiedFile = iterator.next()
|
||||
}
|
||||
|
||||
if (lastModifiedFile == file) return true
|
||||
if (lastModifiedFile == file) return null
|
||||
|
||||
return lastModifiedFile.timeStamp <= timeStamp
|
||||
return lastModifiedFile
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -35,6 +35,12 @@ class GradleScriptInputsWatcher(val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
fun lastModifiedFileTimeStamp(file: VirtualFile): Long = lastModifiedRelatedFile(file)?.timeStamp ?: 0
|
||||
|
||||
fun areRelatedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
||||
return lastModifiedFileTimeStamp(file) <= timeStamp
|
||||
}
|
||||
|
||||
fun addToStorage(file: VirtualFile) {
|
||||
if (storage.contains(file)) {
|
||||
storage.remove(file)
|
||||
@@ -42,19 +48,19 @@ class GradleScriptInputsWatcher(val project: Project) {
|
||||
storage.add(file)
|
||||
}
|
||||
|
||||
fun areAffectedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
||||
if (storage.isEmpty()) return true
|
||||
private fun lastModifiedRelatedFile(file: VirtualFile): VirtualFile? {
|
||||
if (storage.isEmpty()) return null
|
||||
|
||||
val iterator = storage.descendingIterator()
|
||||
if (!iterator.hasNext()) return true
|
||||
if (!iterator.hasNext()) return null
|
||||
|
||||
var lastModifiedFile = iterator.next()
|
||||
while (lastModifiedFile == file && iterator.hasNext()) {
|
||||
lastModifiedFile = iterator.next()
|
||||
}
|
||||
|
||||
if (lastModifiedFile == file) return true
|
||||
if (lastModifiedFile == file) return null
|
||||
|
||||
return lastModifiedFile.timeStamp <= timeStamp
|
||||
return lastModifiedFile
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -55,7 +56,8 @@ fun getGradleScriptInputsStamp(
|
||||
}
|
||||
}
|
||||
|
||||
GradleKotlinScriptConfigurationInputs(result.toString(), file.timeStamp)
|
||||
val relatedFilesTimeStamp = project.service<GradleScriptInputsWatcher>().lastModifiedFileTimeStamp(file)
|
||||
GradleKotlinScriptConfigurationInputs(result.toString(), file.timeStamp, relatedFilesTimeStamp)
|
||||
} else null
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -182,6 +182,15 @@ class GradleScriptInputsWatcherTest : AbstractScriptConfigurationLoadingTest() {
|
||||
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||
}
|
||||
|
||||
fun testLoadedConfigurationWhenExternalFileChanged() {
|
||||
assertAndLoadInitialConfiguration(testFiles.buildKts)
|
||||
|
||||
changePropertiesFile()
|
||||
|
||||
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||
assertConfigurationUpToDate(testFiles.buildKts)
|
||||
}
|
||||
|
||||
private fun assertConfigurationUpToDate(file: KtFile) {
|
||||
scriptConfigurationManager.updater.ensureUpToDatedConfigurationSuggested(file)
|
||||
assertNoBackgroundTasks()
|
||||
|
||||
Reference in New Issue
Block a user