FIR: Support (de)serialization of context receivers

This commit is contained in:
Denis.Zharkov
2022-03-24 13:45:53 +03:00
committed by teamcity
parent dfc736161a
commit 0ba5c528d0
3 changed files with 78 additions and 1 deletions
@@ -194,6 +194,8 @@ fun deserializeClassToSymbol(
} }
}) })
companionObjectSymbol = (declarations.firstOrNull { it is FirRegularClass && it.isCompanion } as FirRegularClass?)?.symbol companionObjectSymbol = (declarations.firstOrNull { it is FirRegularClass && it.isCompanion } as FirRegularClass?)?.symbol
contextReceivers.addAll(classDeserializer.createContextReceiversForClass(classProto))
}.also { }.also {
if (isSealed) { if (isSealed) {
val inheritors = classProto.sealedSubclassFqNameList.map { nameIndex -> val inheritors = classProto.sealedSubclassFqNameList.map { nameIndex ->
@@ -19,10 +19,11 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub
import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.toEffectiveVisibility import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.computeTypeAttributes import org.jetbrains.kotlin.fir.types.computeTypeAttributes
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef
@@ -420,11 +421,44 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
this.containerSource = c.containerSource this.containerSource = c.containerSource
this.initializer = c.constDeserializer.loadConstant(proto, symbol.callableId, c.nameResolver) this.initializer = c.constDeserializer.loadConstant(proto, symbol.callableId, c.nameResolver)
deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false) deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false)
contextReceivers.addAll(
when {
proto.contextReceiverTypeCount > 0 ->
proto.contextReceiverTypeList.map(::loadContextReceiverFromType)
proto.contextReceiverTypeIdCount > 0 ->
proto.contextReceiverTypeIdList.map(::loadContextReceiverFromTypeId)
else -> emptyList()
}
)
}.apply { }.apply {
versionRequirementsTable = c.versionRequirementTable versionRequirementsTable = c.versionRequirementTable
} }
} }
fun loadContextReceiverFromType(proto: ProtoBuf.Type): FirContextReceiver =
loadContextReceiverFromTypeRef(proto.toTypeRef(c))
fun loadContextReceiverFromTypeId(id: Int): FirContextReceiver = loadContextReceiverFromType(c.typeTable[id])
private fun loadContextReceiverFromTypeRef(typeRef: FirTypeRef): FirContextReceiver =
buildContextReceiver {
val type = typeRef.coneType
this.labelNameFromTypeRef = (type as? ConeLookupTagBasedType)?.lookupTag?.name
this.typeRef = typeRef
}
fun createContextReceiversForClass(
classProto: ProtoBuf.Class,
): List<FirContextReceiver> = when {
classProto.contextReceiverTypeCount > 0 ->
classProto.contextReceiverTypeList.map(::loadContextReceiverFromType)
classProto.contextReceiverTypeIdCount > 0 ->
classProto.contextReceiverTypeIdList.map(::loadContextReceiverFromTypeId)
else -> emptyList()
}
fun loadFunction( fun loadFunction(
proto: ProtoBuf.Function, proto: ProtoBuf.Function,
classProto: ProtoBuf.Class? = null, classProto: ProtoBuf.Class? = null,
@@ -485,6 +519,16 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) c.annotationDeserializer.loadFunctionAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false) deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false)
this.containerSource = c.containerSource this.containerSource = c.containerSource
contextReceivers.addAll(
when {
proto.contextReceiverTypeCount > 0 ->
proto.contextReceiverTypeList.map(::loadContextReceiverFromType)
proto.contextReceiverTypeIdCount > 0 ->
proto.contextReceiverTypeIdList.map(::loadContextReceiverFromTypeId)
else -> emptyList()
}
)
}.apply { }.apply {
versionRequirementsTable = c.versionRequirementTable versionRequirementsTable = c.versionRequirementTable
} }
@@ -561,6 +605,8 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable) c.annotationDeserializer.loadConstructorAnnotations(c.containerSource, proto, local.nameResolver, local.typeTable)
containerSource = c.containerSource containerSource = c.containerSource
deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false) deprecation = annotations.getDeprecationInfosFromAnnotations(c.session.languageVersionSettings.apiVersion, false)
contextReceivers.addAll(createContextReceiversForClass(classProto))
}.build().apply { }.build().apply {
containingClassForStaticMemberAttr = c.dispatchReceiver!!.lookupTag containingClassForStaticMemberAttr = c.dispatchReceiver!!.lookupTag
versionRequirementsTable = c.versionRequirementTable versionRequirementsTable = c.versionRequirementTable
@@ -189,6 +189,17 @@ class FirElementSerializer private constructor(
} }
} }
if (klass is FirRegularClass) {
for (contextReceiver in klass.contextReceivers) {
val typeRef = contextReceiver.typeRef
if (useTypeTable()) {
builder.addContextReceiverTypeId(typeId(typeRef))
} else {
builder.addContextReceiverType(typeProto(contextReceiver.typeRef))
}
}
}
if (versionRequirementTable == null) error("Version requirements must be serialized for classes: ${klass.render()}") if (versionRequirementTable == null) error("Version requirements must be serialized for classes: ${klass.render()}")
builder.addAllVersionRequirement(versionRequirementTable.serializeVersionRequirements(klass)) builder.addAllVersionRequirement(versionRequirementTable.serializeVersionRequirements(klass))
@@ -312,6 +323,15 @@ class FirElementSerializer private constructor(
builder.addTypeParameter(local.typeParameterProto(typeParameter)) builder.addTypeParameter(local.typeParameterProto(typeParameter))
} }
for (contextReceiver in property.contextReceivers) {
val typeRef = contextReceiver.typeRef
if (useTypeTable()) {
builder.addContextReceiverTypeId(typeId(typeRef))
} else {
builder.addContextReceiverType(typeProto(contextReceiver.typeRef))
}
}
val receiverTypeRef = property.receiverTypeRef val receiverTypeRef = property.receiverTypeRef
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
if (useTypeTable()) { if (useTypeTable()) {
@@ -386,6 +406,15 @@ class FirElementSerializer private constructor(
builder.addTypeParameter(local.typeParameterProto(typeParameter)) builder.addTypeParameter(local.typeParameterProto(typeParameter))
} }
for (contextReceiver in function.contextReceivers) {
val typeRef = contextReceiver.typeRef
if (useTypeTable()) {
builder.addContextReceiverTypeId(typeId(typeRef))
} else {
builder.addContextReceiverType(typeProto(contextReceiver.typeRef))
}
}
val receiverTypeRef = function.receiverTypeRef val receiverTypeRef = function.receiverTypeRef
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
if (useTypeTable()) { if (useTypeTable()) {