JS PIR: update the generator

- Use symbols in carriers
- .proto messages for carriers
- carrier serializer/derserializer
This commit is contained in:
Anton Bannykh
2021-04-02 17:44:35 +03:00
committed by TeamCityServer
parent c224dd4cb1
commit 1f0d83b420
14 changed files with 580 additions and 94 deletions
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateAnonymousInitializer() {
val body = Field("body", IrBlockBody, lateinit = true)
val body = Field("body", IrBlockBody, blockBodyProto, lateinit = true)
writeFile("PersistentIrAnonymousInitializer.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -33,4 +33,6 @@ internal fun PersistentIrGenerator.generateAnonymousInitializer() {
writeFile("carriers/AnonymousInitializerCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
carriers("AnonymousInitializer", body)()
})
addCarrierProtoMessage("AnonymousInitializer", body)
}
@@ -6,13 +6,17 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateClass() {
val visibilityField = Field("visibility", descriptorType("DescriptorVisibility"))
val thisReceiverField = Field("thisReceiver", irDeclaration("IrValueParameter") + "?")
val typeParametersField = Field("typeParameters", +"List<" + irDeclaration("IrTypeParameter") + ">")
val superTypesField = Field("superTypes", +"List<" + import("IrType", "org.jetbrains.kotlin.ir.types") + ">")
val metadataField = Field("metadata", irDeclaration("MetadataSource") + "?")
val modalityField = Field("modality", descriptorType("Modality"))
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
val thisReceiverField = Field(
"thisReceiver",
IrValueParameter + "?",
valueParameterProto,
propSymbolType = IrValueParameterSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
val superTypesField = Field("superTypes", +"List<" + import("IrType", "org.jetbrains.kotlin.ir.types") + ">", superTypeListProto)
val modalityField = Field("modality", descriptorType("Modality"), modalityProto)
writeFile("PersistentIrClass.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -66,9 +70,9 @@ internal fun PersistentIrGenerator.generateClass() {
),
typeParametersField.toPersistentField(+"emptyList()"),
superTypesField.toPersistentField(+"emptyList()"),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
modalityField.toPersistentField(+"modality"),
attributeOwnerIdField.toPersistentField(+"this"),
+"override var attributeOwnerId: " + IrAttributeContainer + " = this",
),
id,
)()
@@ -78,12 +82,19 @@ internal fun PersistentIrGenerator.generateClass() {
carriers(
"Class",
thisReceiverField,
metadataField,
visibilityField,
modalityField,
attributeOwnerIdField,
typeParametersField,
superTypesField,
)()
})
addCarrierProtoMessage(
"Class",
thisReceiverField,
visibilityField,
modalityField,
typeParametersField,
superTypesField,
)
}
@@ -6,14 +6,9 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateConstructor() {
val returnTypeFieldField = Field("returnTypeField", IrType)
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?")
val extensionReceiverParameterField = Field("extensionReceiverParameter", IrValueParameter + "?")
val valueParametersField = Field("valueParameters", +"List<" + IrValueParameter + ">")
val bodyField = Field("body", IrBody + "?")
val metadataField = Field("metadata", MetadataSource + "?")
val visibilityField = Field("visibility", DescriptorVisibility)
val returnTypeFieldField = Field("returnTypeField", IrType, typeProto)
val bodyField = Field("body", IrBody + "?", bodyProto)
val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
writeFile("PersistentIrConstructor.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -42,7 +37,13 @@ internal fun PersistentIrGenerator.generateConstructor() {
+"override var returnType: IrType",
lines(
+"get() = returnTypeField.let " + block(
+"if (it !== " + import("IrUninitializedType", "org.jetbrains.kotlin.ir.types.impl") + ") it else throw " + import("ReturnTypeIsNotInitializedException", "org.jetbrains.kotlin.ir.types.impl") + "(this)"
+"if (it !== " + import(
"IrUninitializedType",
"org.jetbrains.kotlin.ir.types.impl"
) + ") it else throw " + import(
"ReturnTypeIsNotInitializedException",
"org.jetbrains.kotlin.ir.types.impl"
) + "(this)"
),
+"set(c) " + block(
+"returnTypeField = c"
@@ -54,9 +55,9 @@ internal fun PersistentIrGenerator.generateConstructor() {
extensionReceiverParameterField.toPersistentField(+"null"),
valueParametersField.toPersistentField(+"emptyList()"),
bodyField.toBody(),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
visibilityField.toPersistentField(+"visibility"),
descriptor(ClassConstructorDescriptor)
descriptor(ClassConstructorDescriptor),
),
id,
)()
@@ -69,10 +70,20 @@ internal fun PersistentIrGenerator.generateConstructor() {
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
metadataField,
visibilityField,
typeParametersField,
valueParametersField,
)()
})
addCarrierProtoMessage(
"Constructor",
returnTypeFieldField,
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
visibilityField,
typeParametersField,
valueParametersField,
)
}
@@ -6,8 +6,15 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateEnumEntry() {
val correspondingClassField = Field("correspondingClass", IrClass + "?")
val initializerExpressionField = Field("initializerExpression", IrExpressionBody + "?")
val correspondingClassField = Field(
"correspondingClass",
IrClass + "?",
classProto,
propSymbolType = IrClassSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
val initializerExpressionField = Field("initializerExpression", IrExpressionBody + "?", expressionBodyProto)
writeFile("PersistentIrEnumEntry.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -27,7 +34,7 @@ internal fun PersistentIrGenerator.generateEnumEntry() {
descriptor(ClassDescriptor),
correspondingClassField.toPersistentField(+"null"),
initializerExpressionField.toBody()
initializerExpressionField.toBody(),
),
id,
)()
@@ -40,4 +47,6 @@ internal fun PersistentIrGenerator.generateEnumEntry() {
initializerExpressionField,
)()
})
addCarrierProtoMessage("EnumEntry", correspondingClassField, initializerExpressionField)
}
@@ -43,4 +43,6 @@ internal fun PersistentIrGenerator.generateErrorDeclaration() {
"ErrorDeclaration",
)()
})
addCarrierProtoMessage("ErrorDeclaration")
}
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateField() {
val initializerField = Field("initializer", IrExpressionBody + "?")
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?")
val metadataField = Field("metadata", MetadataSource + "?")
val typeField = Field("type", IrType)
val initializerField = Field("initializer", IrExpressionBody + "?", expressionBodyProto)
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?", propertySymbolProto)
val typeField = Field("type", IrType, typeProto)
writeFile("PersistentIrField.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -34,7 +33,7 @@ internal fun PersistentIrGenerator.generateField() {
descriptor(descriptorType("PropertyDescriptor")),
initializerField.toBody(),
correspondingPropertySymbolField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
typeField.toPersistentField(+"type"),
),
id,
@@ -47,7 +46,8 @@ internal fun PersistentIrGenerator.generateField() {
typeField,
initializerField,
correspondingPropertySymbolField,
metadataField,
)()
})
addCarrierProtoMessage("Field", typeField, initializerField, correspondingPropertySymbolField)
}
@@ -7,17 +7,11 @@ package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateFunction() {
val returnTypeFieldField = Field("returnTypeField", IrType)
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?")
val extensionReceiverParameterField = Field("extensionReceiverParameter", IrValueParameter + "?")
val valueParametersField = Field("valueParameters", +"List<" + IrValueParameter + ">")
val bodyField = Field("body", IrBody + "?")
val metadataField = Field("metadata", MetadataSource + "?")
val visibilityField = Field("visibility", DescriptorVisibility)
val overriddenSymbolsField = Field("overriddenSymbols", +"List<" + irSymbol("IrSimpleFunctionSymbol") + ">")
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?")
val returnTypeFieldField = Field("returnTypeField", IrType, typeProto)
val bodyField = Field("body", IrBody + "?", bodyProto)
val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
val overriddenSymbolsField = Field("overriddenSymbols", +"List<" + IrSimpleFunctionSymbol + ">", simpleFunctionSymbolListProto)
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?", propertySymbolProto)
writeFile("PersistentIrFunctionCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -65,13 +59,10 @@ internal fun PersistentIrGenerator.generateFunction() {
extensionReceiverParameterField.toPersistentField(+"null"),
valueParametersField.toPersistentField(+"emptyList()"),
bodyField.toBody(),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
visibilityField.toPersistentField(+"visibility"),
overriddenSymbolsField.toPersistentField(+"emptyList()"),
lines(
+"@Suppress(\"LeakingThis\")",
attributeOwnerIdField.toPersistentField(+"this"),
),
+"override var attributeOwnerId: " + IrAttributeContainer + " = this",
correspondingPropertySymbolField.toPersistentField(+"null"),
),
id,
@@ -85,13 +76,24 @@ internal fun PersistentIrGenerator.generateFunction() {
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
metadataField,
visibilityField,
typeParametersField,
valueParametersField,
correspondingPropertySymbolField,
overriddenSymbolsField,
attributeOwnerIdField,
)()
})
addCarrierProtoMessage(
"Function",
returnTypeFieldField,
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
visibilityField,
typeParametersField,
valueParametersField,
correspondingPropertySymbolField,
overriddenSymbolsField,
)
}
@@ -6,11 +6,25 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
val typeField = Field("type", IrType)
val delegateField = Field("delegate", irDeclaration("IrVariable"), lateinit = true)
val getterField = Field("getter", irDeclaration("IrSimpleFunction"), lateinit = true)
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?")
val metadataField = Field("metadata", MetadataSource + "?")
val typeField = Field("type", IrType, typeProto)
val delegateField = Field("delegate", IrVariable, variableProto, lateinit = true)
val getterField = Field(
"getter",
IrSimpleFunction,
simpleFunctionProto,
lateinit = true,
propSymbolType = IrSimpleFunctionSymbol,
symbolToDeclaration = +".owner",
declarationToSymbol = +".symbol"
)
val setterField = Field(
"setter",
IrSimpleFunction + "?",
simpleFunctionProto,
propSymbolType = IrSimpleFunctionSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
writeFile("PersistentIrLocalDelegatedProperty.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -35,7 +49,7 @@ internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
delegateField.toPersistentField(+"null"),
getterField.toPersistentField(+"null"),
setterField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
),
id,
)()
@@ -48,7 +62,14 @@ internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
delegateField,
getterField,
setterField,
metadataField,
)()
})
addCarrierProtoMessage(
"LocalDelegatedProperty",
typeField,
delegateField,
getterField,
setterField,
)
}
@@ -19,5 +19,9 @@ fun main() {
generateTypeAlias()
generateTypeParameter()
generateValueParameter()
updateKotlinIrProto()
generateCarrierDeserializer()
generateCarrierSerializer()
}
}
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
import java.io.File
import java.lang.IllegalStateException
import java.lang.StringBuilder
import java.time.Year
internal interface R {
fun text(t: String): R
@@ -19,12 +19,42 @@ internal interface R {
internal typealias E = R.() -> R
internal class Field(val name: String, val type: E, val lateinit: Boolean = false, val notEq: String = "!==")
internal val id: E get() = { this }
internal enum class FieldKind {
REQUIRED, OPTIONAL, REPEATED
}
internal class Proto(
val protoPrefix: String?, // null if flag, proto type if not
val entityName: String, // what to deserialize
val protoType: E, // what type ProtoBuf generates
val irType: E, // what Ir class this maps to
val fieldKind: FieldKind = FieldKind.OPTIONAL,
)
internal class Field(
val name: String,
val propType: E,
val proto: Proto? = null,
val lateinit: Boolean = false,
val notEq: String = "!==",
val propSymbolType: E? = null,
val symbolToDeclaration: E = id,
val declarationToSymbol: E = id,
val storeInCarrierImpl: Boolean = false,
)
internal object PersistentIrGenerator {
private val protoPackage = "org.jetbrains.kotlin.backend.common.serialization.proto"
val carrierPackage = "org.jetbrains.kotlin.ir.declarations.persistent.carriers"
// Imports
val codedInputStream: E = import("codedInputStream", "org.jetbrains.kotlin.backend.common.serialization")
val ExtensionRegistryLite: E = import("ExtensionRegistryLite", "org.jetbrains.kotlin.protobuf")
val ClassDescriptor: E = descriptorType("ClassDescriptor")
val DeclarationDescriptor: E = descriptorType("DeclarationDescriptor")
val ClassConstructorDescriptor: E = descriptorType("ClassConstructorDescriptor")
@@ -35,10 +65,14 @@ internal object PersistentIrGenerator {
val IrDeclarationParent = irDeclaration("IrDeclarationParent")
val IrAnonymousInitializer = irDeclaration("IrAnonymousInitializer")
val IrClass = irDeclaration("IrClass")
val IrFunction = irDeclaration("IrFunction")
val IrSimpleFunction = irDeclaration("IrSimpleFunction")
val IrField = irDeclaration("IrField")
val IrTypeParameter = irDeclaration("IrTypeParameter")
val IrValueParameter = irDeclaration("IrValueParameter")
val MetadataSource = irDeclaration("MetadataSource")
val IrAttributeContainer = irDeclaration("IrAttributeContainer")
val IrVariable = irDeclaration("IrVariable")
val IrConstructorCall = irExpression("IrConstructorCall")
val IrBody = irExpression("IrBody")
@@ -55,7 +89,13 @@ internal object PersistentIrGenerator {
val IrType = import("IrType", "org.jetbrains.kotlin.ir.types")
val IrSymbol = irSymbol("IrSymbol")
val IrPropertySymbol = irSymbol("IrPropertySymbol")
val IrSimpleFunctionSymbol = irSymbol("IrSimpleFunctionSymbol")
val IrFunctionSymbol = irSymbol("IrFunctionSymbol")
val IrFieldSymbol = irSymbol("IrFieldSymbol")
val IrValueParameterSymbol = irSymbol("IrValueParameterSymbol")
val IrTypeParameterSymbol = irSymbol("IrTypeParameterSymbol")
// Constructor parameters
@@ -78,7 +118,10 @@ internal object PersistentIrGenerator {
val source = +"override val source: " + descriptorType("SourceElement") + " = SourceElement.NO_SOURCE"
val returnType = +"returnType: " + IrType
val isPrimary = +"override val isPrimary: Boolean"
val containerSource = +"override val containerSource: " + import("DeserializedContainerSource", "org.jetbrains.kotlin.serialization.deserialization.descriptors") + "?"
val containerSource = +"override val containerSource: " + import(
"DeserializedContainerSource",
"org.jetbrains.kotlin.serialization.deserialization.descriptors"
) + "?"
val irFactory = +"override val factory: PersistentIrFactory"
@@ -86,6 +129,63 @@ internal object PersistentIrGenerator {
+"symbol.bind(this)"
)
// Proto types
val protoValueParameterType = import("IrValueParameter", protoPackage, "ProtoIrValueParameter")
val protoTypeParameterType = import("IrTypeParameter", protoPackage, "ProtoIrTypeParameter")
val protoVariable = import("IrVariable", protoPackage, "ProtoIrVariable")
val protoIrConstructorCall = import("IrConstructorCall", protoPackage, "ProtoIrConstructorCall")
val bodyProto = Proto("int32", "body", +"Int", IrBody)
val blockBodyProto = Proto("int32", "blockBody", +"Int", IrBlockBody)
val expressionBodyProto = Proto("int32", "expressionBody", +"Int", IrExpressionBody)
val valueParameterProto = Proto("int64", "valueParameter", +"Long", IrValueParameterSymbol)
val valueParameterListProto = Proto("int64", "valueParameter", +"Long", IrValueParameterSymbol, fieldKind = FieldKind.REPEATED)
val typeParameterListProto = Proto("int64", "typeParameter", +"Long", IrTypeParameterSymbol, fieldKind = FieldKind.REPEATED)
val superTypeListProto = Proto("int32", "superType", +"Int", IrType, fieldKind = FieldKind.REPEATED)
val typeProto = Proto("int32", "type", +"Int", IrType, fieldKind = FieldKind.REQUIRED)
val optionalTypeProto = Proto("int32", "type", +"Int", IrType, fieldKind = FieldKind.OPTIONAL)
val variableProto = Proto("IrVariable", "variable", protoVariable, IrVariable)
val classProto = Proto("int64", "class", +"Long", IrClassSymbol)
val propertySymbolProto = Proto("int64", "propertySymbol", +"Long", IrPropertySymbol)
val simpleFunctionProto = Proto("int64", "simpleFunction", +"Long", IrSimpleFunctionSymbol)
val simpleFunctionSymbolListProto =
Proto("int64", "simpleFunctionSymbol", +"Long", IrSimpleFunctionSymbol, fieldKind = FieldKind.REPEATED)
val fieldProto = Proto("int64", "field", +"Long", IrFieldSymbol)
val visibilityProto = Proto(null, "visibility", +"Long", DescriptorVisibility)
val modalityProto = Proto(null, "modality", +"Long", descriptorType("Modality"))
val isExternalClassProto = Proto(null, "isExternalClass", +"Long", +"Boolean")
val isExternalFieldProto = Proto(null, "isExternalField", +"Long", +"Boolean")
val isExternalFunctionProto = Proto(null, "isExternalFunction", +"Long", +"Boolean")
val isExternalPropertyProto = Proto(null, "isExternalProperty", +"Long", +"Boolean")
private val allProto = listOf(
bodyProto,
blockBodyProto,
expressionBodyProto,
valueParameterProto,
valueParameterListProto,
typeParameterListProto,
superTypeListProto,
typeProto,
optionalTypeProto,
classProto,
propertySymbolProto,
simpleFunctionProto,
simpleFunctionSymbolListProto,
fieldProto,
variableProto,
visibilityProto,
modalityProto,
isExternalClassProto,
isExternalFieldProto,
isExternalFunctionProto,
isExternalPropertyProto,
)
// Fields
val lastModified = +"override var lastModified: Int = factory.stageController.currentStage"
val loweredUpTo = +"override var loweredUpTo: Int = factory.stageController.currentStage"
@@ -109,10 +209,214 @@ internal object PersistentIrGenerator {
annotationsField,
)
fun Field.toPersistentField(initializer: E, modifier: String = "override") =
persistentField(name, type, initializer, lateinit, modifier, notEq = notEq)
val typeParametersField = Field(
"typeParameters",
+"List<" + IrTypeParameter + ">",
typeParameterListProto,
propSymbolType = +"List<" + IrTypeParameterSymbol + ">",
symbolToDeclaration = +".map { it.owner }",
declarationToSymbol = +".map { it.symbol }",
storeInCarrierImpl = true,
)
fun Field.toBody() = body(type, lateinit, name)
val valueParametersField = Field(
"valueParameters",
+"List<" + IrValueParameter + ">",
valueParameterListProto,
propSymbolType = +"List<" + IrValueParameterSymbol + ">",
symbolToDeclaration = +".map { it.owner }",
declarationToSymbol = +".map { it.symbol }",
storeInCarrierImpl = true,
)
val dispatchReceiverParameterField = Field(
"dispatchReceiverParameter",
IrValueParameter + "?",
valueParameterProto,
propSymbolType = IrValueParameterSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
val extensionReceiverParameterField = Field(
"extensionReceiverParameter",
IrValueParameter + "?",
valueParameterProto,
propSymbolType = IrValueParameterSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
fun Field.toPersistentField(initializer: E, modifier: String = "override") =
persistentField(
name,
propType,
initializer,
lateinit,
modifier,
notEq = notEq,
symbolType = propSymbolType,
declarationToSymbol = declarationToSymbol,
symbolToDeclaration = symbolToDeclaration,
)
fun Field.toBody() = body(propType, lateinit, name)
val protoMessages = mutableListOf<String>()
fun addCarrierProtoMessage(carrierName: String, vararg fields: Field) {
val protoFields = mutableListOf(
"required int32 lastModified",
"optional int64 parentSymbol",
"optional int32 origin",
"repeated IrConstructorCall annotation"
)
protoFields += fields.mapNotNull { f ->
f.proto?.protoPrefix?.let { p ->
val modifier = f.proto.fieldKind.toString().toLowerCase()
"$modifier $p ${f.name}"
}
}
val sb = StringBuilder("message Pir${carrierName}Carrier {\n")
protoFields.forEachIndexed { i, f ->
sb.append(" $f = ${i + 1}")
sb.append(";\n")
}
if (fields.any { it.proto != null && it.proto.protoPrefix == null }) {
sb.append(" optional int64 flags = ${protoFields.size + 1} [default = 0];\n")
}
sb.append("}\n")
protoMessages += sb.toString()
addDeserializerMessage(carrierName, *fields)
addSerializerMessage(carrierName, *fields)
}
val deserializerMethods = mutableListOf<E>().also { list ->
list += +"abstract fun deserializeParentSymbol(proto: Long): " + IrSymbol
list += +"abstract fun deserializeOrigin(proto: Int): " + IrDeclarationOrigin
list += +"abstract fun deserializeAnnotation(proto: " + protoIrConstructorCall + "): " + IrConstructorCall
val seenEntities = mutableSetOf<String>()
allProto.forEach { p ->
if (p.entityName !in seenEntities) {
seenEntities += p.entityName
list += +"abstract fun deserialize${p.entityName.capitalize()}(proto: " + p.protoType + "): " + p.irType
}
}
}
fun addDeserializerMessage(carrierName: String, vararg fields: Field) {
val argumentType = import("Pir${carrierName}Carrier", protoPackage)
val returnType = import("${carrierName}Carrier", carrierPackage)
val carrierImpl = import("${carrierName}CarrierImpl", carrierPackage)
deserializerMethods += lines(
+"fun deserialize${carrierName}Carrier(bytes: ByteArray): " + returnType + " {",
lines(
+"val proto = " + argumentType + ".parseFrom(bytes." + codedInputStream + ", " + ExtensionRegistryLite + ".newInstance())",
+"return " + carrierImpl + "(",
arrayOf(
+"proto.lastModified",
+"if (proto.hasParentSymbol()) deserializeParentSymbol(proto.parentSymbol) else null",
+"deserializeOrigin(proto.origin)",
+"proto.annotationList.map { deserializeAnnotation(it) }",
*fields.map { f ->
if (f.proto == null) {
+"null"
} else {
val deserialize = "deserialize${f.proto.entityName.capitalize()}"
when {
f.proto.fieldKind == FieldKind.REPEATED ->
+"proto.${f.name}List.map { $deserialize(it) }"
f.proto.protoPrefix != null && f.proto.fieldKind == FieldKind.OPTIONAL ->
+"if (proto.has${f.name.capitalize()}()) $deserialize(proto.${f.name}) else null"
f.proto.protoPrefix == null ->
+"$deserialize(proto.flags)"
else ->
+"$deserialize(proto.${f.name})"
}
}
}.toTypedArray()
).join(separator = ",\n").indent(),
+")",
).indent(),
+"}",
)
}
val serializerMethods = mutableListOf<E>().also { list ->
list += +"abstract fun serializeParentSymbol(value: " + IrSymbol + "): Long"
list += +"abstract fun serializeOrigin(value: " + IrDeclarationOrigin + "): Int"
list += +"abstract fun serializeAnnotation(value: " + IrConstructorCall + "): " + protoIrConstructorCall
val seenEntities = mutableSetOf<String>()
allProto.forEach { p ->
if (p.entityName !in seenEntities) {
seenEntities += p.entityName
list += +"abstract fun serialize${p.entityName.capitalize()}(value: " + p.irType + "): " + p.protoType
}
}
}
fun addSerializerMessage(carrierName: String, vararg fields: Field) {
val argumentType = import("${carrierName}Carrier", carrierPackage)
val returnType = import("Pir${carrierName}Carrier", protoPackage)
var flagsHandled = false
serializerMethods += lines(
+"fun serialize${carrierName}Carrier(carrier: " + argumentType + "): ByteArray {",
lines(
+"val proto = " + returnType + ".newBuilder()",
+"proto.setLastModified(carrier.lastModified)",
+"carrier.parentSymbolField?.let { proto.setParentSymbol(serializeParentSymbol(it)) }",
+"proto.setOrigin(serializeOrigin(carrier.originField))",
+"proto.addAllAnnotation(carrier.annotationsField.map { serializeAnnotation(it) })",
*(fields.mapNotNull { f ->
f.proto?.let { p ->
if (p.protoPrefix != null) {
val action = "proto." + (if (p.fieldKind == FieldKind.REPEATED) "addAll" else "set") + f.name.capitalize()
val serializationFun = "serialize${f.proto.entityName.capitalize()}"
val argument = "carrier.${f.name}${if (f.propSymbolType != null) "Symbol" else ""}Field"
when {
p.fieldKind == FieldKind.OPTIONAL ->
+"$argument?.let { $action($serializationFun(it)) }"
p.fieldKind == FieldKind.REPEATED ->
+"$action($argument.map { $serializationFun(it) })"
else ->
+"$action($serializationFun($argument))"
}
} else {
// It's a flag
if (!flagsHandled) {
flagsHandled = true
val flags = fields.filter { it.proto?.protoPrefix == null }
val calls = flags.map { f -> "serialize${f.proto!!.entityName.capitalize()}(carrier.${f.name}Field)" }
+"proto.setFlags(${calls.joinToString(separator = " or ")})"
} else null
}
}
}).toTypedArray(),
+"return proto.build().toByteArray()",
).indent(),
+"}",
)
}
// Helpers
@@ -130,11 +434,24 @@ internal object PersistentIrGenerator {
modifier: String = "override",
isBody: Boolean = false,
notEq: String = "!==",
): E = lines(
+"override var ${name}Field: " + type + "${if (lateinit) "?" else ""} = " + initializer,
id,
+"$modifier var $name: " + type,
lines(
symbolType: E? = null,
declarationToSymbol: E = id,
symbolToDeclaration: E = id,
): E {
val result = mutableListOf(+"override var ${name}Field: " + type + "${if (lateinit) "?" else ""} = " + initializer, id)
if (symbolType != null) {
result += +"override var ${name}SymbolField: " + symbolType + if (lateinit) "?" else ""
result += lines(
+"get() = ${name}Field" + (if (lateinit) "?" else "") + declarationToSymbol,
+"set(v) " + block(
+"${name}Field = v" + (if (lateinit) "?" else "") + symbolToDeclaration
)
).indent()
result += id
}
result += +"$modifier var $name: " + type
result += lines(
+"get() = getCarrier().${name}Field${if (lateinit) "!!" else ""}",
+"set(v) " + block(
+"if (${if (lateinit) "getCarrier().${name}Field" else name} $notEq v) " + block(
@@ -148,7 +465,9 @@ internal object PersistentIrGenerator {
)
)
).indent()
)
return lines(*result.toTypedArray())
}
fun body(bodyType: E, lateinit: Boolean = false, fieldName: String = "body"): E =
persistentField(fieldName, bodyType, initializer = +"null", lateinit, isBody = true)
@@ -162,16 +481,24 @@ internal object PersistentIrGenerator {
fun carriers(name: String, vararg fields: Field): E = lines(
id,
+"internal interface ${name}Carrier : DeclarationCarrier" + block(
*(fields.map { +"val ${it.name}Field: " + it.type + if (it.lateinit) "?" else "" }.toTypedArray()),
*(fields.flatMap {
var result = listOf(+"val ${it.name}Field: " + it.propType + if (it.lateinit) "?" else "")
if (it.propSymbolType != null) {
result += +"val ${it.name}SymbolField: " + it.propSymbolType + if (it.lateinit) "?" else ""
}
result
}.toTypedArray()),
id,
+"override fun clone(): ${name}Carrier " + block(
+"return ${name}CarrierImpl(",
arrayOf(
+"lastModified",
+"parentField",
+"parentSymbolField",
+"originField",
+"annotationsField",
*(fields.map { +"${it.name}Field" }.toTypedArray())
*(fields.map { +"${it.name}${if (it.propSymbolType != null) "Symbol" else ""}Field" }.toTypedArray())
).join(separator = ",\n").indent(),
+")",
)
@@ -180,12 +507,33 @@ internal object PersistentIrGenerator {
+"internal class ${name}CarrierImpl(",
arrayOf(
+"override val lastModified: Int",
+"override val parentField: " + IrDeclarationParent + "?",
+"override val parentSymbolField: " + IrSymbol + "?",
+"override val originField: " + IrDeclarationOrigin,
+"override val annotationsField: List<" + IrConstructorCall + ">",
*(fields.map { +"override val ${it.name}Field: " + it.type + if (it.lateinit) "?" else "" }.toTypedArray()),
*(fields.map {
if (it.propSymbolType != null) {
+"override val ${it.name}SymbolField: " + it.propSymbolType + if (it.lateinit) "?" else ""
} else {
+"override val ${it.name}Field: " + it.propType + if (it.lateinit) "?" else ""
}
}.toTypedArray()),
).join(separator = ",\n").indent(),
+") : ${name}Carrier",
+") : ${name}Carrier" + if (fields.all { it.propSymbolType == null }) id else + " " + blockSpaced(
*(fields.mapNotNull {
it.propSymbolType?.let { _ ->
if (it.storeInCarrierImpl) {
+"override val ${it.name}Field: " + it.propType + " by lazy { ${it.name}SymbolField" + it.symbolToDeclaration + " }"
} else {
lines(
+"override val ${it.name}Field: " + it.propType + if (it.lateinit) "?" else "",
lines(
+"get() = ${it.name}SymbolField" + (if (it.lateinit) "?" else "") + it.symbolToDeclaration,
).indent()
)
}
}
}).toTypedArray()
),
id,
)
@@ -197,7 +545,8 @@ internal object PersistentIrGenerator {
return block(*(fn.flatMap { listOf(id, it) }.toTypedArray()))
}
fun import(name: String, pkg: String): E = { import("$pkg.$name").text(name) }
fun import(name: String, pkg: String, alias: String = name): E =
{ import("$pkg.$name${if (alias != name) " as $alias" else ""}").text(alias) }
fun descriptorType(name: String): E = import(name, "org.jetbrains.kotlin.descriptors")
@@ -215,8 +564,6 @@ internal object PersistentIrGenerator {
operator fun String.unaryPlus(): E = { text(this@unaryPlus) }
val id: E get() = { this }
fun E?.safe(): E = this ?: id
fun Array<out E>.join(prefix: String = "", separator: String = "", suffix: String = ""): E =
@@ -313,4 +660,52 @@ internal object PersistentIrGenerator {
fun writeFile(path: String, content: String) {
File(prefix + path).writeText(content)
}
fun updateKotlinIrProto() {
val file = File("compiler/ir/serialization.common/src/KotlinIr.proto")
if (!file.exists()) throw IllegalStateException("KotlinIr.proto file not found!")
val lines = file.readText().lines()
val start = lines.indexOf("// PIR GENERATOR START")
if (start < 0) throw IllegalStateException("Couldn't find the '// PIR GENERATOR START' line. Don't know where to write generated messages.")
val end = lines.indexOf("// PIR GENERATOR END")
if (end < 0) throw IllegalStateException("Couldn't find the '// PIR GENERATOR END' line. Don't know where to write generated messages.")
val sb = StringBuilder(lines.subList(0, start + 1).joinToString(separator = "\n"))
for (m in protoMessages) {
sb.append("\n").append(m)
}
sb.append("\n").append(lines.subList(end, lines.size).joinToString(separator = "\n"))
file.writeText(sb.toString())
}
fun generateCarrierDeserializer() {
writeFile("../../serialization/IrCarrierDeserializer.kt", renderFile("org.jetbrains.kotlin.ir.serialization") {
lines(
id,
+"internal abstract class IrCarrierDeserializer " + blockSpaced(
*deserializerMethods.toTypedArray()
),
id,
)()
})
}
fun generateCarrierSerializer() {
writeFile("../../serialization/IrCarrierSerializer.kt", renderFile("org.jetbrains.kotlin.ir.serialization") {
lines(
id,
+"internal abstract class IrCarrierSerializer " + blockSpaced(
*serializerMethods.toTypedArray()
),
id,
)()
})
}
}
@@ -6,11 +6,30 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateProperty() {
val backingFieldField = Field("backingField", irDeclaration("IrField") + "?")
val getterField = Field("getter", irDeclaration("IrSimpleFunction") + "?")
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?")
val metadataField = Field("metadata", MetadataSource + "?")
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer)
val backingFieldField = Field(
"backingField",
IrField + "?",
fieldProto,
propSymbolType = IrFieldSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
val getterField = Field(
"getter",
IrSimpleFunction + "?",
simpleFunctionProto,
propSymbolType = IrSimpleFunctionSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
val setterField = Field(
"setter",
IrSimpleFunction + "?",
simpleFunctionProto,
propSymbolType = IrSimpleFunctionSymbol + "?",
symbolToDeclaration = +"?.owner",
declarationToSymbol = +"?.symbol"
)
writeFile("PersistentIrPropertyCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -36,10 +55,10 @@ internal fun PersistentIrGenerator.generateProperty() {
backingFieldField.toPersistentField(+"null"),
getterField.toPersistentField(+"null"),
setterField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"),
+"override var metadata: " + MetadataSource + "? = null",
lines(
+"@Suppress(\"LeakingThis\")",
attributeOwnerIdField.toPersistentField(+"this"),
+"override var attributeOwnerId: " + IrAttributeContainer + " = this",
),
),
id,
@@ -52,8 +71,13 @@ internal fun PersistentIrGenerator.generateProperty() {
backingFieldField,
getterField,
setterField,
metadataField,
attributeOwnerIdField,
)()
})
addCarrierProtoMessage(
"Property",
backingFieldField,
getterField,
setterField,
)
}
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateTypeAlias() {
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">")
val expandedTypeField = Field("expandedType", IrType)
val expandedTypeField = Field("expandedType", IrType, typeProto)
writeFile("PersistentIrTypeAlias.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -43,4 +42,6 @@ internal fun PersistentIrGenerator.generateTypeAlias() {
expandedTypeField,
)()
})
addCarrierProtoMessage("TypeAlias", typeParametersField, expandedTypeField)
}
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateTypeParameter() {
val superTypesField = Field("superTypes", +"List<" + IrType + ">")
val superTypesField = Field("superTypes", +"List<" + IrType + ">", superTypeListProto)
writeFile("PersistentIrTypeParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -39,4 +39,6 @@ internal fun PersistentIrGenerator.generateTypeParameter() {
superTypesField,
)()
})
addCarrierProtoMessage("TypeParameter", superTypesField)
}
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateValueParameter() {
val defaultValueField = Field("defaultValue", IrExpressionBody + "?")
val typeField = Field("type", IrType)
val varargElementTypeField = Field("varargElementType", IrType + "?")
val defaultValueField = Field("defaultValue", IrExpressionBody + "?", expressionBodyProto)
val typeField = Field("type", IrType, typeProto)
val varargElementTypeField = Field("varargElementType", IrType + "?", optionalTypeProto)
writeFile("PersistentIrValueParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines(
@@ -49,4 +49,6 @@ internal fun PersistentIrGenerator.generateValueParameter() {
varargElementTypeField,
)()
})
addCarrierProtoMessage("ValueParameter", defaultValueField, typeField, varargElementTypeField)
}