Introduce string table in for Serialized IR.

This commit is contained in:
Alexander Gorshenev
2019-01-28 20:09:20 +03:00
committed by alexander-gorshenev
parent a9176c736b
commit 814d38f874
6 changed files with 200 additions and 100 deletions
@@ -2,31 +2,46 @@ package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.metadata.KonanIr
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
// This is all information needed to find a descriptor in the
// tree of deserialized descriptors. Think of it as base + offset.
// packageFqName + classFqName + index allow to localize some deserialized descriptor.
// Then the rest of the fields allow to find the needed descriptor relative to the one with index.
class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val resolvedForwardDeclarations: MutableMap<UniqIdKey, UniqIdKey>) {
fun deserializeDescriptorReference(
packageFqNameString: String,
classFqNameString: String,
name: String,
index: Long?,
isEnumEntry: Boolean = false,
isEnumSpecial: Boolean = false,
isDefaultConstructor: Boolean = false,
isFakeOverride: Boolean = false,
isGetter: Boolean = false,
isSetter: Boolean = false
): DeclarationDescriptor {
val packageFqName = packageFqNameString.let {
if (it == "<root>") FqName.ROOT else FqName(it)
}// TODO: whould we store an empty string in the protobuf?
fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor {
val packageFqName =
if (proto.packageFqName == "<root>") FqName.ROOT else FqName(proto.packageFqName) // TODO: whould we store an empty string in the protobuf?
val classFqName = FqName(proto.classFqName)
val protoIndex = if (proto.hasUniqId()) proto.uniqId.index else null
val classFqName = FqName(classFqNameString)
val protoIndex = index
val (clazz, members) = if (proto.classFqName == "") {
val (clazz, members) = if (classFqNameString == "") {
Pair(null, currentModule.getPackage(packageFqName).memberScope.getContributedDescriptors())
} else {
val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!!
Pair(clazz, clazz.unsubstitutedMemberScope.getContributedDescriptors() + clazz.getConstructors())
}
if (proto.packageFqName.startsWith("cnames.") || proto.packageFqName.startsWith("objcnames.")) {
if (packageFqNameString.startsWith("cnames.") || packageFqNameString.startsWith("objcnames.")) {
val descriptor =
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(proto.name), false))!!
currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, FqName(name), false))!!
if (!descriptor.fqNameUnsafe.asString().startsWith("cnames") && !descriptor.fqNameUnsafe.asString().startsWith(
"objcnames"
)
@@ -44,23 +59,21 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
return descriptor
}
if (proto.isEnumEntry) {
val name = proto.name
if (isEnumEntry) {
val memberScope = (clazz as DeserializedClassDescriptor).getUnsubstitutedMemberScope()
return memberScope.getContributedClassifier(Name.identifier(name), NoLookupLocation.FROM_BACKEND)!!
}
if (proto.isEnumSpecial) {
val name = proto.name
if (isEnumSpecial) {
return clazz!!.getStaticScope()
.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BACKEND).single()
}
members.forEach { member ->
if (proto.isDefaultConstructor && member is ClassConstructorDescriptor) return member
if (isDefaultConstructor && member is ClassConstructorDescriptor) return member
val realMembers =
if (proto.isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
if (isFakeOverride && member is CallableMemberDescriptor && member.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
member.resolveFakeOverrideMaybeAbstract()
else
setOf(member)
@@ -69,12 +82,12 @@ class DescriptorReferenceDeserializer(val currentModule: ModuleDescriptor, val r
if (memberIndices.contains(protoIndex)) {
return when {
member is PropertyDescriptor && proto.isSetter -> member.setter!!
member is PropertyDescriptor && proto.isGetter -> member.getter!!
member is PropertyDescriptor && isSetter -> member.setter!!
member is PropertyDescriptor && isGetter -> member.getter!!
else -> member
}
}
}
error("Could not find serialized descriptor for index: ${proto.uniqId.index} ${proto.packageFqName},${proto.classFqName},${proto.name}")
error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}")
}
}
@@ -62,6 +62,7 @@ abstract class IrModuleDeserializer(
abstract fun deserializeIrSymbol(proto: KonanIr.IrSymbol): IrSymbol
abstract fun deserializeIrType(proto: KonanIr.IrTypeIndex): IrType
abstract fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor
abstract fun deserializeString(proto: KonanIr.String): String
private fun deserializeTypeArguments(proto: KonanIr.TypeArguments): List<IrType> {
logger.log { "### deserializeTypeArguments" }
@@ -540,7 +541,7 @@ abstract class IrModuleDeserializer(
val loopId = proto.loopId
loopIndex.getOrPut(loopId) { loop }
val label = if (proto.hasLabel()) proto.label else null
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
val body = if (proto.hasBody()) deserializeExpression(proto.body) else null
val condition = deserializeExpression(proto.condition)
@@ -568,7 +569,7 @@ abstract class IrModuleDeserializer(
}
private fun deserializeBreak(proto: KonanIr.IrBreak, start: Int, end: Int, type: IrType): IrBreak {
val label = if (proto.hasLabel()) proto.label else null
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
val loopId = proto.loopId
val loop = loopIndex[loopId]!!
val irBreak = IrBreakImpl(start, end, type, loop)
@@ -578,7 +579,7 @@ abstract class IrModuleDeserializer(
}
private fun deserializeContinue(proto: KonanIr.IrContinue, start: Int, end: Int, type: IrType): IrContinue {
val label = if (proto.hasLabel()) proto.label else null
val label = if (proto.hasLabel()) deserializeString(proto.label) else null
val loopId = proto.loopId
val loop = loopIndex[loopId]!!
val irContinue = IrContinueImpl(start, end, type, loop)
@@ -604,7 +605,7 @@ abstract class IrModuleDeserializer(
LONG
-> IrConstImpl.long(start, end, type, proto.long)
STRING
-> IrConstImpl.string(start, end, type, proto.string)
-> IrConstImpl.string(start, end, type, deserializeString(proto.string))
FLOAT
-> IrConstImpl.float(start, end, type, proto.float)
DOUBLE
@@ -693,7 +694,7 @@ abstract class IrModuleDeserializer(
origin: IrDeclarationOrigin
): IrTypeParameter {
val symbol = deserializeIrSymbol(proto.symbol) as IrTypeParameterSymbol
val name = Name.identifier(proto.name)
val name = Name.identifier(deserializeString(proto.name))
val variance = deserializeIrTypeVariance(proto.variance)
val parameter = symbolTable.declareGlobalTypeParameter(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
@@ -741,7 +742,7 @@ abstract class IrModuleDeserializer(
IrValueParameterImpl(
start, end, origin,
deserializeIrSymbol(proto.symbol) as IrValueParameterSymbol,
Name.identifier(proto.name),
Name.identifier(deserializeString(proto.name)),
proto.index,
deserializeIrType(proto.type),
varargElementType,
@@ -763,11 +764,11 @@ abstract class IrModuleDeserializer(
val modality = deserializeModality(proto.modality)
val clazz = symbolTable.declareClass(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
symbol.descriptor, modality) { symbol ->
symbol.descriptor, modality) {
IrClassImpl(
start, end, origin,
symbol,
Name.identifier(proto.name),
it,
Name.identifier(deserializeString(proto.name)),
deserializeClassKind(proto.kind),
deserializeVisibility(proto.visibility),
modality,
@@ -825,14 +826,14 @@ abstract class IrModuleDeserializer(
start: Int, end: Int, origin: IrDeclarationOrigin, correspondingProperty: IrProperty? = null
): IrSimpleFunction {
logger.log { "### deserializing IrFunction ${proto.base.name}" }
logger.log { "### deserializing IrFunction ${deserializeString(proto.base.name)}" }
val symbol = deserializeIrSymbol(proto.symbol) as IrSimpleFunctionSymbol
val function = symbolTable.declareSimpleFunction(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irrelevantOrigin,
symbol.descriptor, {
IrFunctionImpl(
start, end, origin, it,
Name.identifier(proto.base.name),
Name.identifier(deserializeString(proto.base.name)),
deserializeVisibility(proto.base.visibility),
deserializeModality(proto.modality),
deserializeIrType(proto.base.returnType),
@@ -869,7 +870,7 @@ abstract class IrModuleDeserializer(
end,
origin,
symbol,
Name.identifier(proto.name),
Name.identifier(deserializeString(proto.name)),
type,
proto.isVar,
proto.isConst,
@@ -891,7 +892,7 @@ abstract class IrModuleDeserializer(
irrelevantOrigin,
symbol.descriptor
) {
IrEnumEntryImpl(start, end, origin, it, Name.identifier(proto.name))
IrEnumEntryImpl(start, end, origin, it, Name.identifier(deserializeString(proto.name)))
}
if (proto.hasCorrespondingClass()) {
@@ -916,8 +917,8 @@ abstract class IrModuleDeserializer(
return initializer
}
private fun deserializeVisibility(value: String): Visibility { // TODO: switch to enum
return when (value) {
private fun deserializeVisibility(value: KonanIr.Visibility): Visibility { // TODO: switch to enum
return when (deserializeString(value.name)) {
"public" -> Visibilities.PUBLIC
"private" -> Visibilities.PRIVATE
"private_to_this" -> Visibilities.PRIVATE_TO_THIS
@@ -942,7 +943,7 @@ abstract class IrModuleDeserializer(
IrConstructorImpl(
start, end, origin,
it,
Name.identifier(proto.base.name),
Name.identifier(deserializeString(proto.base.name)),
deserializeVisibility(proto.base.visibility),
deserializeIrType(proto.base.returnType),
proto.base.isInline,
@@ -968,7 +969,7 @@ abstract class IrModuleDeserializer(
{ IrFieldImpl(
start, end, origin,
it,
Name.identifier(proto.name),
Name.identifier(deserializeString(proto.name)),
type,
deserializeVisibility(proto.visibility),
proto.isFinal,
@@ -1009,7 +1010,7 @@ abstract class IrModuleDeserializer(
val property = IrPropertyImpl(
start, end, origin,
descriptor,
Name.identifier(proto.name),
Name.identifier(deserializeString(proto.name)),
deserializeVisibility(proto.visibility),
deserializeModality(proto.modality),
proto.isVar,
@@ -1068,12 +1069,13 @@ abstract class IrModuleDeserializer(
IrDeclarationOrigin::class.nestedClasses.toList() + DeclarationFactory.FIELD_FOR_OUTER_THIS::class
val originIndex = allKnownOrigins.map { it.objectInstance as IrDeclarationOriginImpl }.associateBy { it.name }
val irrelevantOrigin = object : IrDeclarationOriginImpl("irrelevant") {}
fun deserializeIrDeclarationOrigin(proto: KonanIr.IrDeclarationOrigin) = originIndex[deserializeString(proto.custom)]!!
protected fun deserializeDeclaration(proto: KonanIr.IrDeclaration, parent: IrDeclarationParent?): IrDeclaration {
val start = proto.coordinates.startOffset
val end = proto.coordinates.endOffset
val origin = originIndex[proto.origin.name]!!
val origin = deserializeIrDeclarationOrigin(proto.origin)
val declarator = proto.declarator
@@ -51,7 +51,7 @@ internal class IrModuleSerializer(
private val loopIndex = mutableMapOf<IrLoop, Int>()
private var currentLoopIndex = 0
val descriptorReferenceSerializer = DescriptorReferenceSerializer(declarationTable)
val descriptorReferenceSerializer = DescriptorReferenceSerializer(declarationTable, { string -> serializeString(string) })
// The same symbol can be used multiple times in a module
// so use this index to store symbol data only once.
@@ -63,6 +63,44 @@ internal class IrModuleSerializer(
val protoTypeMap = mutableMapOf<IrTypeKey, Int>()
val protoTypeArray = arrayListOf<KonanIr.IrType>()
val protoStringMap = mutableMapOf<String, Int>()
val protoStringArray = arrayListOf<String>()
/* ------- Common fields ---------------------------------------------------- */
private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin) =
KonanIr.IrDeclarationOrigin.newBuilder()
.setCustom(serializeString((origin as IrDeclarationOriginImpl).name))
.build()
private fun serializeIrStatementOrigin(origin: IrStatementOrigin) =
KonanIr.IrStatementOrigin.newBuilder()
.setName(serializeString((origin as IrStatementOriginImpl).debugName))
.build()
private fun serializeVisibility(visibility: Visibility) =
KonanIr.Visibility.newBuilder()
.setName(serializeString(visibility.name))
.build()
private fun serializeCoordinates(start: Int, end: Int): KonanIr.Coordinates {
return KonanIr.Coordinates.newBuilder()
.setStartOffset(start)
.setEndOffset(end)
.build()
}
/* ------- Strings ---------------------------------------------------------- */
fun serializeString(value: String): KonanIr.String {
val proto = KonanIr.String.newBuilder()
proto.index = protoStringMap.getOrPut(value) {
protoStringArray.add(value)
protoStringArray.size - 1
}
return proto.build()
}
/* ------- IrSymbols -------------------------------------------------------- */
fun protoSymbolKind(symbol: IrSymbol): KonanIr.IrSymbolKind = when (symbol) {
@@ -377,7 +415,7 @@ internal class IrModuleSerializer(
val proto = KonanIr.IrFunctionReference.newBuilder()
.setSymbol(serializeIrSymbol(callable.symbol))
.setMemberAccess(serializeMemberAccessCommon(callable))
callable.origin?.let { proto.origin = (it as IrStatementOriginImpl).debugName }
callable.origin?.let { proto.origin = serializeIrStatementOrigin(it) }
return proto.build()
}
@@ -388,7 +426,7 @@ internal class IrModuleSerializer(
callable.field?.let { proto.field = serializeIrSymbol(it) }
callable.getter?.let { proto.getter = serializeIrSymbol(it) }
callable.setter?.let { proto.setter = serializeIrSymbol(it) }
callable.origin?.let { proto.origin = (it as IrStatementOriginImpl).debugName }
callable.origin?.let { proto.origin = serializeIrStatementOrigin(it) }
return proto.build()
}
@@ -409,7 +447,7 @@ internal class IrModuleSerializer(
IrConstKind.Short -> proto.short = (value.value as Short).toInt()
IrConstKind.Int -> proto.int = value.value as Int
IrConstKind.Long -> proto.long = value.value as Long
IrConstKind.String -> proto.string = value.value as String
IrConstKind.String -> proto.string = serializeString(value.value as String)
IrConstKind.Float -> proto.float = value.value as Float
IrConstKind.Double -> proto.double = value.value as Double
}
@@ -606,7 +644,7 @@ internal class IrModuleSerializer(
private fun serializeLoop(expression: IrLoop): KonanIr.Loop {
val proto = KonanIr.Loop.newBuilder()
.setCondition(serializeExpression(expression.condition))
val label = expression.label
val label = expression.label?.let { serializeString(it) }
if (label != null) {
proto.label = label
}
@@ -631,7 +669,7 @@ internal class IrModuleSerializer(
private fun serializeBreak(expression: IrBreak): KonanIr.IrBreak {
val proto = KonanIr.IrBreak.newBuilder()
val label = expression.label
val label = expression.label?.let { serializeString(it) }
if (label != null) {
proto.label = label
}
@@ -643,7 +681,7 @@ internal class IrModuleSerializer(
private fun serializeContinue(expression: IrContinue): KonanIr.IrContinue {
val proto = KonanIr.IrContinue.newBuilder()
val label = expression.label
val label = expression.label?.let { serializeString(it) }
if (label != null) {
proto.label = label
}
@@ -653,13 +691,6 @@ internal class IrModuleSerializer(
return proto.build()
}
private fun serializeCoordinates(start: Int, end: Int): KonanIr.Coordinates {
return KonanIr.Coordinates.newBuilder()
.setStartOffset(start)
.setEndOffset(end)
.build()
}
private fun serializeExpression(expression: IrExpression): KonanIr.IrExpression {
logger.log { "### serializing Expression: ${ir2string(expression)}" }
@@ -758,7 +789,7 @@ internal class IrModuleSerializer(
private fun serializeIrValueParameter(parameter: IrValueParameter): KonanIr.IrValueParameter {
val proto = KonanIr.IrValueParameter.newBuilder()
.setSymbol(serializeIrSymbol(parameter.symbol))
.setName(parameter.name.toString())
.setName(serializeString(parameter.name.toString()))
.setIndex(parameter.index)
.setType(serializeIrType(parameter.type))
.setIsCrossinline(parameter.isCrossinline)
@@ -773,7 +804,7 @@ internal class IrModuleSerializer(
private fun serializeIrTypeParameter(parameter: IrTypeParameter): KonanIr.IrTypeParameter {
val proto = KonanIr.IrTypeParameter.newBuilder()
.setSymbol(serializeIrSymbol(parameter.symbol))
.setName(parameter.name.toString())
.setName(serializeString(parameter.name.toString()))
.setIndex(parameter.index)
.setVariance(serializeIrTypeVariance(parameter.variance))
.setIsReified(parameter.isReified)
@@ -793,7 +824,7 @@ internal class IrModuleSerializer(
private fun serializeIrFunctionBase(function: IrFunctionBase): KonanIr.IrFunctionBase {
val proto = KonanIr.IrFunctionBase.newBuilder()
.setName(function.name.toString())
.setName(serializeString(function.name.toString()))
.setVisibility(serializeVisibility(function.visibility))
.setIsInline(function.isInline)
.setIsExternal(function.isExternal)
@@ -854,16 +885,12 @@ internal class IrModuleSerializer(
.setBody(serializeStatement(declaration.body))
.build()
private fun serializeVisibility(visibility: Visibility): String {
return visibility.name
}
private fun serializeIrProperty(property: IrProperty): KonanIr.IrProperty {
val index = declarationTable.uniqIdByDeclaration(property)
val proto = KonanIr.IrProperty.newBuilder()
.setIsDelegated(property.isDelegated)
.setName(property.name.toString())
.setName(serializeString(property.name.toString()))
.setVisibility(serializeVisibility(property.visibility))
.setModality(serializeModality(property.modality))
.setIsVar(property.isVar)
@@ -890,7 +917,7 @@ internal class IrModuleSerializer(
private fun serializeIrField(field: IrField): KonanIr.IrField {
val proto = KonanIr.IrField.newBuilder()
.setSymbol(serializeIrSymbol(field.symbol))
.setName(field.name.toString())
.setName(serializeString(field.name.toString()))
.setVisibility(serializeVisibility(field.visibility))
.setIsFinal(field.isFinal)
.setIsExternal(field.isExternal)
@@ -906,7 +933,7 @@ internal class IrModuleSerializer(
private fun serializeIrVariable(variable: IrVariable): KonanIr.IrVariable {
val proto = KonanIr.IrVariable.newBuilder()
.setSymbol(serializeIrSymbol(variable.symbol))
.setName(variable.name.toString())
.setName(serializeString(variable.name.toString()))
.setType(serializeIrType(variable.type))
.setIsConst(variable.isConst)
.setIsVar(variable.isVar)
@@ -935,7 +962,7 @@ internal class IrModuleSerializer(
private fun serializeIrClass(clazz: IrClass): KonanIr.IrClass {
val proto = KonanIr.IrClass.newBuilder()
.setName(clazz.name.toString())
.setName(serializeString(clazz.name.toString()))
.setSymbol(serializeIrSymbol(clazz.symbol))
.setKind(serializeClassKind(clazz.kind))
.setVisibility(serializeVisibility(clazz.visibility))
@@ -957,7 +984,7 @@ internal class IrModuleSerializer(
private fun serializeIrEnumEntry(enumEntry: IrEnumEntry): KonanIr.IrEnumEntry {
val proto = KonanIr.IrEnumEntry.newBuilder()
.setName(enumEntry.name.toString())
.setName(serializeString(enumEntry.name.toString()))
.setSymbol(serializeIrSymbol(enumEntry.symbol))
enumEntry.initializerExpression?.let {
@@ -969,10 +996,6 @@ internal class IrModuleSerializer(
return proto.build()
}
private fun serializeIrDeclarationOrigin(origin: IrDeclarationOrigin) =
KonanIr.IrDeclarationOrigin.newBuilder()
.setName((origin as IrDeclarationOriginImpl).name)
private fun serializeDeclaration(declaration: IrDeclaration): KonanIr.IrDeclaration {
logger.log { "### serializing Declaration: ${ir2string(declaration)}" }
@@ -1020,7 +1043,7 @@ internal class IrModuleSerializer(
//val fileName = context.ir.originalModuleIndex.declarationToFile[declaration.descriptor]
//proto.fileName = fileName
proto.fileName = "some file name"
proto.fileName = serializeString("some file name")
return proto.build()
}
@@ -1028,7 +1051,7 @@ internal class IrModuleSerializer(
// ---------- Top level ------------------------------------------------------
fun serializeFileEntry(entry: SourceManager.FileEntry) = KonanIr.FileEntry.newBuilder()
.setName(entry.name)
.setName(serializeString(entry.name))
.build()
val topLevelDeclarations = mutableMapOf<UniqId, ByteArray>()
@@ -1054,7 +1077,7 @@ internal class IrModuleSerializer(
fun serializeModule(module: IrModuleFragment): KonanIr.IrModule {
val proto = KonanIr.IrModule.newBuilder()
.setName(module.name.toString())
.setName(serializeString(module.name.toString()))
module.files.forEach {
proto.addFile(serializeIrFile(it))
}
@@ -1066,6 +1089,10 @@ internal class IrModuleSerializer(
.addAllTypes(protoTypeArray)
.build()
proto.stringTable = KonanIr.StringTable.newBuilder()
.addAllStrings(protoStringArray)
.build()
return proto.build()
}
@@ -28,6 +28,52 @@ message Coordinates {
required int32 end_offset = 2;
}
message Visibility {
required String name = 1;
}
message IrStatementOrigin {
required String name = 1;
}
enum KnownOrigin {
CUSTOM = 1;
DEFINED = 2;
FAKE_OVERRIDE = 3;
FOR_LOOP_ITERATOR = 4;
FOR_LOOP_VARIABLE = 5;
FOR_LOOP_IMPLICIT_VARIABLE = 6;
PROPERTY_BACKING_FIELD = 7;
DEFAULT_PROPERTY_ACCESSOR = 8;
DELEGATE = 9;
DELEGATED_PROPERTY_ACCESSOR = 10;
DELEGATED_MEMBER = 11;
ENUM_CLASS_SPECIAL_MEMBER = 12;
FUNCTION_FOR_DEFAULT_PARAMETER = 13;
FILE_CLASS = 14;
GENERATED_DATA_CLASS_MEMBER = 15;
GENERATED_INLINE_CLASS_MEMBER = 16;
LOCAL_FUNCTION_FOR_LAMBDA = 17;
CATCH_PARAMETER = 19;
INSTANCE_RECEIVER = 20;
PRIMARY_CONSTRUCTOR_PARAMETER = 21;
IR_TEMPORARY_VARIABLE = 22;
IR_EXTERNAL_DECLARATION_STUB = 23;
IR_EXTERNAL_JAVA_DECLARATION_STUB = 24;
IR_BUILTINS_STUB = 25;
BRIDGE = 26;
FIELD_FOR_ENUM_ENTRY = 27;
FIELD_FOR_ENUM_VALUES = 28;
FIELD_FOR_OBJECT_INSTANCE = 29;
}
message IrDeclarationOrigin {
oneof either {
KnownOrigin origin = 1;
String custom = 2;
}
}
/* ------ Top Level---------------------------------------KonanIrModuleDeserializer.kt------- */
message IrDeclarationContainer {
@@ -35,7 +81,7 @@ message IrDeclarationContainer {
}
message FileEntry { // TODO: extend me.
required string name = 1;
required String name = 1;
}
message IrFile {
@@ -46,10 +92,11 @@ message IrFile {
}
message IrModule {
required string name = 1;
required String name = 1;
repeated IrFile file = 2;
required IrSymbolTable symbol_table = 3;
required IrTypeTable type_table = 4;
required StringTable string_table = 5;
}
/* ------ String Table ------------------------------------------ */
@@ -59,7 +106,7 @@ message String {
}
message StringTable {
repeated string value = 1;
repeated string strings = 1;
}
/* ------ IrSymbols --------------------------------------------- */
@@ -193,7 +240,7 @@ message IrCall {
message IrFunctionReference {
required IrSymbol symbol = 1;
optional Origin origin = 2;
optional IrStatementOrigin origin = 2;
required MemberAccessCommon member_access = 3;
}
@@ -202,7 +249,7 @@ message IrPropertyReference {
optional IrSymbol field = 1;
optional IrSymbol getter = 2;
optional IrSymbol setter = 3;
optional Origin origin = 4;
optional IrStatementOrigin origin = 4;
required MemberAccessCommon member_access = 5;
}
@@ -421,8 +468,8 @@ message IrFunction {
}
message IrFunctionBase {
required string name = 1;
required string visibility = 2;
required String name = 1;
required Visibility visibility = 2;
required bool is_inline = 3;
required bool is_external = 4;
required IrTypeParameterContainer type_parameters = 5;
@@ -443,8 +490,8 @@ message IrConstructor {
message IrField {
required IrSymbol symbol = 1;
optional IrExpression initializer = 2;
required string name = 3;
required string visibility = 4;
required String name = 3;
required Visibility visibility = 4;
required bool is_final = 5;
required bool is_external = 6;
required bool is_static = 7;
@@ -453,8 +500,8 @@ message IrField {
message IrProperty {
optional DescriptorReference descriptor = 1; // IrProperty doesn't have a symbol at all. Preserve this rudiment for now.
required string name = 2;
required string visibility = 3;
required String name = 2;
required Visibility visibility = 3;
required ModalityKind modality = 4;
required bool is_var = 5;
required bool is_const = 6;
@@ -467,7 +514,7 @@ message IrProperty {
}
message IrVariable {
required string name = 1;
required String name = 1;
required IrSymbol symbol = 2;
required IrTypeIndex type = 3;
required bool is_var = 4;
@@ -494,7 +541,7 @@ enum ModalityKind { // It is ModalityKind to not clash with Modality in descript
message IrValueParameter {
required IrSymbol symbol = 1;
required string name = 2;
required String name = 2;
required int32 index = 3;
required IrTypeIndex type = 4;
optional IrTypeIndex vararg_element_type = 5;
@@ -505,7 +552,7 @@ message IrValueParameter {
message IrTypeParameter {
required IrSymbol symbol = 1;
required string name = 2;
required String name = 2;
required int32 index = 3;
required IrTypeVariance variance = 4;
repeated IrTypeIndex super_type = 5;
@@ -518,9 +565,9 @@ message IrTypeParameterContainer {
message IrClass {
required IrSymbol symbol = 1;
required string name = 2;
required String name = 2;
required ClassKind kind = 3;
required string visibility = 4;
required Visibility visibility = 4;
required ModalityKind modality = 5;
// TODO: consider using flags for the booleans.
required bool is_companion = 6;
@@ -538,7 +585,7 @@ message IrEnumEntry {
required IrSymbol symbol = 1;
optional IrExpression initializer = 2;
optional IrDeclaration corresponding_class = 3;
required string name = 4;
required String name = 4;
}
message IrAnonymousInit {
@@ -564,17 +611,12 @@ message IrDeclarator {
}
}
message IrDeclarationOrigin {
required string name = 1;
}
message IrDeclaration {
required IrDeclarationOrigin origin = 1;
required Coordinates coordinates = 2;
required Annotations annotations = 3;
required IrDeclarator declarator = 4;
//repeated IrDeclaration nested = 5;
required string file_name = 5; // TODO: files should be communicated some other way, I suppose.
required String file_name = 5; // TODO: files should be communicated some other way, I suppose.
}
/* ------- IrStatements --------------------------------------------- */
@@ -56,6 +56,7 @@ class KonanIrModuleDeserializer(
var deserializedModuleDescriptor: ModuleDescriptor? = null
var deserializedModuleProtoSymbolTables = mutableMapOf<ModuleDescriptor, KonanIr.IrSymbolTable>()
var deserializedModuleProtoStringTables = mutableMapOf<ModuleDescriptor, KonanIr.StringTable>()
var deserializedModuleProtoTypeTables = mutableMapOf<ModuleDescriptor, KonanIr.IrTypeTable>()
val resolvedForwardDeclarations = mutableMapOf<UniqIdKey, UniqIdKey>()
@@ -139,6 +140,9 @@ class KonanIrModuleDeserializer(
return deserializeIrTypeData(typeData)
}
override fun deserializeString(proto: KonanIr.String) =
deserializedModuleProtoStringTables[deserializedModuleDescriptor]!!.getStrings(proto.index)
fun deserializeIrSymbolData(proto: KonanIr.IrSymbolData): IrSymbol {
val key = proto.uniqId.uniqIdKey(deserializedModuleDescriptor!!)
val topLevelKey = proto.topLevelUniqId.uniqIdKey(deserializedModuleDescriptor!!)
@@ -169,8 +173,19 @@ class KonanIrModuleDeserializer(
return symbol
}
override fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference)
= descriptorReferenceDeserializer.deserializeDescriptorReference(proto)
override fun deserializeDescriptorReference(proto: KonanIr.DescriptorReference): DeclarationDescriptor =
descriptorReferenceDeserializer.deserializeDescriptorReference(
deserializeString(proto.packageFqName),
deserializeString(proto.classFqName),
deserializeString(proto.name),
if (proto.hasUniqId()) proto.uniqId.index else null,
isEnumEntry = proto.isEnumEntry,
isEnumSpecial = proto.isEnumSpecial,
isDefaultConstructor = proto.isDefaultConstructor,
isFakeOverride = proto.isFakeOverride,
isGetter = proto.isGetter,
isSetter = proto.isSetter
)
private val ByteArray.codedInputStream: org.jetbrains.kotlin.protobuf.CodedInputStream
get() {
@@ -295,7 +310,7 @@ class KonanIrModuleDeserializer(
}
fun deserializeIrFile(fileProto: KonanIr.IrFile, moduleDescriptor: ModuleDescriptor, deserializeAllDeclarations: Boolean): IrFile {
val fileEntry = NaiveSourceBasedFileEntryImpl(fileProto.fileEntry.name)
val fileEntry = NaiveSourceBasedFileEntryImpl(deserializeString(fileProto.fileEntry.name))
// TODO: we need to store "" in protobuf, I suppose. Or better yet, reuse fqname storage from metadata.
val fqName = if (fileProto.fqName == "<root>") FqName.ROOT else FqName(fileProto.fqName)
@@ -321,6 +336,7 @@ class KonanIrModuleDeserializer(
deserializedModuleDescriptor = moduleDescriptor
deserializedModuleProtoSymbolTables.put(moduleDescriptor, proto.symbolTable)
deserializedModuleProtoStringTables.put(moduleDescriptor, proto.stringTable)
deserializedModuleProtoTypeTables.put(moduleDescriptor, proto.typeTable)
val files = proto.fileList.map {
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.metadata.KonanIr
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) {
class DescriptorReferenceSerializer(val declarationTable: DeclarationTable, val serializeString: (String) -> KonanIr.String) {
// Not all exported descriptors are deserialized, some a synthesized anew during metadata deserialization.
// Those created descriptors can't carry the uniqIdIndex, since it is available only for deserialized descriptors.
@@ -73,9 +73,9 @@ class DescriptorReferenceSerializer(val declarationTable: DeclarationTable) {
uniqId?.let { declarationTable.descriptors.put(discoverableDescriptorsDeclaration.descriptor, it) }
val proto = KonanIr.DescriptorReference.newBuilder()
.setPackageFqName(packageFqName)
.setClassFqName(classFqName)
.setName(descriptor.name.toString())
.setPackageFqName(serializeString(packageFqName))
.setClassFqName(serializeString(classFqName))
.setName(serializeString(descriptor.name.toString()))
if (uniqId != null) proto.setUniqId(protoUniqId(uniqId))