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 package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateAnonymousInitializer() { 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") { writeFile("PersistentIrAnonymousInitializer.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -33,4 +33,6 @@ internal fun PersistentIrGenerator.generateAnonymousInitializer() {
writeFile("carriers/AnonymousInitializerCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") { writeFile("carriers/AnonymousInitializerCarrier.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent.carriers") {
carriers("AnonymousInitializer", body)() carriers("AnonymousInitializer", body)()
}) })
addCarrierProtoMessage("AnonymousInitializer", body)
} }
@@ -6,13 +6,17 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateClass() { internal fun PersistentIrGenerator.generateClass() {
val visibilityField = Field("visibility", descriptorType("DescriptorVisibility")) val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
val thisReceiverField = Field("thisReceiver", irDeclaration("IrValueParameter") + "?") val thisReceiverField = Field(
val typeParametersField = Field("typeParameters", +"List<" + irDeclaration("IrTypeParameter") + ">") "thisReceiver",
val superTypesField = Field("superTypes", +"List<" + import("IrType", "org.jetbrains.kotlin.ir.types") + ">") IrValueParameter + "?",
val metadataField = Field("metadata", irDeclaration("MetadataSource") + "?") valueParameterProto,
val modalityField = Field("modality", descriptorType("Modality")) propSymbolType = IrValueParameterSymbol + "?",
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer) 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") { writeFile("PersistentIrClass.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -66,9 +70,9 @@ internal fun PersistentIrGenerator.generateClass() {
), ),
typeParametersField.toPersistentField(+"emptyList()"), typeParametersField.toPersistentField(+"emptyList()"),
superTypesField.toPersistentField(+"emptyList()"), superTypesField.toPersistentField(+"emptyList()"),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
modalityField.toPersistentField(+"modality"), modalityField.toPersistentField(+"modality"),
attributeOwnerIdField.toPersistentField(+"this"), +"override var attributeOwnerId: " + IrAttributeContainer + " = this",
), ),
id, id,
)() )()
@@ -78,12 +82,19 @@ internal fun PersistentIrGenerator.generateClass() {
carriers( carriers(
"Class", "Class",
thisReceiverField, thisReceiverField,
metadataField,
visibilityField, visibilityField,
modalityField, modalityField,
attributeOwnerIdField,
typeParametersField, typeParametersField,
superTypesField, superTypesField,
)() )()
}) })
addCarrierProtoMessage(
"Class",
thisReceiverField,
visibilityField,
modalityField,
typeParametersField,
superTypesField,
)
} }
@@ -6,14 +6,9 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateConstructor() { internal fun PersistentIrGenerator.generateConstructor() {
val returnTypeFieldField = Field("returnTypeField", IrType) val returnTypeFieldField = Field("returnTypeField", IrType, typeProto)
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">") val bodyField = Field("body", IrBody + "?", bodyProto)
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?") val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
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)
writeFile("PersistentIrConstructor.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") { writeFile("PersistentIrConstructor.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -42,7 +37,13 @@ internal fun PersistentIrGenerator.generateConstructor() {
+"override var returnType: IrType", +"override var returnType: IrType",
lines( lines(
+"get() = returnTypeField.let " + block( +"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( +"set(c) " + block(
+"returnTypeField = c" +"returnTypeField = c"
@@ -54,9 +55,9 @@ internal fun PersistentIrGenerator.generateConstructor() {
extensionReceiverParameterField.toPersistentField(+"null"), extensionReceiverParameterField.toPersistentField(+"null"),
valueParametersField.toPersistentField(+"emptyList()"), valueParametersField.toPersistentField(+"emptyList()"),
bodyField.toBody(), bodyField.toBody(),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
visibilityField.toPersistentField(+"visibility"), visibilityField.toPersistentField(+"visibility"),
descriptor(ClassConstructorDescriptor) descriptor(ClassConstructorDescriptor),
), ),
id, id,
)() )()
@@ -69,10 +70,20 @@ internal fun PersistentIrGenerator.generateConstructor() {
dispatchReceiverParameterField, dispatchReceiverParameterField,
extensionReceiverParameterField, extensionReceiverParameterField,
bodyField, bodyField,
metadataField,
visibilityField, visibilityField,
typeParametersField, typeParametersField,
valueParametersField, valueParametersField,
)() )()
}) })
addCarrierProtoMessage(
"Constructor",
returnTypeFieldField,
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
visibilityField,
typeParametersField,
valueParametersField,
)
} }
@@ -6,8 +6,15 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateEnumEntry() { internal fun PersistentIrGenerator.generateEnumEntry() {
val correspondingClassField = Field("correspondingClass", IrClass + "?") val correspondingClassField = Field(
val initializerExpressionField = Field("initializerExpression", IrExpressionBody + "?") "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") { writeFile("PersistentIrEnumEntry.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -27,7 +34,7 @@ internal fun PersistentIrGenerator.generateEnumEntry() {
descriptor(ClassDescriptor), descriptor(ClassDescriptor),
correspondingClassField.toPersistentField(+"null"), correspondingClassField.toPersistentField(+"null"),
initializerExpressionField.toBody() initializerExpressionField.toBody(),
), ),
id, id,
)() )()
@@ -40,4 +47,6 @@ internal fun PersistentIrGenerator.generateEnumEntry() {
initializerExpressionField, initializerExpressionField,
)() )()
}) })
addCarrierProtoMessage("EnumEntry", correspondingClassField, initializerExpressionField)
} }
@@ -43,4 +43,6 @@ internal fun PersistentIrGenerator.generateErrorDeclaration() {
"ErrorDeclaration", "ErrorDeclaration",
)() )()
}) })
addCarrierProtoMessage("ErrorDeclaration")
} }
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateField() { internal fun PersistentIrGenerator.generateField() {
val initializerField = Field("initializer", IrExpressionBody + "?") val initializerField = Field("initializer", IrExpressionBody + "?", expressionBodyProto)
val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?") val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?", propertySymbolProto)
val metadataField = Field("metadata", MetadataSource + "?") val typeField = Field("type", IrType, typeProto)
val typeField = Field("type", IrType)
writeFile("PersistentIrField.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") { writeFile("PersistentIrField.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -34,7 +33,7 @@ internal fun PersistentIrGenerator.generateField() {
descriptor(descriptorType("PropertyDescriptor")), descriptor(descriptorType("PropertyDescriptor")),
initializerField.toBody(), initializerField.toBody(),
correspondingPropertySymbolField.toPersistentField(+"null"), correspondingPropertySymbolField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
typeField.toPersistentField(+"type"), typeField.toPersistentField(+"type"),
), ),
id, id,
@@ -47,7 +46,8 @@ internal fun PersistentIrGenerator.generateField() {
typeField, typeField,
initializerField, initializerField,
correspondingPropertySymbolField, correspondingPropertySymbolField,
metadataField,
)() )()
}) })
addCarrierProtoMessage("Field", typeField, initializerField, correspondingPropertySymbolField)
} }
@@ -7,17 +7,11 @@ package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateFunction() { internal fun PersistentIrGenerator.generateFunction() {
val returnTypeFieldField = Field("returnTypeField", IrType) val returnTypeFieldField = Field("returnTypeField", IrType, typeProto)
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">") val bodyField = Field("body", IrBody + "?", bodyProto)
val dispatchReceiverParameterField = Field("dispatchReceiverParameter", IrValueParameter + "?") val visibilityField = Field("visibility", DescriptorVisibility, visibilityProto)
val extensionReceiverParameterField = Field("extensionReceiverParameter", IrValueParameter + "?") val overriddenSymbolsField = Field("overriddenSymbols", +"List<" + IrSimpleFunctionSymbol + ">", simpleFunctionSymbolListProto)
val valueParametersField = Field("valueParameters", +"List<" + IrValueParameter + ">") val correspondingPropertySymbolField = Field("correspondingPropertySymbol", IrPropertySymbol + "?", propertySymbolProto)
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 + "?")
writeFile("PersistentIrFunctionCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") { writeFile("PersistentIrFunctionCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -65,13 +59,10 @@ internal fun PersistentIrGenerator.generateFunction() {
extensionReceiverParameterField.toPersistentField(+"null"), extensionReceiverParameterField.toPersistentField(+"null"),
valueParametersField.toPersistentField(+"emptyList()"), valueParametersField.toPersistentField(+"emptyList()"),
bodyField.toBody(), bodyField.toBody(),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
visibilityField.toPersistentField(+"visibility"), visibilityField.toPersistentField(+"visibility"),
overriddenSymbolsField.toPersistentField(+"emptyList()"), overriddenSymbolsField.toPersistentField(+"emptyList()"),
lines( +"override var attributeOwnerId: " + IrAttributeContainer + " = this",
+"@Suppress(\"LeakingThis\")",
attributeOwnerIdField.toPersistentField(+"this"),
),
correspondingPropertySymbolField.toPersistentField(+"null"), correspondingPropertySymbolField.toPersistentField(+"null"),
), ),
id, id,
@@ -85,13 +76,24 @@ internal fun PersistentIrGenerator.generateFunction() {
dispatchReceiverParameterField, dispatchReceiverParameterField,
extensionReceiverParameterField, extensionReceiverParameterField,
bodyField, bodyField,
metadataField,
visibilityField, visibilityField,
typeParametersField, typeParametersField,
valueParametersField, valueParametersField,
correspondingPropertySymbolField, correspondingPropertySymbolField,
overriddenSymbolsField, overriddenSymbolsField,
attributeOwnerIdField,
)() )()
}) })
addCarrierProtoMessage(
"Function",
returnTypeFieldField,
dispatchReceiverParameterField,
extensionReceiverParameterField,
bodyField,
visibilityField,
typeParametersField,
valueParametersField,
correspondingPropertySymbolField,
overriddenSymbolsField,
)
} }
@@ -6,11 +6,25 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateLocalDelegatedProperty() { internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
val typeField = Field("type", IrType) val typeField = Field("type", IrType, typeProto)
val delegateField = Field("delegate", irDeclaration("IrVariable"), lateinit = true) val delegateField = Field("delegate", IrVariable, variableProto, lateinit = true)
val getterField = Field("getter", irDeclaration("IrSimpleFunction"), lateinit = true) val getterField = Field(
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?") "getter",
val metadataField = Field("metadata", MetadataSource + "?") 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") { writeFile("PersistentIrLocalDelegatedProperty.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -35,7 +49,7 @@ internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
delegateField.toPersistentField(+"null"), delegateField.toPersistentField(+"null"),
getterField.toPersistentField(+"null"), getterField.toPersistentField(+"null"),
setterField.toPersistentField(+"null"), setterField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
), ),
id, id,
)() )()
@@ -48,7 +62,14 @@ internal fun PersistentIrGenerator.generateLocalDelegatedProperty() {
delegateField, delegateField,
getterField, getterField,
setterField, setterField,
metadataField,
)() )()
}) })
addCarrierProtoMessage(
"LocalDelegatedProperty",
typeField,
delegateField,
getterField,
setterField,
)
} }
@@ -19,5 +19,9 @@ fun main() {
generateTypeAlias() generateTypeAlias()
generateTypeParameter() generateTypeParameter()
generateValueParameter() generateValueParameter()
updateKotlinIrProto()
generateCarrierDeserializer()
generateCarrierSerializer()
} }
} }
@@ -6,8 +6,8 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
import java.io.File import java.io.File
import java.lang.IllegalStateException
import java.lang.StringBuilder import java.lang.StringBuilder
import java.time.Year
internal interface R { internal interface R {
fun text(t: String): R fun text(t: String): R
@@ -19,12 +19,42 @@ internal interface R {
internal typealias E = R.() -> 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 { internal object PersistentIrGenerator {
private val protoPackage = "org.jetbrains.kotlin.backend.common.serialization.proto"
val carrierPackage = "org.jetbrains.kotlin.ir.declarations.persistent.carriers"
// Imports // 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 ClassDescriptor: E = descriptorType("ClassDescriptor")
val DeclarationDescriptor: E = descriptorType("DeclarationDescriptor") val DeclarationDescriptor: E = descriptorType("DeclarationDescriptor")
val ClassConstructorDescriptor: E = descriptorType("ClassConstructorDescriptor") val ClassConstructorDescriptor: E = descriptorType("ClassConstructorDescriptor")
@@ -35,10 +65,14 @@ internal object PersistentIrGenerator {
val IrDeclarationParent = irDeclaration("IrDeclarationParent") val IrDeclarationParent = irDeclaration("IrDeclarationParent")
val IrAnonymousInitializer = irDeclaration("IrAnonymousInitializer") val IrAnonymousInitializer = irDeclaration("IrAnonymousInitializer")
val IrClass = irDeclaration("IrClass") val IrClass = irDeclaration("IrClass")
val IrFunction = irDeclaration("IrFunction")
val IrSimpleFunction = irDeclaration("IrSimpleFunction")
val IrField = irDeclaration("IrField")
val IrTypeParameter = irDeclaration("IrTypeParameter") val IrTypeParameter = irDeclaration("IrTypeParameter")
val IrValueParameter = irDeclaration("IrValueParameter") val IrValueParameter = irDeclaration("IrValueParameter")
val MetadataSource = irDeclaration("MetadataSource") val MetadataSource = irDeclaration("MetadataSource")
val IrAttributeContainer = irDeclaration("IrAttributeContainer") val IrAttributeContainer = irDeclaration("IrAttributeContainer")
val IrVariable = irDeclaration("IrVariable")
val IrConstructorCall = irExpression("IrConstructorCall") val IrConstructorCall = irExpression("IrConstructorCall")
val IrBody = irExpression("IrBody") val IrBody = irExpression("IrBody")
@@ -55,7 +89,13 @@ internal object PersistentIrGenerator {
val IrType = import("IrType", "org.jetbrains.kotlin.ir.types") val IrType = import("IrType", "org.jetbrains.kotlin.ir.types")
val IrSymbol = irSymbol("IrSymbol")
val IrPropertySymbol = irSymbol("IrPropertySymbol") 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 // Constructor parameters
@@ -78,7 +118,10 @@ internal object PersistentIrGenerator {
val source = +"override val source: " + descriptorType("SourceElement") + " = SourceElement.NO_SOURCE" val source = +"override val source: " + descriptorType("SourceElement") + " = SourceElement.NO_SOURCE"
val returnType = +"returnType: " + IrType val returnType = +"returnType: " + IrType
val isPrimary = +"override val isPrimary: Boolean" 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" val irFactory = +"override val factory: PersistentIrFactory"
@@ -86,6 +129,63 @@ internal object PersistentIrGenerator {
+"symbol.bind(this)" +"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 // Fields
val lastModified = +"override var lastModified: Int = factory.stageController.currentStage" val lastModified = +"override var lastModified: Int = factory.stageController.currentStage"
val loweredUpTo = +"override var loweredUpTo: Int = factory.stageController.currentStage" val loweredUpTo = +"override var loweredUpTo: Int = factory.stageController.currentStage"
@@ -109,10 +209,214 @@ internal object PersistentIrGenerator {
annotationsField, annotationsField,
) )
fun Field.toPersistentField(initializer: E, modifier: String = "override") = val typeParametersField = Field(
persistentField(name, type, initializer, lateinit, modifier, notEq = notEq) "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 // Helpers
@@ -130,11 +434,24 @@ internal object PersistentIrGenerator {
modifier: String = "override", modifier: String = "override",
isBody: Boolean = false, isBody: Boolean = false,
notEq: String = "!==", notEq: String = "!==",
): E = lines( symbolType: E? = null,
+"override var ${name}Field: " + type + "${if (lateinit) "?" else ""} = " + initializer, declarationToSymbol: E = id,
id, symbolToDeclaration: E = id,
+"$modifier var $name: " + type, ): E {
lines( 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 ""}", +"get() = getCarrier().${name}Field${if (lateinit) "!!" else ""}",
+"set(v) " + block( +"set(v) " + block(
+"if (${if (lateinit) "getCarrier().${name}Field" else name} $notEq v) " + block( +"if (${if (lateinit) "getCarrier().${name}Field" else name} $notEq v) " + block(
@@ -148,7 +465,9 @@ internal object PersistentIrGenerator {
) )
) )
).indent() ).indent()
)
return lines(*result.toTypedArray())
}
fun body(bodyType: E, lateinit: Boolean = false, fieldName: String = "body"): E = fun body(bodyType: E, lateinit: Boolean = false, fieldName: String = "body"): E =
persistentField(fieldName, bodyType, initializer = +"null", lateinit, isBody = true) persistentField(fieldName, bodyType, initializer = +"null", lateinit, isBody = true)
@@ -162,16 +481,24 @@ internal object PersistentIrGenerator {
fun carriers(name: String, vararg fields: Field): E = lines( fun carriers(name: String, vararg fields: Field): E = lines(
id, id,
+"internal interface ${name}Carrier : DeclarationCarrier" + block( +"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, id,
+"override fun clone(): ${name}Carrier " + block( +"override fun clone(): ${name}Carrier " + block(
+"return ${name}CarrierImpl(", +"return ${name}CarrierImpl(",
arrayOf( arrayOf(
+"lastModified", +"lastModified",
+"parentField", +"parentSymbolField",
+"originField", +"originField",
+"annotationsField", +"annotationsField",
*(fields.map { +"${it.name}Field" }.toTypedArray()) *(fields.map { +"${it.name}${if (it.propSymbolType != null) "Symbol" else ""}Field" }.toTypedArray())
).join(separator = ",\n").indent(), ).join(separator = ",\n").indent(),
+")", +")",
) )
@@ -180,12 +507,33 @@ internal object PersistentIrGenerator {
+"internal class ${name}CarrierImpl(", +"internal class ${name}CarrierImpl(",
arrayOf( arrayOf(
+"override val lastModified: Int", +"override val lastModified: Int",
+"override val parentField: " + IrDeclarationParent + "?", +"override val parentSymbolField: " + IrSymbol + "?",
+"override val originField: " + IrDeclarationOrigin, +"override val originField: " + IrDeclarationOrigin,
+"override val annotationsField: List<" + IrConstructorCall + ">", +"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(), ).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, id,
) )
@@ -197,7 +545,8 @@ internal object PersistentIrGenerator {
return block(*(fn.flatMap { listOf(id, it) }.toTypedArray())) 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") 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) } operator fun String.unaryPlus(): E = { text(this@unaryPlus) }
val id: E get() = { this }
fun E?.safe(): E = this ?: id fun E?.safe(): E = this ?: id
fun Array<out E>.join(prefix: String = "", separator: String = "", suffix: String = ""): E = 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) { fun writeFile(path: String, content: String) {
File(prefix + path).writeText(content) 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 package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateProperty() { internal fun PersistentIrGenerator.generateProperty() {
val backingFieldField = Field("backingField", irDeclaration("IrField") + "?") val backingFieldField = Field(
val getterField = Field("getter", irDeclaration("IrSimpleFunction") + "?") "backingField",
val setterField = Field("setter", irDeclaration("IrSimpleFunction") + "?") IrField + "?",
val metadataField = Field("metadata", MetadataSource + "?") fieldProto,
val attributeOwnerIdField = Field("attributeOwnerId", IrAttributeContainer) 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") { writeFile("PersistentIrPropertyCommon.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -36,10 +55,10 @@ internal fun PersistentIrGenerator.generateProperty() {
backingFieldField.toPersistentField(+"null"), backingFieldField.toPersistentField(+"null"),
getterField.toPersistentField(+"null"), getterField.toPersistentField(+"null"),
setterField.toPersistentField(+"null"), setterField.toPersistentField(+"null"),
metadataField.toPersistentField(+"null"), +"override var metadata: " + MetadataSource + "? = null",
lines( lines(
+"@Suppress(\"LeakingThis\")", +"@Suppress(\"LeakingThis\")",
attributeOwnerIdField.toPersistentField(+"this"), +"override var attributeOwnerId: " + IrAttributeContainer + " = this",
), ),
), ),
id, id,
@@ -52,8 +71,13 @@ internal fun PersistentIrGenerator.generateProperty() {
backingFieldField, backingFieldField,
getterField, getterField,
setterField, setterField,
metadataField,
attributeOwnerIdField,
)() )()
}) })
addCarrierProtoMessage(
"Property",
backingFieldField,
getterField,
setterField,
)
} }
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateTypeAlias() { internal fun PersistentIrGenerator.generateTypeAlias() {
val typeParametersField = Field("typeParameters", +"List<" + IrTypeParameter + ">") val expandedTypeField = Field("expandedType", IrType, typeProto)
val expandedTypeField = Field("expandedType", IrType)
writeFile("PersistentIrTypeAlias.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") { writeFile("PersistentIrTypeAlias.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -43,4 +42,6 @@ internal fun PersistentIrGenerator.generateTypeAlias() {
expandedTypeField, expandedTypeField,
)() )()
}) })
addCarrierProtoMessage("TypeAlias", typeParametersField, expandedTypeField)
} }
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.ir.persistentIrGenerator package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateTypeParameter() { 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") { writeFile("PersistentIrTypeParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -39,4 +39,6 @@ internal fun PersistentIrGenerator.generateTypeParameter() {
superTypesField, superTypesField,
)() )()
}) })
addCarrierProtoMessage("TypeParameter", superTypesField)
} }
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.ir.persistentIrGenerator
internal fun PersistentIrGenerator.generateValueParameter() { internal fun PersistentIrGenerator.generateValueParameter() {
val defaultValueField = Field("defaultValue", IrExpressionBody + "?") val defaultValueField = Field("defaultValue", IrExpressionBody + "?", expressionBodyProto)
val typeField = Field("type", IrType) val typeField = Field("type", IrType, typeProto)
val varargElementTypeField = Field("varargElementType", IrType + "?") val varargElementTypeField = Field("varargElementType", IrType + "?", optionalTypeProto)
writeFile("PersistentIrValueParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") { writeFile("PersistentIrValueParameter.kt", renderFile("org.jetbrains.kotlin.ir.declarations.persistent") {
lines( lines(
@@ -49,4 +49,6 @@ internal fun PersistentIrGenerator.generateValueParameter() {
varargElementTypeField, varargElementTypeField,
)() )()
}) })
addCarrierProtoMessage("ValueParameter", defaultValueField, typeField, varargElementTypeField)
} }