From 840d3975cc451f7d8941a888f5a97403da13609d Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Mon, 29 Jun 2020 16:17:50 +0300 Subject: [PATCH] [FIR] Add computing type attributes for deserialized types --- .../deserialization/ClassDeserialization.kt | 3 +- .../FirContractDeserializer.kt | 3 +- .../deserialization/FirMemberDeserializer.kt | 7 ++-- .../deserialization/FirTypeDeserializer.kt | 36 ++++++++++--------- .../providers/impl/FirTypeResolverImpl.kt | 17 ++------- .../kotlin/fir/types/FirTypeUtils.kt | 13 +++++++ 6 files changed, 44 insertions(+), 35 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index df346691960..114af526174 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.types.ConeAttributes import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl @@ -105,7 +106,7 @@ fun deserializeClassToSymbol( val classDeserializer = context.memberDeserializer val superTypesDeserialized = classProto.supertypes(context.typeTable).map { supertypeProto -> - typeDeserializer.simpleType(supertypeProto) + typeDeserializer.simpleType(supertypeProto, ConeAttributes.Empty) }// TODO: + c.components.additionalClassPartsProvider.getSupertypes(this@DeserializedClassDescriptor) superTypesDeserialized.mapNotNullTo(superTypeRefs) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt index b87e0e1dc7d..fb49474cc0f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.contracts.description.* import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction import org.jetbrains.kotlin.fir.expressions.LogicOperationKind +import org.jetbrains.kotlin.fir.types.ConeAttributes import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.isBoolean import org.jetbrains.kotlin.metadata.ProtoBuf @@ -148,7 +149,7 @@ class FirContractDeserializer(private val c: FirDeserializationContext) { } private fun extractType(proto: ProtoBuf.Expression): ConeKotlinType? { - return c.typeDeserializer.type(proto.isInstanceType(c.typeTable) ?: return null) + return c.typeDeserializer.type(proto.isInstanceType(c.typeTable) ?: return null, ConeAttributes.Empty) } private fun loadConstant(value: ProtoBuf.Expression.ConstantValue): ConeConstantReference? = when (value) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt index 5866904f61b..a05eb73776f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirMemberDeserializer.kt @@ -16,8 +16,10 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionStub import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.ConeAttributes import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.computeTypeAttributes import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef @@ -168,7 +170,7 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { } symbol = FirTypeAliasSymbol(ClassId(c.packageFqName, name)) expandedTypeRef = buildResolvedTypeRef { - type = local.typeDeserializer.type(proto.underlyingType(c.typeTable)) + type = local.typeDeserializer.type(proto.underlyingType(c.typeTable), ConeAttributes.Empty) } resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES typeParameters += local.typeDeserializer.ownTypeParameters.map { it.fir } @@ -423,8 +425,9 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) { private fun ProtoBuf.Type.toTypeRef(context: FirDeserializationContext): FirTypeRef { return buildResolvedTypeRef { - type = context.typeDeserializer.type(this@toTypeRef) annotations += context.annotationDeserializer.loadTypeAnnotations(this@toTypeRef, context.nameResolver) + val attributes = annotations.computeTypeAttributes() + type = context.typeDeserializer.type(this@toTypeRef, attributes) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirTypeDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirTypeDeserializer.kt index c61e961793d..7f591640b4e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirTypeDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirTypeDeserializer.kt @@ -77,7 +77,7 @@ class FirTypeDeserializer( val builder = builders[index] builder.apply { proto.upperBoundList.mapTo(bounds) { - buildResolvedTypeRef { type = type(it) } + buildResolvedTypeRef { type = type(it, ConeAttributes.Empty) } } addDefaultBoundIfNecessary() }.build() @@ -96,15 +96,15 @@ class FirTypeDeserializer( } } - fun type(proto: ProtoBuf.Type): ConeKotlinType { + fun type(proto: ProtoBuf.Type, attributes: ConeAttributes): ConeKotlinType { if (proto.hasFlexibleTypeCapabilitiesId()) { - val lowerBound = simpleType(proto) - val upperBound = simpleType(proto.flexibleUpperBound(typeTable)!!) + val lowerBound = simpleType(proto, attributes) + val upperBound = simpleType(proto.flexibleUpperBound(typeTable)!!, attributes) return ConeFlexibleType(lowerBound!!, upperBound!!) //c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound) } - return simpleType(proto) ?: ConeKotlinErrorType("?!id:0") + return simpleType(proto, attributes) ?: ConeKotlinErrorType("?!id:0") } private fun typeParameterSymbol(typeParameterId: Int): ConeTypeParameterLookupTag? = @@ -123,7 +123,7 @@ class FirTypeDeserializer( fun FirClassLikeSymbol<*>.typeParameters(): List = (fir as? FirTypeParameterRefsOwner)?.typeParameters?.map { it.symbol }.orEmpty() - fun simpleType(proto: ProtoBuf.Type): ConeLookupTagBasedType? { + fun simpleType(proto: ProtoBuf.Type, attributes: ConeAttributes): ConeLookupTagBasedType? { val constructor = typeSymbol(proto) ?: return null if (constructor is ConeTypeParameterLookupTag) return ConeTypeParameterTypeImpl(constructor, isNullable = proto.nullable) @@ -135,14 +135,14 @@ class FirTypeDeserializer( val arguments = proto.collectAllArguments().map(this::typeArgument).toTypedArray() val simpleType = if (Flags.SUSPEND_TYPE.get(proto.flags)) { - createSuspendFunctionType(constructor, arguments, isNullable = proto.nullable) + createSuspendFunctionType(constructor, arguments, isNullable = proto.nullable, attributes) } else { - ConeClassLikeTypeImpl(constructor, arguments, isNullable = proto.nullable) + ConeClassLikeTypeImpl(constructor, arguments, isNullable = proto.nullable, attributes) } val abbreviatedTypeProto = proto.abbreviatedType(typeTable) ?: return simpleType - return simpleType(abbreviatedTypeProto) + return simpleType(abbreviatedTypeProto, attributes) } @@ -150,7 +150,8 @@ class FirTypeDeserializer( //annotations: Annotations, TODO?, functionTypeConstructor: ConeClassLikeLookupTag, arguments: Array, - isNullable: Boolean + isNullable: Boolean, + attributes: ConeAttributes ): ConeClassLikeType? { fun ConeClassLikeType.isContinuation(): Boolean { if (this.typeArguments.size != 1) return false @@ -161,7 +162,7 @@ class FirTypeDeserializer( val returnType = arguments.lastOrNull() val continuationType = arguments.getOrNull(arguments.lastIndex - 1) as? ConeClassLikeType ?: return null - if (!continuationType.isContinuation()) return ConeClassLikeTypeImpl(functionTypeConstructor, arguments, isNullable) + if (!continuationType.isContinuation()) return ConeClassLikeTypeImpl(functionTypeConstructor, arguments, isNullable, attributes) val suspendReturnType = continuationType.typeArguments.single() as ConeKotlinTypeProjection @@ -171,7 +172,7 @@ class FirTypeDeserializer( return ConeClassLikeTypeImpl( ConeClassLikeLookupTagImpl(ClassId(kind.packageFqName, kind.numberedClassName(valueParameters.size))), (valueParameters + suspendReturnType).toTypedArray(), - isNullable + isNullable, attributes ) } @@ -179,11 +180,12 @@ class FirTypeDeserializer( //annotations: Annotations, TODO? functionTypeConstructor: ConeClassLikeLookupTag, arguments: Array, - isNullable: Boolean + isNullable: Boolean, + attributes: ConeAttributes ): ConeClassLikeType { val result = when (functionTypeConstructor.toSymbol(session)!!.firUnsafe().typeParameters.size - arguments.size) { - 0 -> createSuspendFunctionTypeForBasicCase(/* annotations, */ functionTypeConstructor, arguments, isNullable) + 0 -> createSuspendFunctionTypeForBasicCase(/* annotations, */ functionTypeConstructor, arguments, isNullable, attributes) // This case for types written by eap compiler 1.1 1 -> { val arity = arguments.size - 1 @@ -192,7 +194,8 @@ class FirTypeDeserializer( ConeClassLikeTypeImpl( ConeClassLikeLookupTagImpl(ClassId(kind.packageFqName, kind.numberedClassName(arity))), arguments, - isNullable + isNullable, + attributes ) } else { null @@ -226,7 +229,8 @@ class FirTypeDeserializer( val variance = ProtoEnumFlags.variance(typeArgumentProto.projection) val type = typeArgumentProto.type(typeTable) ?: return ConeKotlinErrorType("No type recorded") - val coneType = type(type) + // TODO: check that here we don't have any attributes + val coneType = type(type, ConeAttributes.Empty) return coneType.toTypeProjection(variance) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 4561dfcfa0c..de22c57476e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -84,23 +84,9 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver { if (symbol == null) { return ConeKotlinErrorType("Symbol not found, for `${typeRef.render()}`") } - return symbol.constructType(typeRef.qualifier, typeRef.isMarkedNullable, symbolOriginSession = session, typeRef.computeTypeAttributes()) + return symbol.constructType(typeRef.qualifier, typeRef.isMarkedNullable, symbolOriginSession = session, typeRef.annotations.computeTypeAttributes()) } - private fun FirTypeRef.computeTypeAttributes(): ConeAttributes { - if (annotations.isEmpty()) return ConeAttributes.Empty - val attributes = mutableListOf>() - for (annotation in annotations) { - val type = annotation.annotationTypeRef.coneTypeSafe() ?: continue - when (type.lookupTag.classId) { - CompilerConeAttributes.Exact.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.Exact - CompilerConeAttributes.NoInfer.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.NoInfer - } - } - return ConeAttributes.create(attributes) - } - - private fun createFunctionalType(typeRef: FirFunctionTypeRef): ConeClassLikeType { val parameters = listOfNotNull((typeRef.receiverTypeRef as FirResolvedTypeRef?)?.type) + @@ -111,6 +97,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver { } else { KotlinBuiltIns.getFunctionClassId(typeRef.parametersCount) } + val attributes = typeRef.annotations.computeTypeAttributes() return ConeClassLikeTypeImpl( resolveBuiltInQualified(classId, session).toLookupTag(), parameters.toTypedArray(), diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt index ef20685a684..105ab7fb819 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirTypeUtils.kt @@ -77,3 +77,16 @@ fun ConeClassLikeType.toConstKind(): FirConstKind<*>? = when (lookupTag.classId) StandardClassIds.UByte -> FirConstKind.UnsignedByte else -> null } + +fun List.computeTypeAttributes(): ConeAttributes { + if (this.isEmpty()) return ConeAttributes.Empty + val attributes = mutableListOf>() + for (annotation in this) { + val type = annotation.annotationTypeRef.coneTypeSafe() ?: continue + when (type.lookupTag.classId) { + CompilerConeAttributes.Exact.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.Exact + CompilerConeAttributes.NoInfer.ANNOTATION_CLASS_ID -> attributes += CompilerConeAttributes.NoInfer + } + } + return ConeAttributes.create(attributes) +} \ No newline at end of file