FIR serializer: introduce nonSourceAnnotations

This commit is contained in:
Mikhail Glukhikh
2020-04-21 18:42:57 +03:00
parent 7adb4eb872
commit ec7522c675
3 changed files with 57 additions and 13 deletions
@@ -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<FirAnnotationCall> =
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")
}
}
@@ -52,7 +52,7 @@ class FirElementSerializer private constructor(
private val containingDeclaration: FirDeclaration?,
private val typeParameters: Interner<FirTypeParameter>,
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<FirAnnotationCall>): List<Int> =
annotations
.filter {
val annotationConeType = it.annotationTypeRef.coneTypeSafe<ConeClassLikeType>()
annotationConeType?.lookupTag?.classId?.asSingleFqName() == RequireKotlinConstants.FQ_NAME
it.toAnnotationClassId().asSingleFqName() == RequireKotlinConstants.FQ_NAME
}
.mapNotNull(::serializeVersionRequirementFromRequireKotlin)
.map(::get)
@@ -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))
}
}