Implement IC caches changes detection logic over frontend metadata
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.incremental
|
package org.jetbrains.kotlin.incremental
|
||||||
|
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
import com.intellij.openapi.util.io.FileUtil.toSystemIndependentName
|
||||||
import com.intellij.util.containers.CollectionFactory
|
import com.intellij.util.containers.CollectionFactory
|
||||||
import com.intellij.util.io.BooleanDataDescriptor
|
import com.intellij.util.io.BooleanDataDescriptor
|
||||||
@@ -29,8 +28,11 @@ import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
|||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding
|
||||||
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
|
||||||
|
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -53,6 +55,7 @@ open class IncrementalJvmCache(
|
|||||||
), IncrementalCache {
|
), IncrementalCache {
|
||||||
companion object {
|
companion object {
|
||||||
private val PROTO_MAP = "proto"
|
private val PROTO_MAP = "proto"
|
||||||
|
private val FE_PROTO_MAP = "fe-proto"
|
||||||
private val CONSTANTS_MAP = "constants"
|
private val CONSTANTS_MAP = "constants"
|
||||||
private val PACKAGE_PARTS = "package-parts"
|
private val PACKAGE_PARTS = "package-parts"
|
||||||
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
private val MULTIFILE_CLASS_FACADES = "multifile-class-facades"
|
||||||
@@ -68,6 +71,7 @@ open class IncrementalJvmCache(
|
|||||||
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
override val dirtyOutputClassesMap = registerMap(DirtyClassesJvmNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||||
|
|
||||||
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
private val protoMap = registerMap(ProtoMap(PROTO_MAP.storageFile))
|
||||||
|
private val feProtoMap = registerMap(ProtoMap(FE_PROTO_MAP.storageFile))
|
||||||
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
private val constantsMap = registerMap(ConstantsMap(CONSTANTS_MAP.storageFile))
|
||||||
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
private val packagePartMap = registerMap(PackagePartMap(PACKAGE_PARTS.storageFile))
|
||||||
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
private val multifileFacadeToParts = registerMap(MultifileClassFacadeMap(MULTIFILE_CLASS_FACADES.storageFile))
|
||||||
@@ -193,6 +197,44 @@ open class IncrementalJvmCache(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveFrontendClassToCache(
|
||||||
|
classId: ClassId,
|
||||||
|
classProto: ProtoBuf.Class,
|
||||||
|
stringTable: JvmStringTable,
|
||||||
|
sourceFiles: List<File>?,
|
||||||
|
changesCollector: ChangesCollector
|
||||||
|
) {
|
||||||
|
|
||||||
|
val className = JvmClassName.byClassId(classId)
|
||||||
|
|
||||||
|
if (sourceFiles != null) {
|
||||||
|
internalNameToSource[className.internalName] = sourceFiles
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classId.isLocal) return
|
||||||
|
|
||||||
|
val newProtoData = ClassProtoData(classProto, stringTable.toNameResolver())
|
||||||
|
addToClassStorage(newProtoData, sourceFiles?.let { sourceFiles.single() })
|
||||||
|
|
||||||
|
feProtoMap.putAndCollect(
|
||||||
|
className,
|
||||||
|
ProtoMapValue(
|
||||||
|
false,
|
||||||
|
JvmProtoBufUtil.writeDataBytes(stringTable, classProto),
|
||||||
|
stringTable.strings.toTypedArray()
|
||||||
|
),
|
||||||
|
newProtoData,
|
||||||
|
changesCollector
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun collectClassChangesByFeMetadata(
|
||||||
|
className: JvmClassName, classProto: ProtoBuf.Class, stringTable: JvmStringTable, changesCollector: ChangesCollector
|
||||||
|
) {
|
||||||
|
//class
|
||||||
|
feProtoMap.check(className, classProto, stringTable, changesCollector)
|
||||||
|
}
|
||||||
|
|
||||||
fun saveJavaClassProto(source: File?, serializedJavaClass: SerializedJavaClass, collector: ChangesCollector) {
|
fun saveJavaClassProto(source: File?, serializedJavaClass: SerializedJavaClass, collector: ChangesCollector) {
|
||||||
val jvmClassName = JvmClassName.byClassId(serializedJavaClass.classId)
|
val jvmClassName = JvmClassName.byClassId(serializedJavaClass.classId)
|
||||||
javaSourcesProtoMap.process(jvmClassName, serializedJavaClass, collector)
|
javaSourcesProtoMap.process(jvmClassName, serializedJavaClass, collector)
|
||||||
@@ -243,6 +285,7 @@ open class IncrementalJvmCache(
|
|||||||
|
|
||||||
dirtyClasses.forEach {
|
dirtyClasses.forEach {
|
||||||
protoMap.remove(it, changesCollector)
|
protoMap.remove(it, changesCollector)
|
||||||
|
feProtoMap.remove(it, changesCollector)
|
||||||
packagePartMap.remove(it)
|
packagePartMap.remove(it)
|
||||||
multifileFacadeToParts.remove(it)
|
multifileFacadeToParts.remove(it)
|
||||||
partToMultifileFacade.remove(it)
|
partToMultifileFacade.remove(it)
|
||||||
@@ -292,7 +335,12 @@ open class IncrementalJvmCache(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
|
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
|
||||||
return put(kotlinClassInfo, changesCollector)
|
return putAndCollect(
|
||||||
|
kotlinClassInfo.className,
|
||||||
|
kotlinClassInfo.protoMapValue,
|
||||||
|
kotlinClassInfo.protoData,
|
||||||
|
changesCollector
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A module mapping (.kotlin_module file) is stored in a cache,
|
// A module mapping (.kotlin_module file) is stored in a cache,
|
||||||
@@ -308,14 +356,26 @@ open class IncrementalJvmCache(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun put(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
|
fun putAndCollect(
|
||||||
val key = kotlinClassInfo.className.internalName
|
className: JvmClassName,
|
||||||
val oldData = storage[key]
|
newMapValue: ProtoMapValue,
|
||||||
val newData = kotlinClassInfo.protoMapValue
|
newProtoData: ProtoData,
|
||||||
storage[key] = newData
|
changesCollector: ChangesCollector
|
||||||
|
) {
|
||||||
|
val key = className.internalName
|
||||||
|
val oldMapValue = storage[key]
|
||||||
|
storage[key] = newMapValue
|
||||||
|
|
||||||
val packageFqName = kotlinClassInfo.className.packageFqName
|
changesCollector.collectProtoChanges(oldMapValue?.toProtoData(className.packageFqName), newProtoData, packageProtoKey = key)
|
||||||
changesCollector.collectProtoChanges(oldData?.toProtoData(packageFqName), kotlinClassInfo.protoData, packageProtoKey = key)
|
}
|
||||||
|
|
||||||
|
internal fun check(
|
||||||
|
className: JvmClassName, classProto: ProtoBuf.Class, stringTable: JvmStringTable, changesCollector: ChangesCollector
|
||||||
|
) {
|
||||||
|
val key = className.internalName
|
||||||
|
val oldProtoData = storage[key]?.toProtoData(className.packageFqName)
|
||||||
|
val newProtoData = ClassProtoData(classProto, stringTable.toNameResolver())
|
||||||
|
changesCollector.collectProtoChanges(oldProtoData, newProtoData, packageProtoKey = key)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun contains(className: JvmClassName): Boolean =
|
operator fun contains(className: JvmClassName): Boolean =
|
||||||
|
|||||||
+6
-2
@@ -56,10 +56,14 @@ object JvmProtoBufUtil {
|
|||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun writeData(message: MessageLite, stringTable: JvmStringTable): Array<String> =
|
fun writeData(message: MessageLite, stringTable: JvmStringTable): Array<String> =
|
||||||
BitEncoding.encodeBytes(ByteArrayOutputStream().apply {
|
BitEncoding.encodeBytes(writeDataBytes(stringTable, message))
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun writeDataBytes(stringTable: JvmStringTable, message: MessageLite) =
|
||||||
|
ByteArrayOutputStream().apply {
|
||||||
stringTable.serializeTo(this)
|
stringTable.serializeTo(this)
|
||||||
message.writeTo(this)
|
message.writeTo(this)
|
||||||
}.toByteArray())
|
}.toByteArray()
|
||||||
|
|
||||||
// returns JVM signature in the format: "equals(Ljava/lang/Object;)Z"
|
// returns JVM signature in the format: "equals(Ljava/lang/Object;)Z"
|
||||||
fun getJvmMethodSignature(
|
fun getJvmMethodSignature(
|
||||||
|
|||||||
Reference in New Issue
Block a user