Refactoring: introduce file attribute utils
This commit is contained in:
+11
-22
@@ -6,26 +6,15 @@
|
||||
package org.jetbrains.kotlin.idea.core.script
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId
|
||||
import com.intellij.openapi.vfs.newvfs.FileAttribute
|
||||
import kotlin.reflect.KProperty
|
||||
import org.jetbrains.kotlin.idea.core.util.fileAttribute
|
||||
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 ScratchModuleNameProperty()
|
||||
|
||||
private val moduleNameAttribute = FileAttribute("kotlin-script-moduleName", 1, false)
|
||||
private class ScratchModuleNameProperty {
|
||||
|
||||
operator fun getValue(file: VirtualFile, property: KProperty<*>): String? {
|
||||
if (file !is VirtualFileWithId) return null
|
||||
|
||||
return moduleNameAttribute.readAttributeBytes(file)?.let { String(it) }
|
||||
}
|
||||
|
||||
operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: String?) {
|
||||
if (file !is VirtualFileWithId) return
|
||||
|
||||
if (newValue != null) {
|
||||
moduleNameAttribute.writeAttributeBytes(file, newValue.toByteArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
var VirtualFile.scriptRelatedModuleName: String? by fileAttribute(
|
||||
name = "kotlin-script-moduleName",
|
||||
version = 1,
|
||||
read = DataInputStream::readString,
|
||||
write = DataOutputStream::writeString
|
||||
)
|
||||
+21
-66
@@ -17,75 +17,30 @@
|
||||
package org.jetbrains.kotlin.idea.core.script
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId
|
||||
import com.intellij.openapi.vfs.newvfs.FileAttribute
|
||||
import com.intellij.util.io.DataInputOutputUtil.readSeq
|
||||
import com.intellij.util.io.DataInputOutputUtil.writeSeq
|
||||
import com.intellij.util.io.IOUtil.readUTF
|
||||
import com.intellij.util.io.IOUtil.writeUTF
|
||||
import org.jetbrains.kotlin.idea.core.util.*
|
||||
import java.io.DataInput
|
||||
import java.io.DataOutput
|
||||
import java.io.File
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.script.experimental.dependencies.ScriptDependencies
|
||||
|
||||
var VirtualFile.scriptDependencies: ScriptDependencies? by ScriptDependenciesProperty()
|
||||
private val scriptDependencies = FileAttribute("kotlin-script-dependencies", 4, false)
|
||||
|
||||
private class ScriptDependenciesProperty {
|
||||
|
||||
operator fun setValue(file: VirtualFile, property: KProperty<*>, newValue: ScriptDependencies?) {
|
||||
if (file !is VirtualFileWithId) return
|
||||
|
||||
val output = scriptDependencies.writeAttribute(file)
|
||||
output.use {
|
||||
it.writeNullable(newValue) { value ->
|
||||
with(value) {
|
||||
writeFileList(classpath)
|
||||
writeStringList(imports)
|
||||
writeNullable(javaHome, DataOutput::writeFile)
|
||||
writeFileList(scripts)
|
||||
writeFileList(sources)
|
||||
|
||||
}
|
||||
}
|
||||
var VirtualFile.scriptDependencies: ScriptDependencies? by fileAttribute(
|
||||
name = "kotlin-script-dependencies",
|
||||
version = 3,
|
||||
read = {
|
||||
ScriptDependencies(
|
||||
classpath = readFileList(),
|
||||
imports = readStringList(),
|
||||
javaHome = readNullable(DataInput::readFile),
|
||||
scripts = readFileList(),
|
||||
sources = readFileList()
|
||||
)
|
||||
},
|
||||
write = {
|
||||
with(it) {
|
||||
writeFileList(classpath)
|
||||
writeStringList(imports)
|
||||
writeNullable(javaHome, DataOutput::writeFile)
|
||||
writeFileList(scripts)
|
||||
writeFileList(sources)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun getValue(file: VirtualFile, property: KProperty<*>): ScriptDependencies? {
|
||||
if (file !is VirtualFileWithId) return null
|
||||
|
||||
val input = scriptDependencies.readAttribute(file)
|
||||
return input?.use {
|
||||
it.readNullable {
|
||||
ScriptDependencies(
|
||||
classpath = readFileList(),
|
||||
imports = readStringList(),
|
||||
javaHome = readNullable(DataInput::readFile),
|
||||
scripts = readFileList(),
|
||||
sources = readFileList()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun DataInput.readStringList(): List<String> = readSeq(this) { readString() }
|
||||
private fun DataInput.readFileList() = readSeq(this) { readFile() }
|
||||
private fun DataInput.readString() = readUTF(this)
|
||||
private fun DataInput.readFile() = readUTF(this).let { File(it) }
|
||||
|
||||
private fun DataOutput.writeFileList(iterable: Iterable<File>) = writeSeq(this, iterable.toList()) { writeFile(it) }
|
||||
private fun DataOutput.writeFile(it: File) = writeString(it.canonicalPath)
|
||||
private fun DataOutput.writeString(string: String) = writeUTF(this, string)
|
||||
private fun DataOutput.writeStringList(iterable: Iterable<String>) = writeSeq(this, iterable.toList()) { writeString(it) }
|
||||
|
||||
private fun <T : Any> DataOutput.writeNullable(nullable: T?, writeT: DataOutput.(T) -> Unit) {
|
||||
writeBoolean(nullable != null)
|
||||
nullable?.let { writeT(it) }
|
||||
}
|
||||
|
||||
private fun <T : Any> DataInput.readNullable(readT: DataInput.() -> T): T? {
|
||||
val hasValue = readBoolean()
|
||||
return if (hasValue) readT() else null
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.util
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId
|
||||
import com.intellij.openapi.vfs.newvfs.FileAttribute
|
||||
import com.intellij.util.io.DataInputOutputUtil.readSeq
|
||||
import com.intellij.util.io.DataInputOutputUtil.writeSeq
|
||||
import com.intellij.util.io.IOUtil.readUTF
|
||||
import com.intellij.util.io.IOUtil.writeUTF
|
||||
import java.io.*
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
fun <T : Any> fileAttribute(
|
||||
name: String,
|
||||
version: Int,
|
||||
read: DataInputStream.() -> T,
|
||||
write: DataOutputStream.(T) -> Unit
|
||||
): FileAttributeProperty<T> {
|
||||
return object : FileAttributeProperty<T>(name, version) {
|
||||
override fun readValue(input: DataInputStream): T = read(input)
|
||||
override fun writeValue(output: DataOutputStream, value: T) = write(output, value)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FileAttributeProperty<T : Any>(name: String, version: Int, private val default: T? = null) {
|
||||
abstract fun readValue(input: DataInputStream): T
|
||||
abstract fun writeValue(output: DataOutputStream, value: T)
|
||||
|
||||
private val attribute = FileAttribute(name, version, false)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
operator fun getValue(file: VirtualFile, property: KProperty<*>): T? {
|
||||
if (file !is VirtualFileWithId) return null
|
||||
|
||||
return attribute.readAttribute(file)?.use { input ->
|
||||
input.readNullable {
|
||||
readValue(input)
|
||||
}
|
||||
} ?: default
|
||||
}
|
||||
}
|
||||
|
||||
fun DataInput.readStringList(): List<String> = readSeq(this) { readString() }
|
||||
fun DataInput.readFileList(): List<File> = readSeq(this) { readFile() }
|
||||
fun DataInput.readString(): String = readUTF(this)
|
||||
fun DataInput.readFile() = readUTF(this).let { File(it) }
|
||||
|
||||
fun DataOutput.writeFileList(iterable: Iterable<File>) = writeSeq(this, iterable.toList()) { writeFile(it) }
|
||||
fun DataOutput.writeFile(it: File) = writeString(it.canonicalPath)
|
||||
fun DataOutput.writeString(string: String) = writeUTF(this, string)
|
||||
fun DataOutput.writeStringList(iterable: Iterable<String>) = writeSeq(this, iterable.toList()) { writeString(it) }
|
||||
|
||||
fun <T : Any> DataOutput.writeNullable(nullable: T?, writeT: DataOutput.(T) -> Unit) {
|
||||
writeBoolean(nullable != null)
|
||||
nullable?.let { writeT(it) }
|
||||
}
|
||||
|
||||
fun <T : Any> DataInput.readNullable(readT: DataInput.() -> T): T? {
|
||||
val hasValue = readBoolean()
|
||||
return if (hasValue) readT() else null
|
||||
}
|
||||
Reference in New Issue
Block a user