Move all incremental cache value/externalizing types to corresponding files
Original commit: dae5b8e39e
This commit is contained in:
@@ -17,7 +17,9 @@
|
|||||||
package org.jetbrains.kotlin.jps.incremental
|
package org.jetbrains.kotlin.jps.incremental
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.util.io.*
|
import com.intellij.util.io.BooleanDataDescriptor
|
||||||
|
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||||
|
import com.intellij.util.io.IOUtil
|
||||||
import gnu.trove.THashSet
|
import gnu.trove.THashSet
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.jps.builders.BuildTarget
|
import org.jetbrains.jps.builders.BuildTarget
|
||||||
@@ -29,8 +31,7 @@ import org.jetbrains.jps.incremental.storage.PathStringDescriptor
|
|||||||
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||||
import org.jetbrains.kotlin.jps.build.GeneratedJvmClass
|
import org.jetbrains.kotlin.jps.build.GeneratedJvmClass
|
||||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||||
import org.jetbrains.kotlin.jps.incremental.storage.BasicMap
|
import org.jetbrains.kotlin.jps.incremental.storage.*
|
||||||
import org.jetbrains.kotlin.jps.incremental.storage.BasicStringMap
|
|
||||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.*
|
import org.jetbrains.kotlin.load.kotlin.header.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
@@ -38,9 +39,6 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartPro
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
import org.jetbrains.org.objectweb.asm.*
|
||||||
import java.io.DataInput
|
|
||||||
import java.io.DataInputStream
|
|
||||||
import java.io.DataOutput
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -270,7 +268,7 @@ public class IncrementalCacheImpl(
|
|||||||
cacheFormatVersion.clean()
|
cacheFormatVersion.clean()
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
|
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, PROTO_MAP_VALUE_EXTERNALIZER) {
|
||||||
|
|
||||||
public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo {
|
public fun process(kotlinClass: LocalFileKotlinClass, isPackage: Boolean, checkChangesIsOpenPart: Boolean = true): ChangesInfo {
|
||||||
val header = kotlinClass.classHeader
|
val header = kotlinClass.classHeader
|
||||||
@@ -316,7 +314,7 @@ public class IncrementalCacheImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
|
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, CONSTANTS_MAP_EXTERNALIZER) {
|
||||||
private fun getConstantsMap(bytes: ByteArray): Map<String, Any>? {
|
private fun getConstantsMap(bytes: ByteArray): Map<String, Any>? {
|
||||||
val result = HashMap<String, Any>()
|
val result = HashMap<String, Any>()
|
||||||
|
|
||||||
@@ -364,65 +362,7 @@ public class IncrementalCacheImpl(
|
|||||||
value.dumpMap(Any::toString)
|
value.dumpMap(Any::toString)
|
||||||
}
|
}
|
||||||
|
|
||||||
private object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
|
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, STRING_TO_LONG_MAP_EXTERNALIZER) {
|
||||||
override fun save(out: DataOutput, map: Map<String, Any>?) {
|
|
||||||
out.writeInt(map!!.size())
|
|
||||||
for (name in map.keySet().sorted()) {
|
|
||||||
IOUtil.writeString(name, out)
|
|
||||||
val value = map[name]!!
|
|
||||||
when (value) {
|
|
||||||
is Int -> {
|
|
||||||
out.writeByte(Kind.INT.ordinal())
|
|
||||||
out.writeInt(value)
|
|
||||||
}
|
|
||||||
is Float -> {
|
|
||||||
out.writeByte(Kind.FLOAT.ordinal())
|
|
||||||
out.writeFloat(value)
|
|
||||||
}
|
|
||||||
is Long -> {
|
|
||||||
out.writeByte(Kind.LONG.ordinal())
|
|
||||||
out.writeLong(value)
|
|
||||||
}
|
|
||||||
is Double -> {
|
|
||||||
out.writeByte(Kind.DOUBLE.ordinal())
|
|
||||||
out.writeDouble(value)
|
|
||||||
}
|
|
||||||
is String -> {
|
|
||||||
out.writeByte(Kind.STRING.ordinal())
|
|
||||||
IOUtil.writeString(value, out)
|
|
||||||
}
|
|
||||||
else -> throw IllegalStateException("Unexpected constant class: ${value.javaClass}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): Map<String, Any>? {
|
|
||||||
val size = `in`.readInt()
|
|
||||||
val map = HashMap<String, Any>(size)
|
|
||||||
|
|
||||||
repeat(size) {
|
|
||||||
val name = IOUtil.readString(`in`)!!
|
|
||||||
|
|
||||||
val kind = Kind.values()[`in`.readByte().toInt()]
|
|
||||||
val value = when (kind) {
|
|
||||||
Kind.INT -> `in`.readInt()
|
|
||||||
Kind.FLOAT -> `in`.readFloat()
|
|
||||||
Kind.LONG -> `in`.readLong()
|
|
||||||
Kind.DOUBLE -> `in`.readDouble()
|
|
||||||
Kind.STRING -> IOUtil.readString(`in`)!!
|
|
||||||
}
|
|
||||||
map[name] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum class Kind {
|
|
||||||
INT, FLOAT, LONG, DOUBLE, STRING
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class InlineFunctionsMap(storageFile: File) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
|
|
||||||
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
|
private fun getInlineFunctionsMap(bytes: ByteArray): Map<String, Long> {
|
||||||
val result = HashMap<String, Long>()
|
val result = HashMap<String, Long>()
|
||||||
|
|
||||||
@@ -508,7 +448,7 @@ public class IncrementalCacheImpl(
|
|||||||
override fun dumpValue(value: Boolean) = ""
|
override fun dumpValue(value: Boolean) = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
|
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, STRING_LIST_EXTERNALIZER) {
|
||||||
public fun add(facadeName: JvmClassName, partNames: List<String>) {
|
public fun add(facadeName: JvmClassName, partNames: List<String>) {
|
||||||
storage[facadeName.internalName] = partNames
|
storage[facadeName.internalName] = partNames
|
||||||
}
|
}
|
||||||
@@ -538,7 +478,7 @@ public class IncrementalCacheImpl(
|
|||||||
override fun dumpValue(value: String): String = value
|
override fun dumpValue(value: String): String = value
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, PathStringDescriptor.INSTANCE, StringListExternalizer) {
|
private inner class SourceToClassesMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, PathStringDescriptor.INSTANCE, STRING_LIST_EXTERNALIZER) {
|
||||||
public fun clearOutputsForSource(sourceFile: File) {
|
public fun clearOutputsForSource(sourceFile: File) {
|
||||||
storage.remove(sourceFile.absolutePath)
|
storage.remove(sourceFile.absolutePath)
|
||||||
}
|
}
|
||||||
@@ -571,7 +511,7 @@ public class IncrementalCacheImpl(
|
|||||||
override fun dumpValue(value: Boolean) = ""
|
override fun dumpValue(value: Boolean) = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
|
private inner class DirtyInlineFunctionsMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, STRING_LIST_EXTERNALIZER) {
|
||||||
public fun getEntries(): Map<JvmClassName, List<String>> =
|
public fun getEntries(): Map<JvmClassName, List<String>> =
|
||||||
storage.keys.toMap(JvmClassName::byInternalName) { storage[it]!! }
|
storage.keys.toMap(JvmClassName::byInternalName) { storage[it]!! }
|
||||||
|
|
||||||
@@ -592,7 +532,7 @@ public class IncrementalCacheImpl(
|
|||||||
* * inlineFunction - jvmSignature of some inline function in source file
|
* * inlineFunction - jvmSignature of some inline function in source file
|
||||||
* * target files - collection of files inlineFunction has been inlined to
|
* * target files - collection of files inlineFunction has been inlined to
|
||||||
*/
|
*/
|
||||||
private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap<PathFunctionPair, Collection<String>>(storageFile, PathFunctionPairKeyDescriptor, PathCollectionExternalizer) {
|
private inner class InlineFunctionsFilesMap(storageFile: File) : BasicMap<PathFunctionPair, Collection<String>>(storageFile, PATH_FUNCTION_PAIR_KEY_DESCRIPTOR, PATH_COLLECTION_EXTERNALIZER) {
|
||||||
public fun add(sourcePath: String, jvmSignature: String, targetPath: String) {
|
public fun add(sourcePath: String, jvmSignature: String, targetPath: String) {
|
||||||
val key = PathFunctionPair(sourcePath, jvmSignature)
|
val key = PathFunctionPair(sourcePath, jvmSignature)
|
||||||
storage.append(key) { out ->
|
storage.append(key) { out ->
|
||||||
@@ -661,73 +601,6 @@ private fun ByteArray.md5(): Long {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
|
||||||
override fun save(out: DataOutput, map: Map<String, T>?) {
|
|
||||||
out.writeInt(map!!.size())
|
|
||||||
|
|
||||||
for ((key, value) in map.entrySet()) {
|
|
||||||
IOUtil.writeString(key, out)
|
|
||||||
writeValue(out, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): Map<String, T>? {
|
|
||||||
val size = `in`.readInt()
|
|
||||||
val map = HashMap<String, T>(size)
|
|
||||||
|
|
||||||
repeat(size) {
|
|
||||||
val name = IOUtil.readString(`in`)!!
|
|
||||||
map[name] = readValue(`in`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return map
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun writeValue(output: DataOutput, value: T)
|
|
||||||
protected abstract fun readValue(input: DataInput): T
|
|
||||||
}
|
|
||||||
|
|
||||||
private object StringToLongMapExternalizer : StringMapExternalizer<Long>() {
|
|
||||||
override fun readValue(input: DataInput): Long =
|
|
||||||
input.readLong()
|
|
||||||
|
|
||||||
override fun writeValue(output: DataOutput, value: Long) {
|
|
||||||
output.writeLong(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private object StringListExternalizer : DataExternalizer<List<String>> {
|
|
||||||
override fun save(out: DataOutput, value: List<String>) {
|
|
||||||
value.forEach { IOUtil.writeUTF(out, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): List<String> {
|
|
||||||
val result = ArrayList<String>()
|
|
||||||
while ((`in` as DataInputStream).available() > 0) {
|
|
||||||
result.add(IOUtil.readUTF(`in`))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object PathCollectionExternalizer : DataExternalizer<Collection<String>> {
|
|
||||||
override fun save(out: DataOutput, value: Collection<String>) {
|
|
||||||
for (str in value) {
|
|
||||||
IOUtil.writeUTF(out, str)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): Collection<String> {
|
|
||||||
val result = THashSet(FileUtil.PATH_HASHING_STRATEGY)
|
|
||||||
val stream = `in` as DataInputStream
|
|
||||||
while (stream.available() > 0) {
|
|
||||||
val str = IOUtil.readUTF(stream)
|
|
||||||
result.add(str)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val File.normalizedPath: String
|
private val File.normalizedPath: String
|
||||||
get() = FileUtil.toSystemIndependentName(canonicalPath)
|
get() = FileUtil.toSystemIndependentName(canonicalPath)
|
||||||
|
|
||||||
@@ -749,68 +622,3 @@ private fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V)->String): St
|
|||||||
@TestOnly
|
@TestOnly
|
||||||
public fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
|
public fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
|
||||||
"[${sorted().joinToString(", ", transform = Any::toString)}]"
|
"[${sorted().joinToString(", ", transform = Any::toString)}]"
|
||||||
|
|
||||||
private class PathFunctionPair(
|
|
||||||
public val path: String,
|
|
||||||
public val function: String
|
|
||||||
): Comparable<PathFunctionPair> {
|
|
||||||
override fun compareTo(other: PathFunctionPair): Int {
|
|
||||||
val pathComp = FileUtil.comparePaths(path, other.path)
|
|
||||||
|
|
||||||
if (pathComp != 0) return pathComp
|
|
||||||
|
|
||||||
return function.compareTo(other.function)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
|
||||||
when (other) {
|
|
||||||
is PathFunctionPair ->
|
|
||||||
FileUtil.pathsEqual(path, other.path) && function == other.function
|
|
||||||
else ->
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int = 31 * FileUtil.pathHashCode(path) + function.hashCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
private object PathFunctionPairKeyDescriptor : KeyDescriptor<PathFunctionPair> {
|
|
||||||
override fun getHashCode(value: PathFunctionPair): Int =
|
|
||||||
value.hashCode()
|
|
||||||
|
|
||||||
override fun isEqual(val1: PathFunctionPair, val2: PathFunctionPair): Boolean =
|
|
||||||
val1 == val2
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): PathFunctionPair {
|
|
||||||
val path = IOUtil.readUTF(`in`)
|
|
||||||
val function = IOUtil.readUTF(`in`)
|
|
||||||
return PathFunctionPair(path, function)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun save(out: DataOutput, value: PathFunctionPair) {
|
|
||||||
IOUtil.writeUTF(out, value.path)
|
|
||||||
IOUtil.writeUTF(out, value.function)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private object ProtoMapValueExternalizer : DataExternalizer<ProtoMapValue> {
|
|
||||||
override fun save(out: DataOutput, value: ProtoMapValue) {
|
|
||||||
out.writeBoolean(value.isPackageFacade)
|
|
||||||
out.writeInt(value.bytes.size())
|
|
||||||
out.write(value.bytes)
|
|
||||||
out.writeInt(value.strings.size())
|
|
||||||
for (string in value.strings) {
|
|
||||||
out.writeUTF(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(`in`: DataInput): ProtoMapValue {
|
|
||||||
val isPackageFacade = `in`.readBoolean()
|
|
||||||
val bytesLength = `in`.readInt()
|
|
||||||
val bytes = ByteArray(bytesLength)
|
|
||||||
`in`.readFully(bytes, 0, bytesLength)
|
|
||||||
val stringsLength = `in`.readInt()
|
|
||||||
val strings = Array<String>(stringsLength) { `in`.readUTF() }
|
|
||||||
return ProtoMapValue(isPackageFacade, bytes, strings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import com.google.protobuf.MessageLite
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufClassKind
|
||||||
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
import org.jetbrains.kotlin.jps.incremental.ProtoCompareGenerated.ProtoBufPackageKind
|
||||||
|
import org.jetbrains.kotlin.jps.incremental.storage.ProtoMapValue
|
||||||
import org.jetbrains.kotlin.serialization.Flags
|
import org.jetbrains.kotlin.serialization.Flags
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.Deserialization
|
import org.jetbrains.kotlin.serialization.deserialization.Deserialization
|
||||||
@@ -34,7 +35,6 @@ public sealed class DifferenceKind() {
|
|||||||
public class MEMBERS(val names: Collection<String>): DifferenceKind()
|
public class MEMBERS(val names: Collection<String>): DifferenceKind()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray, val strings: Array<String>)
|
|
||||||
|
|
||||||
public fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): DifferenceKind {
|
public fun difference(oldData: ProtoMapValue, newData: ProtoMapValue): DifferenceKind {
|
||||||
if (oldData.isPackageFacade != newData.isPackageFacade) return DifferenceKind.CLASS_SIGNATURE
|
if (oldData.isPackageFacade != newData.isPackageFacade) return DifferenceKind.CLASS_SIGNATURE
|
||||||
|
|||||||
@@ -16,10 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.jps.incremental.storage
|
package org.jetbrains.kotlin.jps.incremental.storage
|
||||||
|
|
||||||
import org.jetbrains.kotlin.jps.incremental.PathCollectionExternalizer
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class LookupMap(file: File) : BasicMap<IntPair, Collection<String>>(file, INT_PAIR_KEY_DESCRIPTOR, PathCollectionExternalizer) {
|
class LookupMap(file: File) : BasicMap<IntPair, Collection<String>>(file, INT_PAIR_KEY_DESCRIPTOR, PATH_COLLECTION_EXTERNALIZER) {
|
||||||
override fun dumpKey(key: IntPair): String = key.toString()
|
override fun dumpKey(key: IntPair): String = key.toString()
|
||||||
|
|
||||||
override fun dumpValue(value: Collection<String>): String = value.toString()
|
override fun dumpValue(value: Collection<String>): String = value.toString()
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.jps.incremental.storage
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.util.io.DataExternalizer
|
||||||
|
import com.intellij.util.io.IOUtil
|
||||||
|
import com.intellij.util.io.KeyDescriptor
|
||||||
|
import gnu.trove.THashSet
|
||||||
|
import java.io.DataInput
|
||||||
|
import java.io.DataInputStream
|
||||||
|
import java.io.DataOutput
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object INT_PAIR_KEY_DESCRIPTOR : KeyDescriptor<IntPair> {
|
||||||
|
override fun read(`in`: DataInput): IntPair {
|
||||||
|
val first = `in`.readInt()
|
||||||
|
val second = `in`.readInt()
|
||||||
|
return IntPair(first, second)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun save(out: DataOutput, value: IntPair?) {
|
||||||
|
if (value == null) return
|
||||||
|
|
||||||
|
out.writeInt(value.first)
|
||||||
|
out.writeInt(value.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getHashCode(value: IntPair?): Int = value?.hashCode() ?: 0
|
||||||
|
|
||||||
|
override fun isEqual(val1: IntPair?, val2: IntPair?): Boolean = val1 == val2
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object PATH_FUNCTION_PAIR_KEY_DESCRIPTOR : KeyDescriptor<PathFunctionPair> {
|
||||||
|
override fun getHashCode(value: PathFunctionPair): Int =
|
||||||
|
value.hashCode()
|
||||||
|
|
||||||
|
override fun isEqual(val1: PathFunctionPair, val2: PathFunctionPair): Boolean =
|
||||||
|
val1 == val2
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): PathFunctionPair {
|
||||||
|
val path = IOUtil.readUTF(`in`)
|
||||||
|
val function = IOUtil.readUTF(`in`)
|
||||||
|
return PathFunctionPair(path, function)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun save(out: DataOutput, value: PathFunctionPair) {
|
||||||
|
IOUtil.writeUTF(out, value.path)
|
||||||
|
IOUtil.writeUTF(out, value.function)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object PROTO_MAP_VALUE_EXTERNALIZER : DataExternalizer<ProtoMapValue> {
|
||||||
|
override fun save(out: DataOutput, value: ProtoMapValue) {
|
||||||
|
out.writeBoolean(value.isPackageFacade)
|
||||||
|
out.writeInt(value.bytes.size())
|
||||||
|
out.write(value.bytes)
|
||||||
|
out.writeInt(value.strings.size())
|
||||||
|
for (string in value.strings) {
|
||||||
|
out.writeUTF(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): ProtoMapValue {
|
||||||
|
val isPackageFacade = `in`.readBoolean()
|
||||||
|
val bytesLength = `in`.readInt()
|
||||||
|
val bytes = ByteArray(bytesLength)
|
||||||
|
`in`.readFully(bytes, 0, bytesLength)
|
||||||
|
val stringsLength = `in`.readInt()
|
||||||
|
val strings = Array<String>(stringsLength) { `in`.readUTF() }
|
||||||
|
return ProtoMapValue(isPackageFacade, bytes, strings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
||||||
|
override fun save(out: DataOutput, map: Map<String, T>?) {
|
||||||
|
out.writeInt(map!!.size())
|
||||||
|
|
||||||
|
for ((key, value) in map.entrySet()) {
|
||||||
|
IOUtil.writeString(key, out)
|
||||||
|
writeValue(out, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): Map<String, T>? {
|
||||||
|
val size = `in`.readInt()
|
||||||
|
val map = HashMap<String, T>(size)
|
||||||
|
|
||||||
|
repeat(size) {
|
||||||
|
val name = IOUtil.readString(`in`)!!
|
||||||
|
map[name] = readValue(`in`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun writeValue(output: DataOutput, value: T)
|
||||||
|
protected abstract fun readValue(input: DataInput): T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object STRING_TO_LONG_MAP_EXTERNALIZER : StringMapExternalizer<Long>() {
|
||||||
|
override fun readValue(input: DataInput): Long =
|
||||||
|
input.readLong()
|
||||||
|
|
||||||
|
override fun writeValue(output: DataOutput, value: Long) {
|
||||||
|
output.writeLong(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object STRING_LIST_EXTERNALIZER : DataExternalizer<List<String>> {
|
||||||
|
override fun save(out: DataOutput, value: List<String>) {
|
||||||
|
value.forEach { IOUtil.writeUTF(out, it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): List<String> {
|
||||||
|
val result = ArrayList<String>()
|
||||||
|
while ((`in` as DataInputStream).available() > 0) {
|
||||||
|
result.add(IOUtil.readUTF(`in`))
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object PATH_COLLECTION_EXTERNALIZER : DataExternalizer<Collection<String>> {
|
||||||
|
override fun save(out: DataOutput, value: Collection<String>) {
|
||||||
|
for (str in value) {
|
||||||
|
IOUtil.writeUTF(out, str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): Collection<String> {
|
||||||
|
val result = THashSet(FileUtil.PATH_HASHING_STRATEGY)
|
||||||
|
val stream = `in` as DataInputStream
|
||||||
|
while (stream.available() > 0) {
|
||||||
|
val str = IOUtil.readUTF(stream)
|
||||||
|
result.add(str)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object CONSTANTS_MAP_EXTERNALIZER : DataExternalizer<Map<String, Any>> {
|
||||||
|
override fun save(out: DataOutput, map: Map<String, Any>?) {
|
||||||
|
out.writeInt(map!!.size())
|
||||||
|
for (name in map.keySet().sorted()) {
|
||||||
|
IOUtil.writeString(name, out)
|
||||||
|
val value = map[name]!!
|
||||||
|
when (value) {
|
||||||
|
is Int -> {
|
||||||
|
out.writeByte(Kind.INT.ordinal())
|
||||||
|
out.writeInt(value)
|
||||||
|
}
|
||||||
|
is Float -> {
|
||||||
|
out.writeByte(Kind.FLOAT.ordinal())
|
||||||
|
out.writeFloat(value)
|
||||||
|
}
|
||||||
|
is Long -> {
|
||||||
|
out.writeByte(Kind.LONG.ordinal())
|
||||||
|
out.writeLong(value)
|
||||||
|
}
|
||||||
|
is Double -> {
|
||||||
|
out.writeByte(Kind.DOUBLE.ordinal())
|
||||||
|
out.writeDouble(value)
|
||||||
|
}
|
||||||
|
is String -> {
|
||||||
|
out.writeByte(Kind.STRING.ordinal())
|
||||||
|
IOUtil.writeString(value, out)
|
||||||
|
}
|
||||||
|
else -> throw IllegalStateException("Unexpected constant class: ${value.javaClass}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun read(`in`: DataInput): Map<String, Any>? {
|
||||||
|
val size = `in`.readInt()
|
||||||
|
val map = HashMap<String, Any>(size)
|
||||||
|
|
||||||
|
repeat(size) {
|
||||||
|
val name = IOUtil.readString(`in`)!!
|
||||||
|
|
||||||
|
val kind = Kind.values()[`in`.readByte().toInt()]
|
||||||
|
val value = when (kind) {
|
||||||
|
Kind.INT -> `in`.readInt()
|
||||||
|
Kind.FLOAT -> `in`.readFloat()
|
||||||
|
Kind.LONG -> `in`.readLong()
|
||||||
|
Kind.DOUBLE -> `in`.readDouble()
|
||||||
|
Kind.STRING -> IOUtil.readString(`in`)!!
|
||||||
|
}
|
||||||
|
map[name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class Kind {
|
||||||
|
INT, FLOAT, LONG, DOUBLE, STRING
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
-17
@@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.jps.incremental.storage
|
package org.jetbrains.kotlin.jps.incremental.storage
|
||||||
|
|
||||||
import com.intellij.util.io.KeyDescriptor
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import java.io.DataInput
|
|
||||||
import java.io.DataOutput
|
|
||||||
|
|
||||||
data class IntPair(val first: Int, val second: Int) : Comparable<IntPair> {
|
data class IntPair(val first: Int, val second: Int) : Comparable<IntPair> {
|
||||||
override fun compareTo(other: IntPair): Int {
|
override fun compareTo(other: IntPair): Int {
|
||||||
@@ -32,21 +30,27 @@ data class IntPair(val first: Int, val second: Int) : Comparable<IntPair> {
|
|||||||
|
|
||||||
fun HashPair(a: Any, b: Any): IntPair = IntPair(a.hashCode(), b.hashCode())
|
fun HashPair(a: Any, b: Any): IntPair = IntPair(a.hashCode(), b.hashCode())
|
||||||
|
|
||||||
internal object INT_PAIR_KEY_DESCRIPTOR : KeyDescriptor<IntPair> {
|
class PathFunctionPair(
|
||||||
override fun read(`in`: DataInput): IntPair {
|
public val path: String,
|
||||||
val first = `in`.readInt()
|
public val function: String
|
||||||
val second = `in`.readInt()
|
): Comparable<PathFunctionPair> {
|
||||||
return IntPair(first, second)
|
override fun compareTo(other: PathFunctionPair): Int {
|
||||||
|
val pathComp = FileUtil.comparePaths(path, other.path)
|
||||||
|
|
||||||
|
if (pathComp != 0) return pathComp
|
||||||
|
|
||||||
|
return function.compareTo(other.function)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun save(out: DataOutput, value: IntPair?) {
|
override fun equals(other: Any?): Boolean =
|
||||||
if (value == null) return
|
when (other) {
|
||||||
|
is PathFunctionPair ->
|
||||||
|
FileUtil.pathsEqual(path, other.path) && function == other.function
|
||||||
|
else ->
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
out.writeInt(value.first)
|
override fun hashCode(): Int = 31 * FileUtil.pathHashCode(path) + function.hashCode()
|
||||||
out.writeInt(value.second)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getHashCode(value: IntPair?): Int = value?.hashCode() ?: 0
|
data class ProtoMapValue(val isPackageFacade: Boolean, val bytes: ByteArray, val strings: Array<String>)
|
||||||
|
|
||||||
override fun isEqual(val1: IntPair?, val2: IntPair?): Boolean = val1 == val2
|
|
||||||
}
|
|
||||||
+5
-1
@@ -18,7 +18,11 @@ package org.jetbrains.kotlin.jps.incremental
|
|||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.testFramework.UsefulTestCase
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.*
|
import org.jetbrains.kotlin.jps.incremental.storage.ProtoMapValue
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleMultifileClassPartKind
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind
|
||||||
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||||
|
|||||||
Reference in New Issue
Block a user