[K2] Fix annotation serialization for simple cases

#KT-57611
This commit is contained in:
Ivan Kylchik
2023-03-31 12:54:29 +02:00
committed by Space Team
parent 5cc6338fb9
commit 4a50bd9b16
23 changed files with 478 additions and 27 deletions
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.serialization.constant.ConstantValue import org.jetbrains.kotlin.fir.serialization.constant.ConstantValue
import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue import org.jetbrains.kotlin.fir.serialization.constant.toConstantValue
@@ -28,7 +29,9 @@ class FirAnnotationSerializer(private val session: FirSession, internal val stri
fun addArgument(argumentExpression: FirExpression, parameterName: Name) { fun addArgument(argumentExpression: FirExpression, parameterName: Name) {
val argument = ProtoBuf.Annotation.Argument.newBuilder() val argument = ProtoBuf.Annotation.Argument.newBuilder()
argument.nameId = stringTable.getStringIndex(parameterName.asString()) argument.nameId = stringTable.getStringIndex(parameterName.asString())
argument.setValue(valueProto(argumentExpression.toConstantValue(session) ?: return)) val constantValue = argumentExpression.toConstantValue(session)
?: error("Cannot convert expression ${argumentExpression.render()} to constant")
argument.setValue(valueProto(constantValue))
addArgument(argument) addArgument(argument)
} }
@@ -573,10 +573,6 @@ class FirElementSerializer private constructor(
builder.addAllVersionRequirement(serializeVersionRequirements(typeAlias)) builder.addAllVersionRequirement(serializeVersionRequirements(typeAlias))
} }
for (annotation in typeAlias.nonSourceAnnotations(session)) {
builder.addAnnotation(extension.annotationSerializer.serializeAnnotation(annotation))
}
extension.serializeTypeAlias(typeAlias, builder) extension.serializeTypeAlias(typeAlias, builder)
return builder return builder
@@ -24,10 +24,10 @@ import org.jetbrains.kotlin.serialization.deserialization.DYNAMIC_TYPE_DESERIALI
class FirKLibSerializerExtension( class FirKLibSerializerExtension(
override val session: FirSession, override val session: FirSession,
override val metadataVersion: BinaryVersion, override val metadataVersion: BinaryVersion,
constValueProvider: ConstValueProvider?, override val constValueProvider: ConstValueProvider?,
private val allowErrorTypes: Boolean, private val allowErrorTypes: Boolean,
private val exportKDoc: Boolean private val exportKDoc: Boolean
) : FirSerializerExtensionBase(KlibMetadataSerializerProtocol, constValueProvider) { ) : FirSerializerExtensionBase(KlibMetadataSerializerProtocol) {
override fun shouldUseTypeTable(): Boolean = true override fun shouldUseTypeTable(): Boolean = true
override fun serializeFlexibleType(type: ConeFlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) { override fun serializeFlexibleType(type: ConeFlexibleType, lowerProto: ProtoBuf.Type.Builder, upperProto: ProtoBuf.Type.Builder) {
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.fir.types.ConeErrorType import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeFlexibleType import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -24,6 +25,8 @@ abstract class FirSerializerExtension {
val annotationSerializer by lazy { FirAnnotationSerializer(session, stringTable) } val annotationSerializer by lazy { FirAnnotationSerializer(session, stringTable) }
protected abstract val constValueProvider: ConstValueProvider?
open fun shouldUseTypeTable(): Boolean = false open fun shouldUseTypeTable(): Boolean = false
open fun shouldUseNormalizedVisibility(): Boolean = false open fun shouldUseNormalizedVisibility(): Boolean = false
@@ -77,6 +80,10 @@ abstract class FirSerializerExtension {
} }
open fun serializeTypeAlias(typeAlias: FirTypeAlias, proto: ProtoBuf.TypeAlias.Builder) { open fun serializeTypeAlias(typeAlias: FirTypeAlias, proto: ProtoBuf.TypeAlias.Builder) {
for (annotation in typeAlias.nonSourceAnnotations(session)) {
val annotationWithConstants = constValueProvider?.getNewFirAnnotationWithConstantValues(typeAlias, annotation) ?: annotation
proto.addAnnotation(annotationSerializer.serializeAnnotation(annotationWithConstants))
}
} }
open fun serializeErrorType(type: ConeErrorType, builder: ProtoBuf.Type.Builder) { open fun serializeErrorType(type: ConeErrorType, builder: ProtoBuf.Type.Builder) {
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.fir.serialization.constant.buildValueProtoBufIfPropertyIsConst
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -18,7 +20,6 @@ import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
abstract class FirSerializerExtensionBase( abstract class FirSerializerExtensionBase(
val protocol: SerializerExtensionProtocol, val protocol: SerializerExtensionProtocol,
private val constValueProvider: ConstValueProvider?
) : FirSerializerExtension() { ) : FirSerializerExtension() {
final override val stringTable = FirElementAwareSerializableStringTable() final override val stringTable = FirElementAwareSerializableStringTable()
@@ -50,7 +51,7 @@ abstract class FirSerializerExtensionBase(
childSerializer: FirElementSerializer childSerializer: FirElementSerializer
) { ) {
function.serializeAnnotations(proto, protocol.functionAnnotation) function.serializeAnnotations(proto, protocol.functionAnnotation)
function.receiverParameter?.serializeAnnotations(proto, protocol.functionExtensionReceiverAnnotation) function.receiverParameter?.serializeAnnotations(proto, protocol.functionExtensionReceiverAnnotation, function)
} }
override fun serializeProperty( override fun serializeProperty(
@@ -72,13 +73,13 @@ abstract class FirSerializerExtensionBase(
destination += annotation destination += annotation
} }
regularPropertyAnnotations.serializeAnnotations(proto, protocol.propertyAnnotation) regularPropertyAnnotations.serializeAnnotations(proto, protocol.propertyAnnotation, property)
fieldPropertyAnnotations.serializeAnnotations(proto, protocol.propertyBackingFieldAnnotation) fieldPropertyAnnotations.serializeAnnotations(proto, protocol.propertyBackingFieldAnnotation, property)
delegatePropertyAnnotations.serializeAnnotations(proto, protocol.propertyDelegatedFieldAnnotation) delegatePropertyAnnotations.serializeAnnotations(proto, protocol.propertyDelegatedFieldAnnotation, property)
property.getter?.serializeAnnotations(proto, protocol.propertyGetterAnnotation) property.getter?.serializeAnnotations(proto, protocol.propertyGetterAnnotation)
property.setter?.serializeAnnotations(proto, protocol.propertySetterAnnotation) property.setter?.serializeAnnotations(proto, protocol.propertySetterAnnotation)
property.receiverParameter?.serializeAnnotations(proto, protocol.propertyExtensionReceiverAnnotation) property.receiverParameter?.serializeAnnotations(proto, protocol.propertyExtensionReceiverAnnotation, property)
constValueProvider?.buildValueProtoBufIfPropertyIsConst(property, annotationSerializer)?.let { constProtoBuf -> constValueProvider?.buildValueProtoBufIfPropertyIsConst(property, annotationSerializer)?.let { constProtoBuf ->
proto.setExtension(protocol.compileTimeValue, constProtoBuf) proto.setExtension(protocol.compileTimeValue, constProtoBuf)
@@ -94,7 +95,8 @@ abstract class FirSerializerExtensionBase(
} }
override fun serializeTypeAnnotations(annotations: List<FirAnnotation>, proto: ProtoBuf.Type.Builder) { override fun serializeTypeAnnotations(annotations: List<FirAnnotation>, proto: ProtoBuf.Type.Builder) {
annotations.serializeAnnotations(proto, protocol.typeAnnotation) // TODO support const extraction for type annotations
annotations.serializeAnnotations(proto, protocol.typeAnnotation, container = null)
} }
override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) {
@@ -111,9 +113,10 @@ abstract class FirSerializerExtensionBase(
> FirAnnotationContainer.serializeAnnotations( > FirAnnotationContainer.serializeAnnotations(
proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>, proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?, extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?,
container: FirAnnotationContainer? = this
) { ) {
if (extension == null) return if (extension == null) return
this.nonSourceAnnotations(session).serializeAnnotations(proto, extension) this.nonSourceAnnotations(session).serializeAnnotations(proto, extension, container)
} }
@Suppress("Reformat") @Suppress("Reformat")
@@ -123,10 +126,37 @@ abstract class FirSerializerExtensionBase(
> List<FirAnnotation>.serializeAnnotations( > List<FirAnnotation>.serializeAnnotations(
proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>, proto: GeneratedMessageLite.ExtendableBuilder<MessageType, BuilderType>,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?, extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Annotation>>?,
container: FirAnnotationContainer?,
) { ) {
if (extension == null) return if (extension == null) return
for (annotation in this) { for (annotation in this) {
proto.addExtensionOrNull(extension, annotationSerializer.serializeAnnotation(annotation)) val annotationWithConstants = when {
container == null -> null
container is FirPropertyAccessor ->
constValueProvider?.getNewFirAnnotationWithConstantValues(
container.propertySymbol.fir,
annotation,
container,
isGetter = container.isGetter
)
container is FirValueParameter ->
constValueProvider?.getNewFirAnnotationWithConstantValues(
container,
annotation,
)
extension == protocol.propertyExtensionReceiverAnnotation || extension == protocol.functionExtensionReceiverAnnotation ->
constValueProvider?.getNewFirAnnotationWithConstantValues(
container,
annotation,
(container as FirCallableDeclaration).receiverParameter!!,
)
else ->
constValueProvider?.getNewFirAnnotationWithConstantValues(
container,
annotation,
)
} ?: annotation
proto.addExtensionOrNull(extension, annotationSerializer.serializeAnnotation(annotationWithConstants))
} }
} }
@@ -5,8 +5,13 @@
package org.jetbrains.kotlin.fir.serialization.constant package org.jetbrains.kotlin.fir.serialization.constant
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.FirReceiverParameter
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirConstExpression import org.jetbrains.kotlin.fir.expressions.FirConstExpression
import org.jetbrains.kotlin.fir.serialization.FirAnnotationSerializer import org.jetbrains.kotlin.fir.serialization.FirAnnotationSerializer
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -16,17 +21,37 @@ abstract class ConstValueProvider {
abstract fun getConstantValueForProperty(firProperty: FirProperty): FirConstExpression<*>? abstract fun getConstantValueForProperty(firProperty: FirProperty): FirConstExpression<*>?
fun buildValueProtoBufIfPropertyIsConst( abstract fun getNewFirAnnotationWithConstantValues(
firProperty: FirProperty, annotationSerializer: FirAnnotationSerializer firAnnotationContainer: FirAnnotationContainer,
): ProtoBuf.Annotation.Argument.Value? { firAnnotation: FirAnnotation,
return getConstantValueForProperty(firProperty).toProtoBuf(annotationSerializer) ): FirAnnotation
}
private fun FirConstExpression<*>?.toProtoBuf( abstract fun getNewFirAnnotationWithConstantValues(
annotationSerializer: FirAnnotationSerializer firProperty: FirProperty,
): ProtoBuf.Annotation.Argument.Value? { firAnnotation: FirAnnotation,
firPropertyAccessor: FirPropertyAccessor,
isGetter: Boolean,
): FirAnnotation
abstract fun getNewFirAnnotationWithConstantValues(
firExtensionReceiverContainer: FirAnnotationContainer,
firAnnotation: FirAnnotation,
receiverParameter: FirReceiverParameter,
): FirAnnotation
abstract fun getNewFirAnnotationWithConstantValues(
valueParameter: FirValueParameter,
firAnnotation: FirAnnotation,
): FirAnnotation
fun FirConstExpression<*>?.toProtoBuf(annotationSerializer: FirAnnotationSerializer): ProtoBuf.Annotation.Argument.Value? {
val constantValue = this?.toConstantValue(session) ?: return null val constantValue = this?.toConstantValue(session) ?: return null
return annotationSerializer.valueProto(constantValue).build() return annotationSerializer.valueProto(constantValue).build()
} }
} }
fun ConstValueProvider.buildValueProtoBufIfPropertyIsConst(
firProperty: FirProperty, annotationSerializer: FirAnnotationSerializer
): ProtoBuf.Annotation.Argument.Value? {
return getConstantValueForProperty(firProperty).toProtoBuf(annotationSerializer)
}
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.backend.ConstValueProviderImpl
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.FirMetadataSource import org.jetbrains.kotlin.fir.backend.FirMetadataSource
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.firProvider import org.jetbrains.kotlin.fir.resolve.providers.firProvider
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
import org.jetbrains.kotlin.fir.serialization.* import org.jetbrains.kotlin.fir.serialization.*
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.ir.declarations.MetadataSource import org.jetbrains.kotlin.ir.declarations.MetadataSource
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
@@ -58,6 +60,7 @@ class FirJvmSerializerExtension(
override val metadataVersion: BinaryVersion, override val metadataVersion: BinaryVersion,
private val jvmDefaultMode: JvmDefaultMode, private val jvmDefaultMode: JvmDefaultMode,
override val stringTable: FirElementAwareStringTable, override val stringTable: FirElementAwareStringTable,
override val constValueProvider: ConstValueProvider?,
) : FirSerializerExtension() { ) : FirSerializerExtension() {
constructor( constructor(
@@ -73,7 +76,7 @@ class FirJvmSerializerExtension(
session, bindings, metadata, localDelegatedProperties, approximator, components.scopeSession, session, bindings, metadata, localDelegatedProperties, approximator, components.scopeSession,
state.globalSerializationBindings, state.useTypeTableInSerializer, state.moduleName, state.classBuilderMode, state.globalSerializationBindings, state.useTypeTableInSerializer, state.moduleName, state.classBuilderMode,
state.isParamAssertionsDisabled, state.unifiedNullChecks, state.metadataVersion, state.jvmDefaultMode, state.isParamAssertionsDisabled, state.unifiedNullChecks, state.metadataVersion, state.jvmDefaultMode,
FirJvmElementAwareStringTable(typeMapper, components), FirJvmElementAwareStringTable(typeMapper, components), ConstValueProviderImpl(components),
) )
override fun shouldUseTypeTable(): Boolean = useTypeTable override fun shouldUseTypeTable(): Boolean = useTypeTable
@@ -173,7 +176,8 @@ class FirJvmSerializerExtension(
override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) {
for (annotation in typeParameter.nonSourceAnnotations(session)) { for (annotation in typeParameter.nonSourceAnnotations(session)) {
proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation)) val annotationWithConstants = constValueProvider?.getNewFirAnnotationWithConstantValues(typeParameter, annotation) ?: annotation
proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotationWithConstants))
} }
} }
@@ -105,6 +105,7 @@ fun makeLocalFirMetadataSerializerForMetadataSource(
configuration.metadataVersion(session.languageVersionSettings.languageVersion), configuration.metadataVersion(session.languageVersionSettings.languageVersion),
session.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode), session.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode),
stringTable, stringTable,
constValueProvider = null
) )
return FirMetadataSerializer( return FirMetadataSerializer(
globalSerializationBindings, globalSerializationBindings,
@@ -7,15 +7,22 @@ package org.jetbrains.kotlin.fir.backend
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.builtins.UnsignedType
import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirProperty import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationArgumentMapping
import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.types.ConstantValueKind
class ConstValueProviderImpl( class ConstValueProviderImpl(
@@ -30,6 +37,108 @@ class ConstValueProviderImpl(
return irConst.toFirConst() return irConst.toFirConst()
} }
override fun getNewFirAnnotationWithConstantValues(
firAnnotationContainer: FirAnnotationContainer,
firAnnotation: FirAnnotation,
): FirAnnotation {
if (firAnnotation is FirErrorAnnotationCall) return firAnnotation
val irDeclaration = when (firAnnotationContainer) {
is FirClass -> components.classifierStorage.getCachedIrClass(firAnnotationContainer)
is FirEnumEntry -> components.classifierStorage.getCachedIrEnumEntry(firAnnotationContainer)
is FirTypeAlias -> components.classifierStorage.getCachedTypeAlias(firAnnotationContainer)
is FirTypeParameter -> components.classifierStorage.getCachedIrTypeParameter(firAnnotationContainer)
is FirScript -> components.declarationStorage.getCachedIrScript(firAnnotationContainer)
is FirConstructor -> components.declarationStorage.getCachedIrConstructor(firAnnotationContainer)
is FirFunction -> components.declarationStorage.getCachedIrFunction(firAnnotationContainer)
is FirProperty -> components.declarationStorage.getCachedIrProperty(firAnnotationContainer)
else -> error("Cannot extract IR declaration for ${firAnnotationContainer.render()}")
} ?: return firAnnotation
return buildNewFirAnnotationByCorrespondingIrAnnotation(irDeclaration, firAnnotationContainer, firAnnotation)
}
override fun getNewFirAnnotationWithConstantValues(
firProperty: FirProperty,
firAnnotation: FirAnnotation,
firPropertyAccessor: FirPropertyAccessor,
isGetter: Boolean,
): FirAnnotation {
if (firAnnotation is FirErrorAnnotationCall) return firAnnotation
val irProperty = components.declarationStorage.getCachedIrProperty(firProperty) ?: return firAnnotation
val irAccessor = (if (isGetter) irProperty.getter else irProperty.setter)
?: error("Cannot extract IR property accessor for ${firProperty.render()}")
return buildNewFirAnnotationByCorrespondingIrAnnotation(irAccessor, firPropertyAccessor, firAnnotation)
}
override fun getNewFirAnnotationWithConstantValues(
firExtensionReceiverContainer: FirAnnotationContainer,
firAnnotation: FirAnnotation,
receiverParameter: FirReceiverParameter
): FirAnnotation {
if (firAnnotation is FirErrorAnnotationCall) return firAnnotation
val extensionReceiver = when (firExtensionReceiverContainer) {
is FirFunction -> components.declarationStorage.getCachedIrFunction(firExtensionReceiverContainer)?.extensionReceiverParameter
is FirProperty -> components.declarationStorage.getCachedIrProperty(firExtensionReceiverContainer)?.getter?.extensionReceiverParameter
else -> error("Cannot extract IR extension receiver for ${firExtensionReceiverContainer::class}")
} ?: return firAnnotation
return buildNewFirAnnotationByCorrespondingIrAnnotation(extensionReceiver, receiverParameter, firAnnotation)
}
override fun getNewFirAnnotationWithConstantValues(
valueParameter: FirValueParameter,
firAnnotation: FirAnnotation,
): FirAnnotation {
if (firAnnotation is FirErrorAnnotationCall) return firAnnotation
val firFunction = valueParameter.containingFunctionSymbol.fir
val irFunction = components.declarationStorage.getCachedIrFunction(firFunction) ?: return firAnnotation
val irValueParameter = irFunction.valueParameters.single { it.name == valueParameter.name }
return buildNewFirAnnotationByCorrespondingIrAnnotation(irValueParameter, valueParameter, firAnnotation)
}
private fun buildNewFirAnnotationByCorrespondingIrAnnotation(
irDeclaration: IrDeclarationBase,
firAnnotationContainer: FirAnnotationContainer,
firAnnotation: FirAnnotation
): FirAnnotation {
assert(irDeclaration.annotations.size == firAnnotationContainer.annotations.size) {
"Number of annotations for IR and FIR declaration are not equal"
}
val annotationIndex = firAnnotationContainer.annotations.indexOf(firAnnotation)
val irArguments = irDeclaration.annotations[annotationIndex].getArgumentsWithIr()
val annotationArgsMapping = buildAnnotationArgumentMapping {
firAnnotation.argumentMapping.mapping.forEach { (name, firExpression) ->
if (firExpression is FirConstExpression<*>) {
mapping[name] = firExpression
return@forEach
}
val irExpression = irArguments.single { it.first.name == name }.second
// TODO recursion for annotations
mapping[name] = (irExpression as? IrConst<*>)?.toFirConst() ?: firExpression
}
}
return when (firAnnotation) {
is FirAnnotationCall -> buildAnnotationCall {
this.annotationTypeRef = firAnnotation.annotationTypeRef
this.calleeReference = firAnnotation.calleeReference
this.argumentMapping = annotationArgsMapping
}
else -> buildAnnotation {
this.annotationTypeRef = firAnnotation.annotationTypeRef
this.argumentMapping = annotationArgsMapping
}
}
}
private fun IrConst<*>.getConstantKind(): ConstantValueKind<*>? { private fun IrConst<*>.getConstantKind(): ConstantValueKind<*>? {
if (this.kind == IrConstKind.Null) return ConstantValueKind.Null if (this.kind == IrConstKind.Null) return ConstantValueKind.Null
@@ -28418,6 +28418,22 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -28418,6 +28418,22 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -0,0 +1,79 @@
// TARGET_BACKEND: JVM_IR
// TARGET_BACKEND: JS_IR
// TARGET_BACKEND: NATIVE
// MODULE: lib
// FILE: lib.kt
// Commented targets are not serializable
@Target(
/*1*/ AnnotationTarget.CLASS,
/*2*/ AnnotationTarget.ANNOTATION_CLASS,
/*3*/ AnnotationTarget.TYPE_PARAMETER,
/*4*/ AnnotationTarget.PROPERTY,
/*5*/ AnnotationTarget.FIELD,
/*6*/ // AnnotationTarget.LOCAL_VARIABLE,
/*7*/ AnnotationTarget.VALUE_PARAMETER,
/*8*/ AnnotationTarget.CONSTRUCTOR,
/*9*/ AnnotationTarget.FUNCTION,
/*10*/ AnnotationTarget.PROPERTY_GETTER,
/*11*/ AnnotationTarget.PROPERTY_SETTER,
/*12*/ AnnotationTarget.TYPE,
/*13*/ // AnnotationTarget.EXPRESSION, // can be applied only to source annotations
/*14*/ // AnnotationTarget.FILE,
/*15*/ AnnotationTarget.TYPEALIAS
)
@Retention(AnnotationRetention.BINARY)
annotation class BinaryAnnotation(val str: String)
// 1. CLASS
// 8. CONSTRUCTOR
@BinaryAnnotation("Str" + "ing")
class A @BinaryAnnotation("Str" + "ing") constructor(val i: Int) {
@BinaryAnnotation("Str" + "ing") constructor() : this(0)
}
// 2. ANNOTATION_CLASS
@BinaryAnnotation("Str" + "ing")
annotation class Anno
// 3. TYPE_PARAMETER
fun <@BinaryAnnotation("Str" + "ing") T, U> fooWithTypeParam(a: T, b: U) {}
// 4. PROPERTY
@BinaryAnnotation("Str" + "ing")
val prop: Int = 0
// 5. FIELD
enum class SomeEnum {
@BinaryAnnotation("Str" + "ing") A,
B;
}
// 7. VALUE_PARAMETER
fun @receiver:BinaryAnnotation("Str" + "ing") String.myExtension() { }
fun foo(@BinaryAnnotation("Str" + "ing") a: Int) { }
val @receiver:BinaryAnnotation("Str" + "ing") String.a: Int
get() = 0
// 9. FUNCTION
@BinaryAnnotation("Str" + "ing")
fun bar() {}
// 10. PROPERTY_GETTER
// 11. PROPERTY_SETTER
var b: Int
@BinaryAnnotation("Str" + "ing") get() = 0
@BinaryAnnotation("Str" + "ing") set(value) {}
// 15. TYPEALIAS
@BinaryAnnotation("Str" + "ing")
typealias C = Int
// MODULE: main
// FILE: main.kt
fun box(): String {
return "OK"
}
@@ -27236,6 +27236,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
}
} }
@Nested @Nested
@@ -28418,6 +28418,22 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -28418,6 +28418,22 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -22964,6 +22964,19 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
} }
} }
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Serialization extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
}
} }
@TestMetadata("compiler/testData/codegen/box/ir") @TestMetadata("compiler/testData/codegen/box/ir")
@@ -21058,6 +21058,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
}
} }
@Nested @Nested
@@ -21172,6 +21172,22 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -21172,6 +21172,22 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -21172,6 +21172,22 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -24362,6 +24362,26 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
@Tag("codegenK2")
@Tag("firCodegen")
@UseExtTestCaseGroupProvider()
@FirPipeline()
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -24127,6 +24127,25 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt"); runTest("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck/unsignedConst.kt");
} }
} }
@Nested
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
@Tag("codegen")
@Tag("k1Codegen")
@UseExtTestCaseGroupProvider()
public class Serialization {
@Test
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
}
@Test
@TestMetadata("annotationSerialization.kt")
public void testAnnotationSerialization() throws Exception {
runTest("compiler/testData/codegen/box/involvesIrInterpreter/serialization/annotationSerialization.kt");
}
}
} }
@Nested @Nested
@@ -18707,6 +18707,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/dumpIrAndCheck"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
} }
} }
@TestMetadata("compiler/testData/codegen/box/involvesIrInterpreter/serialization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Serialization extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInSerialization() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/involvesIrInterpreter/serialization"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
}
} }
@TestMetadata("compiler/testData/codegen/box/ir") @TestMetadata("compiler/testData/codegen/box/ir")