diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ModuleNameFileAttribute.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ModuleNameFileAttribute.kt index 1192e9f7e68..864b5ee6d0e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ModuleNameFileAttribute.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ModuleNameFileAttribute.kt @@ -6,13 +6,13 @@ package org.jetbrains.kotlin.idea.core.script import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.util.fileAttribute +import org.jetbrains.kotlin.idea.core.util.cachedFileAttribute import org.jetbrains.kotlin.idea.core.util.readString import org.jetbrains.kotlin.idea.core.util.writeString import java.io.DataInputStream import java.io.DataOutputStream -var VirtualFile.scriptRelatedModuleName: String? by fileAttribute( +var VirtualFile.scriptRelatedModuleName: String? by cachedFileAttribute( name = "kotlin-script-moduleName", version = 1, read = DataInputStream::readString, diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesFileAttribute.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesFileAttribute.kt index 16f12aa51ab..9890a87584e 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesFileAttribute.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/script/ScriptDependenciesFileAttribute.kt @@ -22,7 +22,7 @@ import java.io.DataInput import java.io.DataOutput import kotlin.script.experimental.dependencies.ScriptDependencies -var VirtualFile.scriptDependencies: ScriptDependencies? by fileAttribute( +var VirtualFile.scriptDependencies: ScriptDependencies? by cachedFileAttribute( name = "kotlin-script-dependencies", version = 3, read = { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/FileAttributeUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/FileAttributeUtils.kt index db00c74031d..c723c1df625 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/FileAttributeUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/util/FileAttributeUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.idea.core.util +import com.intellij.openapi.util.NullableLazyKey import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFileWithId import com.intellij.openapi.vfs.newvfs.FileAttribute @@ -15,11 +16,11 @@ import com.intellij.util.io.IOUtil.writeUTF import java.io.* import kotlin.reflect.KProperty -fun fileAttribute( +inline fun cachedFileAttribute( name: String, version: Int, - read: DataInputStream.() -> T, - write: DataOutputStream.(T) -> Unit + crossinline read: DataInputStream.() -> T, + crossinline write: DataOutputStream.(T) -> Unit ): FileAttributeProperty { return object : FileAttributeProperty(name, version) { override fun readValue(input: DataInputStream): T = read(input) @@ -33,17 +34,13 @@ abstract class FileAttributeProperty(name: String, version: Int, privat private val attribute = FileAttribute(name, version, false) - operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: T?) { - if (file !is VirtualFileWithId) return + @Suppress("LeakingThis") + private val cache = NullableLazyKey.create( + "FileAttributeProperty.$name", + this::computeValue + ) - attribute.writeAttribute(file).use { output -> - output.writeNullable(newValue) { value -> - writeValue(output, value) - } - } - } - - operator fun getValue(file: VirtualFile, property: KProperty<*>): T? { + private fun computeValue(file: VirtualFile): T? { if (file !is VirtualFileWithId) return null return attribute.readAttribute(file)?.use { input -> @@ -52,12 +49,28 @@ abstract class FileAttributeProperty(name: String, version: Int, privat } } ?: default } + + operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: T?) { + if (file !is VirtualFileWithId) return + + attribute.writeAttribute(file).use { output -> + output.writeNullable(newValue) { value -> + writeValue(output, value) + } + } + + // clear cache + file.putUserData(cache, null) + } + + operator fun getValue(file: VirtualFile, property: KProperty<*>): T? = + cache.getValue(file) } fun DataInput.readStringList(): List = readSeq(this) { readString() } fun DataInput.readFileList(): List = readSeq(this) { readFile() } fun DataInput.readString(): String = readUTF(this) -fun DataInput.readFile() = readUTF(this).let { File(it) } +fun DataInput.readFile() = File(readUTF(this)) fun DataOutput.writeFileList(iterable: Iterable) = writeSeq(this, iterable.toList()) { writeFile(it) } fun DataOutput.writeFile(it: File) = writeString(it.canonicalPath) diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ui/ScratchFileAttributes.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ui/ScratchFileAttributes.kt index 8111243b95a..68fe2e97ebd 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ui/ScratchFileAttributes.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/ui/ScratchFileAttributes.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.idea.scratch.ui import com.intellij.openapi.vfs.VirtualFile -import org.jetbrains.kotlin.idea.core.util.fileAttribute +import org.jetbrains.kotlin.idea.core.util.cachedFileAttribute -var VirtualFile.scratchPanelConfig: ScratchPanelConfig? by fileAttribute( +var VirtualFile.scratchPanelConfig: ScratchPanelConfig? by cachedFileAttribute( name = "kotlin-scratch-panel-config", version = 1, read = { ScratchPanelConfig(readBoolean(), readBoolean()) },