[FIR] Handle expect declarations in JVM backend

1. Do not generate bytecode for expect declarations

2. Serialize @OptionalExpectation annotations into .kotlin_module file

^KT-62931: Fixed
This commit is contained in:
vladislav.grechko
2024-02-08 18:01:11 +01:00
committed by Space Team
parent b74501ee93
commit d753a22fc6
24 changed files with 352 additions and 113 deletions
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.constant.ConstantValue
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
@@ -35,7 +33,7 @@ abstract class FirSerializerExtensionBase(
versionRequirementTable: MutableVersionRequirementTable,
childSerializer: FirElementSerializer
) {
klass.serializeAnnotations(proto, protocol.classAnnotation)
klass.serializeAnnotations(session, additionalMetadataProvider, annotationSerializer, proto, protocol.classAnnotation)
}
override fun serializeScript(
@@ -50,7 +48,7 @@ abstract class FirSerializerExtensionBase(
proto: ProtoBuf.Constructor.Builder,
childSerializer: FirElementSerializer
) {
constructor.serializeAnnotations(proto, protocol.constructorAnnotation)
constructor.serializeAnnotations(session, additionalMetadataProvider, annotationSerializer, proto, protocol.constructorAnnotation)
}
override fun serializeFunction(
@@ -59,8 +57,14 @@ abstract class FirSerializerExtensionBase(
versionRequirementTable: MutableVersionRequirementTable?,
childSerializer: FirElementSerializer
) {
function.serializeAnnotations(proto, protocol.functionAnnotation)
function.receiverParameter?.serializeAnnotations(proto, protocol.functionExtensionReceiverAnnotation)
function.serializeAnnotations(session, additionalMetadataProvider, annotationSerializer, proto, protocol.functionAnnotation)
function.receiverParameter?.serializeAnnotations(
session,
additionalMetadataProvider,
annotationSerializer,
proto,
protocol.functionExtensionReceiverAnnotation
)
}
override fun serializeProperty(
@@ -72,7 +76,7 @@ abstract class FirSerializerExtensionBase(
val fieldPropertyAnnotations = mutableListOf<FirAnnotation>()
val delegatePropertyAnnotations = mutableListOf<FirAnnotation>()
for (annotation in property.backingField?.allRequiredAnnotations(session).orEmpty()) {
for (annotation in property.backingField?.allRequiredAnnotations(session, additionalMetadataProvider).orEmpty()) {
val destination = when (annotation.useSiteTarget) {
AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD -> delegatePropertyAnnotations
else -> fieldPropertyAnnotations
@@ -80,13 +84,31 @@ abstract class FirSerializerExtensionBase(
destination += annotation
}
property.allRequiredAnnotations(session).serializeAnnotations(proto, protocol.propertyAnnotation)
property.allRequiredAnnotations(session, additionalMetadataProvider).serializeAnnotations(proto, protocol.propertyAnnotation)
fieldPropertyAnnotations.serializeAnnotations(proto, protocol.propertyBackingFieldAnnotation)
delegatePropertyAnnotations.serializeAnnotations(proto, protocol.propertyDelegatedFieldAnnotation)
property.getter?.serializeAnnotations(proto, protocol.propertyGetterAnnotation)
property.setter?.serializeAnnotations(proto, protocol.propertySetterAnnotation)
property.receiverParameter?.serializeAnnotations(proto, protocol.propertyExtensionReceiverAnnotation)
property.getter?.serializeAnnotations(
session,
additionalMetadataProvider,
annotationSerializer,
proto,
protocol.propertyGetterAnnotation
)
property.setter?.serializeAnnotations(
session,
additionalMetadataProvider,
annotationSerializer,
proto,
protocol.propertySetterAnnotation
)
property.receiverParameter?.serializeAnnotations(
session,
additionalMetadataProvider,
annotationSerializer,
proto,
protocol.propertyExtensionReceiverAnnotation
)
if (!Flags.HAS_CONSTANT.get(proto.flags)) return
property.initializer?.toConstantValue<ConstantValue<*>>(session, constValueProvider)?.let {
@@ -95,11 +117,11 @@ abstract class FirSerializerExtensionBase(
}
override fun serializeEnumEntry(enumEntry: FirEnumEntry, proto: ProtoBuf.EnumEntry.Builder) {
enumEntry.serializeAnnotations(proto, protocol.enumEntryAnnotation)
enumEntry.serializeAnnotations(session, additionalMetadataProvider, annotationSerializer, proto, protocol.enumEntryAnnotation)
}
override fun serializeValueParameter(parameter: FirValueParameter, proto: ProtoBuf.ValueParameter.Builder) {
parameter.serializeAnnotations(proto, protocol.parameterAnnotation)
parameter.serializeAnnotations(session, additionalMetadataProvider, annotationSerializer, proto, protocol.parameterAnnotation)
}
override fun serializeTypeAnnotations(annotations: List<FirAnnotation>, proto: ProtoBuf.Type.Builder) {
@@ -107,19 +129,13 @@ abstract class FirSerializerExtensionBase(
}
override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) {
typeParameter.serializeAnnotations(proto, protocol.typeParameterAnnotation)
}
@Suppress("Reformat")
private fun <
MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>,
BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
> FirAnnotationContainer.serializeAnnotations(
proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?
) {
if (extension == null) return
this.allRequiredAnnotations(session).serializeAnnotations(proto, extension)
typeParameter.serializeAnnotations(
session,
additionalMetadataProvider,
annotationSerializer,
proto,
protocol.typeParameterAnnotation
)
}
@Suppress("Reformat")
@@ -135,28 +151,4 @@ abstract class FirSerializerExtensionBase(
proto.addExtensionOrNull(extension, annotationSerializer.serializeAnnotation(annotation))
}
}
@Suppress("Reformat")
private fun <
MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>,
BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
Type
> GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>.addExtensionOrNull(
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<Type>>,
value: Type?
) {
if (value != null) {
addExtension(extension, value)
}
}
private fun FirAnnotationContainer.allRequiredAnnotations(session: FirSession): List<FirAnnotation> {
val nonSourceAnnotations = nonSourceAnnotations(session)
val additionalMetadataAnnotationsProvider = additionalMetadataProvider
return if (this is FirDeclaration && additionalMetadataAnnotationsProvider != null) {
nonSourceAnnotations + additionalMetadataAnnotationsProvider.findGeneratedAnnotationsFor(this)
} else {
nonSourceAnnotations
}
}
}
}
@@ -6,19 +6,24 @@
package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.nonSourceAnnotations
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.protobuf.GeneratedMessageLite
import org.jetbrains.kotlin.types.AbstractTypeApproximator
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
@@ -59,3 +64,56 @@ fun FirMemberDeclaration.isNotPrivateOrShouldBeSerialized(produceHeaderKlib: Boo
// Always keep private interfaces as they can be part of public type hierarchies.
|| (this as? FirClass)?.isInterface == true
}
fun <
MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>,
BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
> FirAnnotationContainer.serializeAnnotations(
session: FirSession,
additionalMetadataProvider: FirAdditionalMetadataProvider?,
annotationSerializer: FirAnnotationSerializer,
proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?,
) {
if (extension == null) return
allRequiredAnnotations(session, additionalMetadataProvider).serializeAnnotations(annotationSerializer, proto, extension)
}
fun FirAnnotationContainer.allRequiredAnnotations(
session: FirSession,
additionalMetadataProvider: FirAdditionalMetadataProvider?,
): List<FirAnnotation> {
val nonSourceAnnotations = nonSourceAnnotations(session)
return if (this is FirDeclaration && additionalMetadataProvider != null) {
nonSourceAnnotations + additionalMetadataProvider.findGeneratedAnnotationsFor(this)
} else {
nonSourceAnnotations
}
}
fun <
MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>,
BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
> List<FirAnnotation>.serializeAnnotations(
annotationSerializer: FirAnnotationSerializer,
proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?,
) {
if (extension == null) return
for (annotation in this) {
proto.addExtensionOrNull(extension, annotationSerializer.serializeAnnotation(annotation))
}
}
fun <
MessageType : GeneratedMessageLite.ExtendableMessage<MessageType>,
BuilderType : GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
Type,
> GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>.addExtensionOrNull(
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<Type>>,
value: Type?,
) {
if (value != null) {
addExtension(extension, value)
}
}