From db815c96c5c43b09884d704ec067488384cc80dc Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 28 Aug 2020 13:33:33 +0300 Subject: [PATCH] [FIR] Substitute copied type parameters in fake override properties --- .../scopes/impl/FirClassSubstitutionScope.kt | 77 +++++++++++++++---- .../expressions/useImportedMember.fir.txt | 3 +- 2 files changed, 63 insertions(+), 17 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 0fbf4f60ab3..447a8c83011 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -352,16 +352,9 @@ class FirClassSubstitutionScope( val copiedParameterTypes = baseFunction.valueParameters.map { substitutor.substituteOrNull(it.returnTypeRef.coneType) } - val copiedReceiverType = newReceiverType?.let { - substitutor.substituteOrNull(it) - } ?: baseFunction.receiverTypeRef?.let { - substitutor.substituteOrNull(it.coneType) - } - val copiedReturnType = newReturnType?.let { - substitutor.substituteOrNull(it) - } ?: baseFunction.returnTypeRef.let { - substitutor.substituteOrNull(it.coneType) - } + val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType( + baseFunction as FirCallableMemberDeclaration<*>, newReceiverType, newReturnType, substitutor + ) configureAnnotationsAndSignature(session, baseFunction, copiedParameterTypes, copiedReceiverType, copiedReturnType) copiedTypeParameters } @@ -421,22 +414,74 @@ class FirClassSubstitutionScope( source = baseProperty.source this.session = session origin = FirDeclarationOrigin.FakeOverride - returnTypeRef = baseProperty.returnTypeRef.withReplacedReturnType(newReturnType) - receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType) name = baseProperty.name isVar = baseProperty.isVar this.symbol = symbol isLocal = false status = baseProperty.status.withExpect(isExpect) resolvePhase = baseProperty.resolvePhase - annotations += baseProperty.annotations - if (newTypeParameters != null) { - typeParameters += newTypeParameters - } + typeParameters += configureAnnotationsTypeParametersAndSignature(baseProperty, newTypeParameters, newReceiverType, newReturnType) } return symbol } + private fun FirPropertyBuilder.configureAnnotationsTypeParametersAndSignature( + baseProperty: FirProperty, + newTypeParameters: List?, + newReceiverType: ConeKotlinType? = null, + newReturnType: ConeKotlinType? = null + ): List { + return when { + baseProperty.typeParameters.isEmpty() -> { + configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType) + emptyList() + } + newTypeParameters == null -> { + val (copiedTypeParameters, substitutor) = createNewTypeParametersAndSubstitutor( + baseProperty, ConeSubstitutor.Empty + ) + val (copiedReceiverType, copiedReturnType) = substituteReceiverAndReturnType( + baseProperty, newReceiverType, newReturnType, substitutor + ) + configureAnnotationsAndSignature(baseProperty, copiedReceiverType, copiedReturnType) + copiedTypeParameters.filterIsInstance() + } + else -> { + configureAnnotationsAndSignature(baseProperty, newReceiverType, newReturnType) + newTypeParameters + } + } + } + + private fun substituteReceiverAndReturnType( + baseCallable: FirCallableMemberDeclaration<*>, + newReceiverType: ConeKotlinType?, + newReturnType: ConeKotlinType?, + substitutor: ConeSubstitutor + ): Pair { + val copiedReceiverType = newReceiverType?.let { + substitutor.substituteOrNull(it) + } ?: baseCallable.receiverTypeRef?.let { + substitutor.substituteOrNull(it.coneType) + } + val copiedReturnType = newReturnType?.let { + substitutor.substituteOrNull(it) + } ?: baseCallable.returnTypeRef.let { + substitutor.substituteOrNull(it.coneType) + } + return copiedReceiverType to copiedReturnType + } + + private fun FirPropertyBuilder.configureAnnotationsAndSignature( + baseProperty: FirProperty, + newReceiverType: ConeKotlinType? = null, + newReturnType: ConeKotlinType? = null + ) { + annotations += baseProperty.annotations + returnTypeRef = baseProperty.returnTypeRef.withReplacedConeType(newReturnType) + receiverTypeRef = baseProperty.receiverTypeRef?.withReplacedConeType(newReceiverType) + } + fun createFakeOverrideField( session: FirSession, baseField: FirField, diff --git a/compiler/testData/ir/irText/expressions/useImportedMember.fir.txt b/compiler/testData/ir/irText/expressions/useImportedMember.fir.txt index 6c06d09745b..87907acdc09 100644 --- a/compiler/testData/ir/irText/expressions/useImportedMember.fir.txt +++ b/compiler/testData/ir/irText/expressions/useImportedMember.fir.txt @@ -124,10 +124,11 @@ FILE fqName: fileName:/useImportedMember.kt RETURN type=kotlin.Nothing from='public final fun (): T of .C. declared in .C' GET_VAR ': T of .C. declared in .C.' type=T of .C. origin=null PROPERTY FAKE_OVERRIDE name:fromClass visibility:public modality:FINAL [fake_override,val] - FUN FAKE_OVERRIDE name: visibility:public modality:FINAL <> ($this:.BaseClass) returnType:T of .BaseClass. [fake_override] + FUN FAKE_OVERRIDE name: visibility:public modality:FINAL ($this:.BaseClass) returnType:T of .C. [fake_override] correspondingProperty: PROPERTY FAKE_OVERRIDE name:fromClass visibility:public modality:FINAL [fake_override,val] overridden: public final fun (): T of .BaseClass. declared in .BaseClass + TYPE_PARAMETER name:T index:0 variance: superTypes:[kotlin.Any?] $this: VALUE_PARAMETER name: type:.BaseClass FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: