From ec7522c675640fbd23fb9f29ac524eae08208faf Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 21 Apr 2020 18:42:57 +0300 Subject: [PATCH] FIR serializer: introduce nonSourceAnnotations --- .../fir/serialization/FirAnnotationUtils.kt | 44 +++++++++++++++++++ .../fir/serialization/FirElementSerializer.kt | 23 +++++----- .../backend/jvm/FirJvmSerializerExtension.kt | 3 +- 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirAnnotationUtils.kt diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirAnnotationUtils.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirAnnotationUtils.kt new file mode 100644 index 00000000000..d427c2c94df --- /dev/null +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirAnnotationUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.serialization + +import org.jetbrains.kotlin.fir.FirAnnotationContainer +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.Name + +private fun FirAnnotationCall.toAnnotationLookupTag(): ConeClassLikeLookupTag = + ((annotationTypeRef as FirResolvedTypeRef).type as ConeClassLikeType).lookupTag + +internal fun FirAnnotationCall.toAnnotationClassId(): ClassId = + toAnnotationLookupTag().classId + +internal fun FirAnnotationCall.toAnnotationClass(session: FirSession): FirRegularClass? = + toAnnotationLookupTag().toSymbol(session)?.fir as? FirRegularClass + +fun FirAnnotationContainer.nonSourceAnnotations(session: FirSession): List = + annotations.filter { annotation -> + val firAnnotationClass = annotation.toAnnotationClass(session) + firAnnotationClass != null && firAnnotationClass.annotations.none { meta -> + val firMetaAnnotationClassId = meta.toAnnotationClassId() + firMetaAnnotationClassId.asString() == "kotlin/annotation/Retention" && + // TODO: this is temporary solution, we need something better + (meta.argumentList.arguments.singleOrNull() as? FirQualifiedAccessExpression)?.let { + val callableSymbol = (it.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirCallableSymbol<*> + callableSymbol?.callableId?.callableName + } == Name.identifier("SOURCE") + } + } + diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index 6d795cda45f..9b754c45412 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -52,7 +52,7 @@ class FirElementSerializer private constructor( private val containingDeclaration: FirDeclaration?, private val typeParameters: Interner, private val extension: FirSerializerExtension, - val typeTable: MutableTypeTable, + private val typeTable: MutableTypeTable, private val versionRequirementTable: MutableVersionRequirementTable?, private val serializeTypeTableToFunction: Boolean, ) { @@ -90,7 +90,7 @@ class FirElementSerializer private constructor( val regularClass = klass as? FirRegularClass val modality = regularClass?.modality ?: Modality.FINAL val flags = Flags.getClassFlags( - klass.annotations.isNotEmpty(), + klass.nonSourceAnnotations(session).isNotEmpty(), ProtoEnumFlags.visibility(regularClass?.let { normalizeVisibility(it) } ?: Visibilities.LOCAL), ProtoEnumFlags.modality(modality), ProtoEnumFlags.classKind(klass.classKind, regularClass?.isCompanion == true), @@ -201,7 +201,7 @@ class FirElementSerializer private constructor( //val compileTimeConstant = property.compileTimeInitializer val hasConstant = false // TODO: compileTimeConstant != null && compileTimeConstant !is NullValue - val hasAnnotations = property.annotations.isNotEmpty() + val hasAnnotations = property.nonSourceAnnotations(session).isNotEmpty() // TODO: hasAnnotations(descriptor) || hasAnnotations(descriptor.backingField) || hasAnnotations(descriptor.delegateField) val modality = property.modality!! @@ -230,7 +230,7 @@ class FirElementSerializer private constructor( } if (setter !is FirDefaultPropertyAccessor || - setter.annotations.isNotEmpty() || + setter.nonSourceAnnotations(session).isNotEmpty() || setter.visibility != property.visibility ) { val setterLocal = local.createChildSerializer(setter) @@ -299,7 +299,7 @@ class FirElementSerializer private constructor( val local = createChildSerializer(function) val flags = Flags.getFunctionFlags( - function.annotations.isNotEmpty(), + function.nonSourceAnnotations(session).isNotEmpty(), ProtoEnumFlags.visibility(simpleFunction?.let { normalizeVisibility(it) } ?: Visibilities.LOCAL), ProtoEnumFlags.modality(simpleFunction?.modality ?: Modality.FINAL), ProtoEnumFlags.memberKind(CallableMemberDescriptor.Kind.DECLARATION), @@ -383,7 +383,7 @@ class FirElementSerializer private constructor( val local = createChildSerializer(typeAlias) val flags = Flags.getTypeAliasFlags( - typeAlias.annotations.isNotEmpty(), + typeAlias.nonSourceAnnotations(session).isNotEmpty(), ProtoEnumFlags.visibility(normalizeVisibility(typeAlias)) ) if (flags != builder.flags) { @@ -414,7 +414,7 @@ class FirElementSerializer private constructor( builder.addAllVersionRequirement(serializeVersionRequirements(typeAlias)) } - for (annotation in typeAlias.annotations) { + for (annotation in typeAlias.nonSourceAnnotations(session)) { builder.addAnnotation(extension.annotationSerializer.serializeAnnotation(annotation)) } @@ -436,7 +436,7 @@ class FirElementSerializer private constructor( val local = createChildSerializer(constructor) val flags = Flags.getConstructorFlags( - constructor.annotations.isNotEmpty(), + constructor.nonSourceAnnotations(session).isNotEmpty(), ProtoEnumFlags.visibility(normalizeVisibility(constructor)), !constructor.isPrimary ) @@ -471,7 +471,7 @@ class FirElementSerializer private constructor( val declaresDefaultValue = parameter.defaultValue != null // TODO: || parameter.isActualParameterWithAnyExpectedDefault val flags = Flags.getValueParameterFlags( - parameter.annotations.isNotEmpty(), declaresDefaultValue, + parameter.nonSourceAnnotations(session).isNotEmpty(), declaresDefaultValue, parameter.isCrossinline, parameter.isNoinline ) if (flags != builder.flags) { @@ -687,7 +687,7 @@ class FirElementSerializer private constructor( val isDefault = accessor is FirDefaultPropertyAccessor && accessor.annotations.isEmpty() && accessor.visibility == property.visibility return Flags.getAccessorFlags( - accessor.annotations.isNotEmpty(), + accessor.nonSourceAnnotations(session).isNotEmpty(), ProtoEnumFlags.visibility(normalizeVisibility(accessor)), ProtoEnumFlags.modality(accessor.modality!!), !isDefault, @@ -735,8 +735,7 @@ class FirElementSerializer private constructor( private fun MutableVersionRequirementTable.serializeVersionRequirements(annotations: List): List = annotations .filter { - val annotationConeType = it.annotationTypeRef.coneTypeSafe() - annotationConeType?.lookupTag?.classId?.asSingleFqName() == RequireKotlinConstants.FQ_NAME + it.toAnnotationClassId().asSingleFqName() == RequireKotlinConstants.FQ_NAME } .mapNotNull(::serializeVersionRequirementFromRequireKotlin) .map(::get) diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt index daa127cdf0d..5f2f553d1ce 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmSerializerExtension.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType import org.jetbrains.kotlin.fir.serialization.FirElementSerializer import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension +import org.jetbrains.kotlin.fir.serialization.nonSourceAnnotations import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.load.java.JvmAbi @@ -182,7 +183,7 @@ class FirJvmSerializerExtension @JvmOverloads constructor( } override fun serializeTypeParameter(typeParameter: FirTypeParameter, proto: ProtoBuf.TypeParameter.Builder) { - for (annotation in typeParameter.annotations) { + for (annotation in typeParameter.nonSourceAnnotations(session)) { proto.addExtension(JvmProtoBuf.typeParameterAnnotation, annotationSerializer.serializeAnnotation(annotation)) } }