From 30e52186ebf3943a76475e6c2270daa43f030beb Mon Sep 17 00:00:00 2001 From: Nikolay Lunyak Date: Mon, 23 Aug 2021 19:13:21 +0300 Subject: [PATCH] [FIR] Make default accessors always present --- .../FirPropertyFieldDeclarationChecker.kt | 9 +++- .../converter/DeclarationsConverter.kt | 26 ++++------ .../kotlin/fir/builder/RawFirBuilder.kt | 14 ++---- .../FirDeclarationsResolveTransformer.kt | 48 ------------------- 4 files changed, 18 insertions(+), 79 deletions(-) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyFieldDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyFieldDeclarationChecker.kt index 305cd9c6be0..80bbbb0da6e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyFieldDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirPropertyFieldDeclarationChecker.kt @@ -10,6 +10,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.FirProperty +import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.typeContext @@ -45,12 +47,15 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() { } } + private val FirPropertyAccessor?.isNotExplicit + get() = this == null || this is FirDefaultPropertyAccessor + private fun checkAsPropertyNotSubtype( property: FirProperty, context: CheckerContext, reporter: DiagnosticReporter ) { - if (property.isVar && property.setter == null) { + if (property.isVar && property.setter.isNotExplicit) { reporter.reportOn(property.source, FirErrors.PROPERTY_MUST_HAVE_SETTER, context) } } @@ -60,7 +65,7 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() { context: CheckerContext, reporter: DiagnosticReporter ) { - if (property.getter == null) { + if (property.getter.isNotExplicit) { reporter.reportOn(property.source, FirErrors.PROPERTY_MUST_HAVE_GETTER, context) } } diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 6f0ef51fbbe..9848b6e4223 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -1132,24 +1132,19 @@ class DeclarationsConverter( isExternal = modifiers.hasExternal() } - val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField val convertedAccessors = accessors.map { - convertGetterOrSetter(it, returnType, propertyVisibility, symbol, modifiers, hasExplicitBackingField) + convertGetterOrSetter(it, returnType, propertyVisibility, symbol, modifiers) } this.getter = convertedAccessors.find { it.isGetter } - ?: if (!hasExplicitBackingField) { - FirDefaultPropertyGetter( - property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor), moduleData, FirDeclarationOrigin.Source, returnType, propertyVisibility, symbol, - ).also { - it.status = defaultAccessorStatus() - it.initContainingClassAttr() - } - } else { - null + ?: FirDefaultPropertyGetter( + property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor), moduleData, FirDeclarationOrigin.Source, returnType, propertyVisibility, symbol, + ).also { + it.status = defaultAccessorStatus() + it.initContainingClassAttr() } // NOTE: We still need the setter even for a val property so we can report errors (e.g., VAL_WITH_SETTER). this.setter = convertedAccessors.find { it.isSetter } - ?: if (isVar && !hasExplicitBackingField) { + ?: if (isVar) { FirDefaultPropertySetter( property.toFirSourceElement(FirFakeSourceElementKind.DefaultAccessor), moduleData, @@ -1259,7 +1254,6 @@ class DeclarationsConverter( propertyVisibility: Visibility, propertySymbol: FirPropertySymbol, propertyModifiers: Modifier, - hasBackingField: Boolean, ): FirPropertyAccessor { var modifiers = Modifier() var isGetter = true @@ -1298,11 +1292,7 @@ class DeclarationsConverter( isExternal = propertyModifiers.hasExternal() || modifiers.hasExternal() } val sourceElement = getterOrSetter.toFirSourceElement() - // If an explicit backing field is present, - // the default accessors might not be compatible - // with it. We should check the types first, and - // only then see if we can create the default accessors. - if (block == null && expression == null && !hasBackingField) { + if (block == null && expression == null) { return FirDefaultPropertyAccessor .createGetterOrSetter( sourceElement, diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index cd66cc60af3..24d3864a9e2 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -368,7 +368,6 @@ open class RawFirBuilder( propertyTypeRef: FirTypeRef, propertySymbol: FirPropertySymbol, isGetter: Boolean, - hasExplicitBackingField: Boolean, ): FirPropertyAccessor? { val accessorVisibility = if (this?.visibility != null && this.visibility != Visibilities.Unknown) this.visibility else property.visibility @@ -425,11 +424,7 @@ open class RawFirBuilder( this@RawFirBuilder.context.firFunctionTargets.removeLast() } } - // If an explicit backing field is present, - // the default accessors might not be compatible - // with it. We should check the types first, and - // only then see if we can create the default accessors. - !hasExplicitBackingField && (isGetter || property.isVar) -> { + isGetter || property.isVar -> { // Default getter for val/var properties, and default setter for var properties. val propertySource = this?.toFirSourceElement() ?: property.toFirPsiSourceElement(FirFakeSourceElementKind.DefaultAccessor) @@ -1531,20 +1526,17 @@ open class RawFirBuilder( propertyType, ) - val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField getter = this@toFirProperty.getter.toFirPropertyAccessor( this@toFirProperty, propertyType, propertySymbol = symbol, - isGetter = true, - hasExplicitBackingField, + isGetter = true ) setter = this@toFirProperty.setter.toFirPropertyAccessor( this@toFirProperty, propertyType, propertySymbol = symbol, - isGetter = false, - hasExplicitBackingField, + isGetter = false ) status = FirDeclarationStatusImpl(visibility, modality).apply { 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 5522995a375..b9ae6e6755f 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 @@ -151,10 +151,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } property.transformBackingField(transformer, withExpectedType(property.returnTypeRef)) } - // 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) @@ -185,50 +181,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } } - private fun FirProperty.generateMissingDefaultAccessors() { - val fieldDeclaration = backingField ?: return - - if ( - !this.hasExplicitBackingField || - fieldDeclaration.returnTypeRef !is FirResolvedTypeRef - ) { - return - } - - val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext( - errorTypesEqualToAnything = false, - stubTypesEqualToAnything = false - ) - - if (getter == null && 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 {