[FIR] KT-57104: Preserve @JvmName on fake-override accessors

Otherwise, when we come to `ClassCodegen.kt:173
for `GradleActionTest` and check
`FUN FAKE_OVERRIDE name:<get-project>`,
we then go to `JvmSignatureClashDetector.kt:37`,
and call `mapRawSignature(overriddenFunction)`
which ignores the original `@JvmName`.
It does so because it relies on the property copy
which forgets to copy the getter, but
`@get:JvmName` is stored in it.

Extra when-branches for `FAKE_OVERRIDE` are needed,
because otherwise the annotations would not
be copied in `Fir2IrDeclarationStorage.kt:723`.

Extra when-branches for `DELEGATED_MEMBER` are
needed, because otherwise the generated IR changes
in some tests. For example, see:
`FirLightTreeIrTextTestGenerated.Declarations.testKt35550`.

The `assumesBackingField`-related change is backed by
the `FirLightTreeIrTextTestGenerated.Stubs.testJavaEnum` test.

`this.body = null` ensures the resulting IR
matches K1.

The change in `FirImplicitBodyResolve.kt` is needed,
because otherwise the bootstrap compiler fails at
`:compiler:frontend:compileKotlin`,
but I didn't come up with a smaller test for it.

If we don't make an explicit accessor copy,
then when we later create a `Fir2IrLazyPropertyAccessor`
for the fake override getter, it's `fir` will
be a reference to the `FirProperty`, not `FirPropertyAccessor`.
That's why `DumpIrTreeVisitor` will render `IntrinsicConstEvaluation` as
a getter annotation as well.

`FirPsiIrTextTestGenerated.testDelegatedGenericImplementation`
renders type parameters from `<get-x>`,
because when assigning `extensionReceiverParameter`
of the setter `<set-x>` we come to
`Fir2IrClassifierStorage.kt:638`,
and in this cache there's the parameter with
the `<get-x>` parent.
Note that `typeContext.origin == DEFAULT` in
`getCachedIrTypeParameter`.
It's `DEFAULT` because at the line `Fir2IrDeclarationStorage.kt:335`
the `function` variable is `null` (because there's no setter).

The change in `declarationAttributes.kt` is backed
by the `FirPsiIrTextTestGenerated.testKt45853` test.

^KT-57104 Fixed
^KT-57432 Fixed

Merge-request: KT-MR-9210
Merged-by: Nikolay Lunyak <Nikolay.Lunyak@jetbrains.com>
This commit is contained in:
Nikolay Lunyak
2023-03-22 18:16:31 +00:00
committed by Space Team
parent 9a4a3d1f49
commit 7b04201e77
12 changed files with 214 additions and 14 deletions
@@ -10,10 +10,12 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.synthetic.buildSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
import org.jetbrains.kotlin.fir.declarations.utils.isStatic
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
@@ -374,11 +376,115 @@ object FirFakeOverrideGenerator {
fakeOverrideSubstitution
)
deprecationsProvider = baseProperty.deprecationsProvider
getter = baseProperty.getter?.buildCopyIfNeeded(
moduleData = session.moduleData,
origin = origin,
propertyReturnTypeRef = this@buildProperty.returnTypeRef,
propertySymbol = newSymbol,
dispatchReceiverType = dispatchReceiverType,
derivedClassLookupTag = derivedClassLookupTag,
baseProperty = baseProperty,
)
setter = baseProperty.setter?.buildCopyIfNeeded(
moduleData = session.moduleData,
origin = origin,
propertyReturnTypeRef = this@buildProperty.returnTypeRef,
propertySymbol = newSymbol,
dispatchReceiverType = dispatchReceiverType,
derivedClassLookupTag = derivedClassLookupTag,
baseProperty = baseProperty,
)
}.apply {
containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf { shouldOverrideSetContainingClass(baseProperty) }
}
}
private fun FirPropertyAccessor.buildCopyIfNeeded(
moduleData: FirModuleData,
origin: FirDeclarationOrigin,
propertyReturnTypeRef: FirTypeRef,
propertySymbol: FirPropertySymbol,
dispatchReceiverType: ConeSimpleKotlinType?,
derivedClassLookupTag: ConeClassLikeLookupTag?,
baseProperty: FirProperty,
) = when {
annotations.isNotEmpty() || visibility != baseProperty.visibility -> buildCopy(
moduleData,
origin,
propertyReturnTypeRef,
propertySymbol,
dispatchReceiverType,
derivedClassLookupTag,
baseProperty,
)
else -> null
}
private fun FirPropertyAccessor.buildCopy(
moduleData: FirModuleData,
origin: FirDeclarationOrigin,
propertyReturnTypeRef: FirTypeRef,
propertySymbol: FirPropertySymbol,
dispatchReceiverType: ConeSimpleKotlinType?,
derivedClassLookupTag: ConeClassLikeLookupTag?,
baseProperty: FirProperty,
) = when (this) {
is FirDefaultPropertyGetter -> FirDefaultPropertyGetter(
source = source,
moduleData = moduleData,
origin = origin,
propertyTypeRef = propertyReturnTypeRef,
visibility = visibility,
propertySymbol = propertySymbol,
modality = modality ?: Modality.FINAL,
effectiveVisibility = effectiveVisibility,
).apply {
replaceAnnotations(annotations)
}
is FirDefaultPropertySetter -> FirDefaultPropertySetter(
source = source,
moduleData = moduleData,
origin = origin,
propertyTypeRef = propertyReturnTypeRef,
visibility = visibility,
propertySymbol = propertySymbol,
modality = modality ?: Modality.FINAL,
effectiveVisibility = effectiveVisibility,
).apply {
replaceAnnotations(annotations)
}
else -> buildPropertyAccessorCopy(this) {
this.symbol = FirPropertyAccessorSymbol()
this.moduleData = moduleData
this.origin = origin
this.propertySymbol = propertySymbol
this.dispatchReceiverType = dispatchReceiverType
this.body = null
}.also {
if (it.isSetter) {
val newParameter = buildValueParameterCopy(it.valueParameters.first()) {
this.symbol = FirValueParameterSymbol(symbol.name)
this.returnTypeRef = propertyReturnTypeRef
}
it.replaceValueParameters(listOf(newParameter))
} else {
it.replaceReturnTypeRef(propertyReturnTypeRef)
}
}
}.also { accessor ->
when (accessor.origin) {
FirDeclarationOrigin.IntersectionOverride -> accessor.originalForIntersectionOverrideAttr = this
FirDeclarationOrigin.SubstitutionOverride -> accessor.originalForSubstitutionOverrideAttr = this
else -> {}
}
accessor.containingClassForStaticMemberAttr = derivedClassLookupTag.takeIf {
accessor is FirDefaultPropertyAccessor || shouldOverrideSetContainingClass(baseProperty)
}
}
fun createCopyForFirField(
newSymbol: FirFieldSymbol,
baseField: FirField,