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.idea.core.script.configuration.cache.CachedConfigurationInputs
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
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(
|
data class GradleKotlinScriptConfigurationInputs(
|
||||||
val buildScriptAndPluginsSections: String,
|
val sections: String,
|
||||||
val timeStamp: Long
|
val inputsTimeStamp: Long,
|
||||||
|
val relatedFilesTimeStamp: Long
|
||||||
) : CachedConfigurationInputs {
|
) : CachedConfigurationInputs {
|
||||||
override fun isUpToDate(project: Project, file: VirtualFile, ktFile: KtFile?): Boolean {
|
override fun isUpToDate(project: Project, file: VirtualFile, ktFile: KtFile?): Boolean {
|
||||||
val actualStamp = getGradleScriptInputsStamp(project, file, ktFile) ?: return false
|
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) {
|
fun addToStorage(file: VirtualFile) {
|
||||||
if (storage.contains(file)) {
|
if (storage.contains(file)) {
|
||||||
storage.remove(file)
|
storage.remove(file)
|
||||||
@@ -42,19 +48,19 @@ class GradleScriptInputsWatcher(val project: Project) {
|
|||||||
storage.add(file)
|
storage.add(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun areAffectedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
private fun lastModifiedRelatedFile(file: VirtualFile): VirtualFile? {
|
||||||
if (storage.isEmpty()) return true
|
if (storage.isEmpty()) return null
|
||||||
|
|
||||||
val iterator = storage.descendingIterator()
|
val iterator = storage.descendingIterator()
|
||||||
if (!iterator.hasNext()) return true
|
if (!iterator.hasNext()) return null
|
||||||
|
|
||||||
var lastModifiedFile = iterator.next()
|
var lastModifiedFile = iterator.next()
|
||||||
while (lastModifiedFile == file && iterator.hasNext()) {
|
while (lastModifiedFile == file && iterator.hasNext()) {
|
||||||
lastModifiedFile = iterator.next()
|
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) {
|
fun addToStorage(file: VirtualFile) {
|
||||||
if (storage.contains(file)) {
|
if (storage.contains(file)) {
|
||||||
storage.remove(file)
|
storage.remove(file)
|
||||||
@@ -42,19 +48,19 @@ class GradleScriptInputsWatcher(val project: Project) {
|
|||||||
storage.add(file)
|
storage.add(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun areAffectedFilesUpToDate(file: VirtualFile, timeStamp: Long): Boolean {
|
private fun lastModifiedRelatedFile(file: VirtualFile): VirtualFile? {
|
||||||
if (storage.isEmpty()) return true
|
if (storage.isEmpty()) return null
|
||||||
|
|
||||||
val iterator = storage.descendingIterator()
|
val iterator = storage.descendingIterator()
|
||||||
if (!iterator.hasNext()) return true
|
if (!iterator.hasNext()) return null
|
||||||
|
|
||||||
var lastModifiedFile = iterator.next()
|
var lastModifiedFile = iterator.next()
|
||||||
while (lastModifiedFile == file && iterator.hasNext()) {
|
while (lastModifiedFile == file && iterator.hasNext()) {
|
||||||
lastModifiedFile = iterator.next()
|
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
|
package org.jetbrains.kotlin.idea.scripting.gradle
|
||||||
|
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.registry.Registry
|
import com.intellij.openapi.util.registry.Registry
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
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
|
} else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
@@ -182,6 +182,15 @@ class GradleScriptInputsWatcherTest : AbstractScriptConfigurationLoadingTest() {
|
|||||||
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testLoadedConfigurationWhenExternalFileChanged() {
|
||||||
|
assertAndLoadInitialConfiguration(testFiles.buildKts)
|
||||||
|
|
||||||
|
changePropertiesFile()
|
||||||
|
|
||||||
|
assertConfigurationUpdateWasDone(testFiles.buildKts)
|
||||||
|
assertConfigurationUpToDate(testFiles.buildKts)
|
||||||
|
}
|
||||||
|
|
||||||
private fun assertConfigurationUpToDate(file: KtFile) {
|
private fun assertConfigurationUpToDate(file: KtFile) {
|
||||||
scriptConfigurationManager.updater.ensureUpToDatedConfigurationSuggested(file)
|
scriptConfigurationManager.updater.ensureUpToDatedConfigurationSuggested(file)
|
||||||
assertNoBackgroundTasks()
|
assertNoBackgroundTasks()
|
||||||
|
|||||||
Reference in New Issue
Block a user