Use AnnotationSplitter for annotations on extension receiver

Instead of using `@receiver:`-targeted annotations on the receiver type,
use normal annotations of the ReceiverParameterDescriptor instance
everywhere
This commit is contained in:
Alexander Udalov
2018-08-08 18:54:49 +02:00
parent 823a24e0a3
commit 0e5544a491
10 changed files with 54 additions and 99 deletions
@@ -15,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil; import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.backend.common.bridges.Bridge; import org.jetbrains.kotlin.backend.common.bridges.Bridge;
import org.jetbrains.kotlin.backend.common.bridges.ImplKt; import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithOnlyTargetedAnnotations;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt; import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
@@ -73,7 +72,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION;
import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable; import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_GETTER;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.PROPERTY_SETTER;
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly; import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor; import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*; import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
@@ -532,22 +532,16 @@ public class FunctionCodegen {
continue; continue;
} }
if (kind == JvmMethodParameterKind.VALUE) { AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper);
AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper).genAnnotations( Annotated annotated =
iterator.next(), kind == JvmMethodParameterKind.VALUE
parameterSignature.getAsmType() ? iterator.next()
); : kind == JvmMethodParameterKind.RECEIVER
} ? JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter()
else if (kind == JvmMethodParameterKind.RECEIVER) { : null;
ReceiverParameterDescriptor receiver = JvmCodegenUtil.getDirectMember(functionDescriptor).getExtensionReceiverParameter();
if (receiver != null) { if (annotated != null) {
AnnotationCodegen annotationCodegen = AnnotationCodegen.forParameter(i, mv, innerClassConsumer, typeMapper); annotationCodegen.genAnnotations(annotated, parameterSignature.getAsmType());
Annotated targetedAnnotations = new AnnotatedWithOnlyTargetedAnnotations(receiver.getType());
annotationCodegen.genAnnotations(targetedAnnotations, parameterSignature.getAsmType(), RECEIVER);
annotationCodegen.genAnnotations(receiver, parameterSignature.getAsmType());
}
} }
} }
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.codegen.annotation package org.jetbrains.kotlin.codegen.annotation
import org.jetbrains.kotlin.descriptors.annotations.Annotated import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
interface WrappedAnnotated : Annotated { interface WrappedAnnotated : Annotated {
@@ -25,19 +24,3 @@ interface WrappedAnnotated : Annotated {
} }
class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, override val annotations: Annotations) : WrappedAnnotated class AnnotatedWithFakeAnnotations(override val originalAnnotated: Annotated, override val annotations: Annotations) : WrappedAnnotated
class AnnotatedWithOnlyTargetedAnnotations(original: Annotated) : Annotated {
override val annotations: Annotations = UseSiteTargetedAnnotations(original.annotations)
private class UseSiteTargetedAnnotations(private val additionalAnnotations: Annotations) : Annotations {
override fun isEmpty() = true
override fun getUseSiteTargetedAnnotations() = getAdditionalTargetedAnnotations()
override fun getAllAnnotations() = getAdditionalTargetedAnnotations()
override fun iterator() = emptyList<AnnotationDescriptor>().iterator()
private fun getAdditionalTargetedAnnotations() = additionalAnnotations.getUseSiteTargetedAnnotations()
}
}
@@ -939,8 +939,9 @@ public class DescriptorResolver {
ReceiverParameterDescriptor receiverDescriptor; ReceiverParameterDescriptor receiverDescriptor;
if (receiverType != null) { if (receiverType != null) {
AnnotationSplitter splitter = AnnotationSplitter.create(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
propertyDescriptor, receiverType, Annotations.Companion.getEMPTY() propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
); );
} }
else { else {
@@ -25,6 +25,8 @@ import org.jetbrains.kotlin.contracts.description.ContractProviderKey
import org.jetbrains.kotlin.contracts.description.LazyContractProvider import org.jetbrains.kotlin.contracts.description.LazyContractProvider
import org.jetbrains.kotlin.contracts.parsing.ContractParsingServices import org.jetbrains.kotlin.contracts.parsing.ContractParsingServices
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationSplitter
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
@@ -55,6 +57,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker
import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
@@ -75,7 +78,8 @@ class FunctionDescriptorResolver(
private val overloadChecker: OverloadChecker, private val overloadChecker: OverloadChecker,
private val contractParsingServices: ContractParsingServices, private val contractParsingServices: ContractParsingServices,
private val expressionTypingServices: ExpressionTypingServices, private val expressionTypingServices: ExpressionTypingServices,
private val languageVersionSettings: LanguageVersionSettings private val languageVersionSettings: LanguageVersionSettings,
private val storageManager: StorageManager
) { ) {
fun resolveFunctionDescriptor( fun resolveFunctionDescriptor(
containingDescriptor: DeclarationDescriptor, containingDescriptor: DeclarationDescriptor,
@@ -209,10 +213,15 @@ class FunctionDescriptorResolver(
} }
} }
val extensionReceiver = receiverType?.let {
val splitter = AnnotationSplitter.create(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createExtensionReceiverParameterForCallable(
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
)
}
functionDescriptor.initialize( functionDescriptor.initialize(
receiverType?.let { extensionReceiver,
DescriptorFactory.createExtensionReceiverParameterForCallable(functionDescriptor, it, Annotations.EMPTY)
},
getDispatchReceiverParameterIfNeeded(container), getDispatchReceiverParameterIfNeeded(container),
typeParameterDescriptors, typeParameterDescriptors,
valueParameterDescriptors, valueParameterDescriptors,
@@ -39,9 +39,7 @@ object LateinitIntrinsicApplicabilityChecker : CallChecker {
// An optimization // An optimization
if (descriptor.name.asString() != "isInitialized") return if (descriptor.name.asString() != "isInitialized") return
// TODO: store "@receiver:..." annotations in ReceiverParameterDescriptor if (descriptor.extensionReceiverParameter?.annotations?.hasAnnotation(ACCESSIBLE_LATEINIT_PROPERTY_LITERAL) != true) return
val annotations = descriptor.extensionReceiverParameter?.value?.type?.annotations?.getUseSiteTargetedAnnotations() ?: return
if (annotations.none { it.annotation.fqName == ACCESSIBLE_LATEINIT_PROPERTY_LITERAL }) return
val expression = (resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression?.let(KtPsiUtil::safeDeparenthesize) val expression = (resolvedCall.extensionReceiver as? ExpressionReceiver)?.expression?.let(KtPsiUtil::safeDeparenthesize)
if (expression !is KtCallableReferenceExpression) { if (expression !is KtCallableReferenceExpression) {
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.psi2ir.generators package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -31,24 +30,12 @@ class AnnotationGenerator(context: GeneratorContext) : IrElementVisitorVoid {
} }
} }
override fun visitValueParameter(declaration: IrValueParameter) {
super.visitValueParameter(declaration)
declaration.descriptor.type.annotations.getAllAnnotations()
.filter { it.target == AnnotationUseSiteTarget.RECEIVER }
.generateAnnotationConstructorCalls(declaration)
}
private fun generateAnnotationsForDeclaration(declaration: IrDeclaration) { private fun generateAnnotationsForDeclaration(declaration: IrDeclaration) {
declaration.descriptor.annotations.getAllAnnotations() declaration.descriptor.annotations.getAllAnnotations()
.filter { isAnnotationTargetMatchingDeclaration(it.target, declaration) } .filter { isAnnotationTargetMatchingDeclaration(it.target, declaration) }
.generateAnnotationConstructorCalls(declaration) .mapTo(declaration.annotations) {
} constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
}
private fun List<AnnotationWithTarget>.generateAnnotationConstructorCalls(declaration: IrDeclaration) {
mapTo(declaration.annotations) {
constantValueGenerator.generateAnnotationConstructorCall(it.annotation)
}
} }
private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean = private fun isAnnotationTargetMatchingDeclaration(target: AnnotationUseSiteTarget?, element: IrElement): Boolean =
@@ -21,19 +21,19 @@ FILE fqName:<root> fileName:/receiverParameterWithAnnotations.kt
BLOCK_BODY BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()' DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
INSTANCE_INITIALIZER_CALL classDescriptor='A' INSTANCE_INITIALIZER_CALL classDescriptor='A'
FUN name:f visibility:public modality:FINAL <> ($this:A, $receiver:@receiver:Ann kotlin.String) returnType:kotlin.String flags: FUN name:f visibility:public modality:FINAL <> ($this:A, $receiver:kotlin.String) returnType:kotlin.String flags:
$this: VALUE_PARAMETER name:<this> type:A flags: $this: VALUE_PARAMETER name:<this> type:A flags:
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String flags: $receiver: VALUE_PARAMETER name:<this> type:kotlin.String flags:
annotations: annotations:
CALL 'constructor Ann()' type=Ann origin=null CALL 'constructor Ann()' type=Ann origin=null
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='f() on String: String' RETURN type=kotlin.Nothing from='f() on String: String'
CONST String type=kotlin.String value= CONST String type=kotlin.String value=
PROPERTY name:p visibility:public modality:FINAL flags:val PROPERTY name:p visibility:public modality:FINAL flags:val
FUN name:<get-p> visibility:public modality:FINAL <> ($this:A, $receiver:@receiver:Ann kotlin.String?) returnType:kotlin.String flags: FUN name:<get-p> visibility:public modality:FINAL <> ($this:A, $receiver:kotlin.String?) returnType:kotlin.String flags:
correspondingProperty: PROPERTY name:p visibility:public modality:FINAL flags:val correspondingProperty: PROPERTY name:p visibility:public modality:FINAL flags:val
$this: VALUE_PARAMETER name:<this> type:A flags: $this: VALUE_PARAMETER name:<this> type:A flags:
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String? flags: $receiver: VALUE_PARAMETER name:<this> type:kotlin.String? flags:
annotations: annotations:
CALL 'constructor Ann()' type=Ann origin=null CALL 'constructor Ann()' type=Ann origin=null
BLOCK_BODY BLOCK_BODY
@@ -52,17 +52,17 @@ FILE fqName:<root> fileName:/receiverParameterWithAnnotations.kt
overridden: overridden:
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags: FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String flags:
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags: $this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
FUN name:topLevelF visibility:public modality:FINAL <> ($receiver:@receiver:Ann kotlin.String?) returnType:kotlin.String flags: FUN name:topLevelF visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String flags:
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String? flags: $receiver: VALUE_PARAMETER name:<this> type:kotlin.String? flags:
annotations: annotations:
CALL 'constructor Ann()' type=Ann origin=null CALL 'constructor Ann()' type=Ann origin=null
BLOCK_BODY BLOCK_BODY
RETURN type=kotlin.Nothing from='topLevelF() on String?: String' RETURN type=kotlin.Nothing from='topLevelF() on String?: String'
CONST String type=kotlin.String value= CONST String type=kotlin.String value=
PROPERTY name:topLevelP visibility:public modality:FINAL flags:val PROPERTY name:topLevelP visibility:public modality:FINAL flags:val
FUN name:<get-topLevelP> visibility:public modality:FINAL <> ($receiver:@receiver:Ann kotlin.String) returnType:kotlin.String flags: FUN name:<get-topLevelP> visibility:public modality:FINAL <> ($receiver:kotlin.String) returnType:kotlin.String flags:
correspondingProperty: PROPERTY name:topLevelP visibility:public modality:FINAL flags:val correspondingProperty: PROPERTY name:topLevelP visibility:public modality:FINAL flags:val
$receiver: VALUE_PARAMETER name:<this> type:@receiver:Ann kotlin.String flags: $receiver: VALUE_PARAMETER name:<this> type:kotlin.String flags:
annotations: annotations:
CALL 'constructor Ann()' type=Ann origin=null CALL 'constructor Ann()' type=Ann origin=null
BLOCK_BODY BLOCK_BODY
@@ -7,8 +7,6 @@ package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
@@ -63,8 +61,8 @@ class MemberDeserializer(private val c: DeserializationContext) {
local.typeDeserializer.type(proto.returnType(c.typeTable)), local.typeDeserializer.type(proto.returnType(c.typeTable)),
local.typeDeserializer.ownTypeParameters, local.typeDeserializer.ownTypeParameters,
getDispatchReceiverParameter(), getDispatchReceiverParameter(),
proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) }?.let { receiverType -> proto.receiverType(c.typeTable)?.let(local.typeDeserializer::type)?.let { receiverType ->
DescriptorFactory.createExtensionReceiverParameterForCallable(property, receiverType, Annotations.EMPTY) DescriptorFactory.createExtensionReceiverParameterForCallable(property, receiverType, receiverAnnotations)
} }
) )
@@ -257,8 +255,8 @@ class MemberDeserializer(private val c: DeserializationContext) {
val local = c.childContext(function, proto.typeParameterList) val local = c.childContext(function, proto.typeParameterList)
function.initializeWithCoroutinesExperimentalityStatus( function.initializeWithCoroutinesExperimentalityStatus(
proto.receiverType(c.typeTable)?.let { local.typeDeserializer.type(it, receiverAnnotations) }?.let { receiverType -> proto.receiverType(c.typeTable)?.let(local.typeDeserializer::type)?.let { receiverType ->
DescriptorFactory.createExtensionReceiverParameterForCallable(function, receiverType, Annotations.EMPTY) DescriptorFactory.createExtensionReceiverParameterForCallable(function, receiverType, receiverAnnotations)
}, },
getDispatchReceiverParameter(), getDispatchReceiverParameter(),
local.typeDeserializer.ownTypeParameters, local.typeDeserializer.ownTypeParameters,
@@ -351,20 +349,12 @@ class MemberDeserializer(private val c: DeserializationContext) {
} }
} }
private fun getReceiverParameterAnnotations( private fun getReceiverParameterAnnotations(proto: MessageLite, kind: AnnotatedCallableKind): Annotations =
proto: MessageLite, DeserializedAnnotations(c.storageManager) {
kind: AnnotatedCallableKind,
receiverTargetedKind: AnnotatedCallableKind = kind
): Annotations {
return DeserializedAnnotationsWithPossibleTargets(c.storageManager) {
c.containingDeclaration.asProtoContainer()?.let { c.containingDeclaration.asProtoContainer()?.let {
c.components.annotationAndConstantLoader c.components.annotationAndConstantLoader.loadExtensionReceiverParameterAnnotations(it, proto, kind)
.loadExtensionReceiverParameterAnnotations(it, proto, receiverTargetedKind)
.map { annotation -> AnnotationWithTarget(annotation, AnnotationUseSiteTarget.RECEIVER) }
.toList()
}.orEmpty() }.orEmpty()
} }
}
private fun valueParameters( private fun valueParameters(
valueParameters: List<ProtoBuf.ValueParameter>, valueParameters: List<ProtoBuf.ValueParameter>,
@@ -7,14 +7,13 @@ package org.jetbrains.kotlin.serialization.deserialization
import org.jetbrains.kotlin.builtins.* import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.* import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotationsWithPossibleTargets import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedAnnotations
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedTypeParameterDescriptor
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -52,18 +51,18 @@ class TypeDeserializer(
get() = typeParameterDescriptors.values.toList() get() = typeParameterDescriptors.values.toList()
// TODO: don't load identical types from TypeTable more than once // TODO: don't load identical types from TypeTable more than once
fun type(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): KotlinType { fun type(proto: ProtoBuf.Type): KotlinType {
if (proto.hasFlexibleTypeCapabilitiesId()) { if (proto.hasFlexibleTypeCapabilitiesId()) {
val id = c.nameResolver.getString(proto.flexibleTypeCapabilitiesId) val id = c.nameResolver.getString(proto.flexibleTypeCapabilitiesId)
val lowerBound = simpleType(proto, additionalAnnotations) val lowerBound = simpleType(proto)
val upperBound = simpleType(proto.flexibleUpperBound(c.typeTable)!!, additionalAnnotations) val upperBound = simpleType(proto.flexibleUpperBound(c.typeTable)!!)
return c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound) return c.components.flexibleTypeDeserializer.create(proto, id, lowerBound, upperBound)
} }
return simpleType(proto, additionalAnnotations) return simpleType(proto)
} }
fun simpleType(proto: ProtoBuf.Type, additionalAnnotations: Annotations = Annotations.EMPTY): SimpleType { fun simpleType(proto: ProtoBuf.Type): SimpleType {
val localClassifierType = when { val localClassifierType = when {
proto.hasClassName() -> computeLocalClassifierReplacementType(proto.className) proto.hasClassName() -> computeLocalClassifierReplacementType(proto.className)
proto.hasTypeAliasName() -> computeLocalClassifierReplacementType(proto.typeAliasName) proto.hasTypeAliasName() -> computeLocalClassifierReplacementType(proto.typeAliasName)
@@ -77,11 +76,8 @@ class TypeDeserializer(
return ErrorUtils.createErrorTypeWithCustomConstructor(constructor.toString(), constructor) return ErrorUtils.createErrorTypeWithCustomConstructor(constructor.toString(), constructor)
} }
val annotations = DeserializedAnnotationsWithPossibleTargets(c.storageManager) { val annotations = DeserializedAnnotations(c.storageManager) {
c.components.annotationAndConstantLoader.loadTypeAnnotations(proto, c.nameResolver) c.components.annotationAndConstantLoader.loadTypeAnnotations(proto, c.nameResolver)
.map { AnnotationWithTarget(it, null) }
.plus(additionalAnnotations.getAllAnnotations())
.toList()
} }
fun ProtoBuf.Type.collectAllArguments(): List<ProtoBuf.Type.Argument> = fun ProtoBuf.Type.collectAllArguments(): List<ProtoBuf.Type.Argument> =
@@ -98,7 +94,7 @@ class TypeDeserializer(
} }
val abbreviatedTypeProto = proto.abbreviatedType(c.typeTable) ?: return simpleType val abbreviatedTypeProto = proto.abbreviatedType(c.typeTable) ?: return simpleType
return simpleType.withAbbreviation(simpleType(abbreviatedTypeProto, additionalAnnotations)) return simpleType.withAbbreviation(simpleType(abbreviatedTypeProto))
} }
private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor { private fun typeConstructor(proto: ProtoBuf.Type): TypeConstructor {
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.upperBounds import org.jetbrains.kotlin.metadata.deserialization.upperBounds
@@ -45,9 +44,7 @@ class DeserializedTypeParameterDescriptor(
if (upperBounds.isEmpty()) { if (upperBounds.isEmpty()) {
return listOf(this.builtIns.defaultBound) return listOf(this.builtIns.defaultBound)
} }
return upperBounds.map { return upperBounds.map(c.typeDeserializer::type)
c.typeDeserializer.type(it, Annotations.EMPTY)
}
} }
override fun reportSupertypeLoopError(type: KotlinType) = throw IllegalStateException( override fun reportSupertypeLoopError(type: KotlinType) = throw IllegalStateException(