From 1291f9e460984556a25158a7704115006aadcb43 Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Mon, 9 Aug 2021 15:56:36 +0300 Subject: [PATCH] [FIR] Add missing getters generation --- .../FirDeclarationsResolveTransformer.kt | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 71ba1231d8b..3a3aab338b3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -11,11 +11,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.buildValueParameter +import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl 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.utils.isInline -import org.jetbrains.kotlin.fir.declarations.utils.isLocal -import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* @@ -47,6 +48,8 @@ import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.types.AbstractTypeChecker +import org.jetbrains.kotlin.name.SpecialNames open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) : FirPartialBodyResolveTransformer(transformer) { private val statusResolver: FirStatusResolver = FirStatusResolver(session, scopeSession) @@ -148,6 +151,10 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor storeVariableReturnType(property) } } + // In case an explicit backing field declaration + // is present, and the default accessors haven't + // been generated earlier. + property.generateMissingDefaultAccessors() val delegate = property.delegate if (delegate != null) { transformPropertyAccessorsWithDelegate(property, delegate) @@ -178,6 +185,51 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } } + private fun FirProperty.generateMissingDefaultAccessors() { + val fieldDeclaration = backingField ?: return + + val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext( + errorTypesEqualToAnything = false, + stubTypesEqualToAnything = false + ) + + if (fieldDeclaration.isSubtypeOf(this, typeCheckerContext)) { + this.replaceGetter( + FirDefaultPropertyGetter( + null, + this.moduleData, + FirDeclarationOrigin.Source, + this.returnTypeRef, + this.visibility, + this.symbol, + ).also { + it.status = this.getDefaultAccessorStatus() + } + ) + } else if (this.isVar && this.isSubtypeOf(fieldDeclaration, typeCheckerContext)) { + this.replaceSetter( + FirDefaultPropertySetter( + null, + this.moduleData, + FirDeclarationOrigin.Source, + this.returnTypeRef, + this.visibility, + this.symbol, + ).also { + it.status = this.getDefaultAccessorStatus() + } + ) + } + } + + fun FirProperty.getDefaultAccessorStatus(): FirDeclarationStatus { + // Downward propagation of `inline` and `external` modifiers (from property to its accessors) + return FirDeclarationStatusImpl(this.visibility, this.modality).apply { + isInline = this@getDefaultAccessorStatus.isInline + isExternal = this@getDefaultAccessorStatus.isExternal + } + } + override fun transformField(field: FirField, data: ResolutionMode): FirField { val returnTypeRef = field.returnTypeRef if (implicitTypeOnly) return field