diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt index ea856ee541e..f6f0a0cc278 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt @@ -169,7 +169,7 @@ internal fun checkPropertyInitializer( !isExpect && !isInitialized && !isExternal && - property.backingField == null + !property.hasExplicitBackingField ) { if (property.receiverTypeRef != null && !property.hasAccessorImplementation) { reporter.reportOn(propertySource, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt index 5d8ba91f1ce..bb00e2422fb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirInlineDeclarationChecker.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.declaration +import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.Visibilities @@ -231,7 +232,12 @@ object FirInlineDeclarationChecker : FirFunctionChecker() { source: FirSourceElement, context: CheckerContext ) { - if (calledDeclaration == null) return + if ( + calledDeclaration == null || + calledDeclaration.callableId.callableName == BACKING_FIELD + ) { + return + } val recordedEffectiveVisibility = calledDeclaration.publishedApiEffectiveVisibility ?: calledDeclaration.effectiveVisibility val calledFunEffectiveVisibility = recordedEffectiveVisibility.let { if (it == EffectiveVisibility.Local) { 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 e67646ac797..305cd9c6be0 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,7 @@ 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.utils.hasExplicitBackingField import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.isSubtypeOf @@ -18,6 +19,10 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { val backingField = declaration.backingField ?: return + if (!declaration.hasExplicitBackingField) { + return + } + val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( errorTypesEqualToAnything = false, stubTypesEqualToAnything = false diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index b39f1a73b18..09efc9dbed1 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -197,7 +197,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(declarationStorage: Fir2IrDecla is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this) is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this) is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) - is FirDelegateFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) + is FirDelegateFieldSymbol -> declarationStorage.getIrDelegateFieldSymbol(this) is FirVariableSymbol<*> -> declarationStorage.getIrValueSymbol(this) else -> null } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 87ca57a7cf4..0dc470b8be0 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -1223,8 +1223,16 @@ class Fir2IrDeclarationStorage( return irProperty.symbol } - fun getIrBackingFieldSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol { - return when (val fir = firVariableSymbol.fir) { + fun getIrBackingFieldSymbol(firBackingFieldSymbol: FirBackingFieldSymbol): IrSymbol { + return getIrPropertyForwardedSymbol(firBackingFieldSymbol.fir.propertySymbol.fir) + } + + fun getIrDelegateFieldSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol { + return getIrPropertyForwardedSymbol(firVariableSymbol.fir) + } + + fun getIrPropertyForwardedSymbol(fir: FirVariable): IrSymbol { + return when (fir) { is FirProperty -> { if (fir.isLocal) { return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir) 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 918d1298537..6f0ef51fbbe 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 @@ -9,6 +9,7 @@ import com.intellij.lang.LighterASTNode import com.intellij.psi.TokenType import com.intellij.util.diff.FlyweightCapableTreeStructure import org.jetbrains.kotlin.KtNodeTypes.* +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality @@ -1081,7 +1082,7 @@ class DeclarationsConverter( typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, symbol) } - backingField = fieldDeclaration.convertBackingField(symbol, modifiers) + backingField = fieldDeclaration.convertBackingField(symbol, modifiers, returnType, isVar) if (isLocal) { this.isLocal = true @@ -1131,7 +1132,7 @@ class DeclarationsConverter( isExternal = modifiers.hasExternal() } - val hasExplicitBackingField = backingField != null + val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField val convertedAccessors = accessors.map { convertGetterOrSetter(it, returnType, propertyVisibility, symbol, modifiers, hasExplicitBackingField) } @@ -1355,7 +1356,9 @@ class DeclarationsConverter( private fun LighterASTNode?.convertBackingField( propertySymbol: FirPropertySymbol, propertyModifiers: Modifier, - ): FirBackingField? { + propertyReturnType: FirTypeRef, + isVar: Boolean, + ): FirBackingField { var modifiers = Modifier() var returnType: FirTypeRef = implicitType var initializerExpression: LighterASTNode? = null @@ -1382,14 +1385,24 @@ class DeclarationsConverter( moduleData = baseModuleData origin = FirDeclarationOrigin.Source returnTypeRef = returnType - symbol = FirPropertyFieldDeclarationSymbol() + name = StandardNames.BACKING_FIELD + symbol = FirBackingFieldSymbol(CallableId(name)) this.status = status annotations += modifiers.annotations this.propertySymbol = propertySymbol this.initializer = backingFieldInitializer + this.isVar = isVar + this.isVal = !isVar } } else { - null + FirDefaultPropertyBackingField( + moduleData = baseModuleData, + annotations = modifiers.annotations, + returnTypeRef = propertyReturnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), + isVar = isVar, + propertySymbol = propertySymbol, + status = status, + ) } } 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 9d5e44058df..cd66cc60af3 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 @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.builder import com.intellij.psi.PsiElement import com.intellij.psi.tree.IElementType import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality @@ -473,7 +474,8 @@ open class RawFirBuilder( private fun KtBackingField?.toFirBackingField( property: KtProperty, propertySymbol: FirPropertySymbol, - ): FirBackingField? { + propertyReturnType: FirTypeRef, + ): FirBackingField { val componentVisibility = if (this?.visibility != null && this.visibility != Visibilities.Unknown) { this.visibility } else { @@ -497,12 +499,22 @@ open class RawFirBuilder( returnTypeRef = returnType this.status = status extractAnnotationsTo(this) - symbol = FirPropertyFieldDeclarationSymbol() + name = BACKING_FIELD + symbol = FirBackingFieldSymbol(CallableId(name)) this.propertySymbol = propertySymbol this.initializer = backingFieldInitializer + this.isVar = property.isVar + this.isVal = !property.isVar } } else { - null + FirDefaultPropertyBackingField( + moduleData = baseModuleData, + annotations = mutableListOf(), + returnTypeRef = propertyReturnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor), + isVar = property.isVar, + propertySymbol = propertySymbol, + status = status, + ) } } @@ -1478,6 +1490,7 @@ open class RawFirBuilder( backingField = this@toFirProperty.fieldDeclaration.toFirBackingField( this@toFirProperty, propertySymbol = symbol, + propertyType, ) status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL).apply { @@ -1515,9 +1528,10 @@ open class RawFirBuilder( backingField = this@toFirProperty.fieldDeclaration.toFirBackingField( this@toFirProperty, propertySymbol = symbol, + propertyType, ) - val hasExplicitBackingField = backingField != null + val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField getter = this@toFirProperty.getter.toFirPropertyAccessor( this@toFirProperty, propertyType, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt index 841802f1f93..49d152870cc 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirCallResolver.kt @@ -721,7 +721,7 @@ class FirCallResolver( val candidate = candidates.single() val coneSymbol = candidate.symbol if (coneSymbol is FirBackingFieldSymbol) { - coneSymbol.fir.isReferredViaField = true + coneSymbol.fir.propertySymbol.fir.isReferredViaField = true return buildBackingFieldReference { this.source = source resolvedSymbol = coneSymbol diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index 500a2a67953..8e93ae7e60a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -65,6 +65,12 @@ abstract class FirVisibilityChecker : FirSessionComponent { val containingDeclarations = callInfo.containingDeclarations val session = callInfo.session + // We won't resolve into the backing field + // in the first place, if it's not accessible. + if (declaration is FirBackingField) { + return true + } + return isVisible(declaration, session, useSiteFile, containingDeclarations, candidate.dispatchReceiverValue) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 429e9e01066..38dc28d0a1a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -236,9 +236,12 @@ class ScopeTowerLevel( } } - val lookupTag = candidate.dispatchReceiverClassOrNull() + if (candidate !is FirBackingFieldSymbol) { + return null + } + + val lookupTag = candidate.fir.propertySymbol.dispatchReceiverClassOrNull() return when { - candidate !is FirBackingFieldSymbol -> null lookupTag != null -> { bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue -> (implicitReceiverValue.type as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag == lookupTag diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index e8f08e88e0c..a0c3e7d3831 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField +import org.jetbrains.kotlin.fir.declarations.utils.hasExplicitBackingField import org.jetbrains.kotlin.fir.declarations.utils.isLocal import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildAnonymousFunctionExpression @@ -524,7 +526,7 @@ class ControlFlowGraphBuilder { // ----------------------------------- Property ----------------------------------- fun enterProperty(property: FirProperty): PropertyInitializerEnterNode? { - if (property.initializer == null && property.delegate == null && property.backingField == null) return null + if (property.initializer == null && property.delegate == null && !property.hasExplicitBackingField) return null val graph = ControlFlowGraph(property, "val ${property.name}", ControlFlowGraph.Kind.PropertyInitializer) pushGraph(graph, Mode.PropertyInitializer) @@ -542,7 +544,7 @@ class ControlFlowGraphBuilder { } fun exitProperty(property: FirProperty): Pair? { - if (property.initializer == null && property.delegate == null && property.backingField == null) return null + if (property.initializer == null && property.delegate == null && !property.hasExplicitBackingField) return null val exitNode = exitTargetsForTry.pop() as PropertyInitializerExitNode popAndAddEdge(exitNode) val graph = popGraph() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index d9d7176beab..98579d1e1c5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -467,6 +467,14 @@ abstract class AbstractFirStatusResolveTransformer( property.getter?.let { transformPropertyAccessor(it, property) } property.setter?.let { transformPropertyAccessor(it, property) } + + property.backingField?.let { + it.transformStatus( + this, + statusResolver.resolveStatus(it, containingClass, property, isLocal = false) + ) + } + calculateDeprecations(property) return property } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolver.kt index 3042447c077..c344a55b66e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolver.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility import org.jetbrains.kotlin.fir.declarations.utils.isExpect @@ -58,6 +59,7 @@ class FirStatusResolver( is FirTypeAlias -> resolveStatus(declaration, containingClass, isLocal) is FirConstructor -> resolveStatus(declaration, containingClass, isLocal) is FirField -> resolveStatus(declaration, containingClass, isLocal) + is FirBackingField -> resolveStatus(declaration, containingClass, isLocal) else -> error("Unsupported declaration type: ${declaration.render()}") } } @@ -133,6 +135,14 @@ class FirStatusResolver( return resolveStatus(field, field.status, containingClass, null, isLocal) { emptyList() } } + fun resolveStatus( + backingField: FirBackingField, + containingClass: FirClass?, + isLocal: Boolean + ): FirResolvedDeclarationStatus { + return resolveStatus(backingField, backingField.status, containingClass, null, isLocal) { emptyList() } + } + fun resolveStatus(enumEntry: FirEnumEntry, containingClass: FirClass?, isLocal: Boolean): FirResolvedDeclarationStatus { return resolveStatus(enumEntry, enumEntry.status, containingClass, null, isLocal) { emptyList() } } 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 3a3aab338b3..2137f21ad35 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,10 +11,7 @@ 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.impl.* import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic @@ -141,7 +138,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor val initializerIsAlreadyResolved = bodyResolveState >= FirPropertyBodyResolveState.INITIALIZER_RESOLVED context.withProperty(property) { context.forPropertyInitializer { - property.transformBackingField(transformer, ResolutionMode.ContextDependent) property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate) if (!initializerIsAlreadyResolved) { property.transformChildrenWithoutComponents(returnTypeRef) @@ -150,6 +146,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor if (property.initializer != null) { storeVariableReturnType(property) } + property.transformBackingField(transformer, withExpectedType(property.returnTypeRef)) } // In case an explicit backing field declaration // is present, and the default accessors haven't @@ -188,12 +185,19 @@ 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 (fieldDeclaration.isSubtypeOf(this, typeCheckerContext)) { + if (getter == null && fieldDeclaration.isSubtypeOf(this, typeCheckerContext)) { this.replaceGetter( FirDefaultPropertyGetter( null, @@ -341,12 +345,16 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor if (variable.delegateFieldSymbol != null) { replacePropertyReferenceTypeInDelegateAccessors(variable) } + // This ensures there's no ImplicitTypeRef + // left in the backingField (witch is always present). + variable.transformBackingField(transformer, withExpectedType(variable.returnTypeRef)) } else { val resolutionMode = withExpectedType(variable.returnTypeRef) if (variable.initializer != null) { variable.transformInitializer(transformer, resolutionMode) storeVariableReturnType(variable) } + variable.transformBackingField(transformer, withExpectedType(variable.returnTypeRef)) variable.transformAccessors() } variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent) @@ -875,18 +883,22 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor backingField: FirBackingField, data: ResolutionMode, ): FirStatement { - if (backingField.returnTypeRef is FirErrorTypeRef) { - return backingField - } backingField.transformInitializer( transformer, withExpectedType(backingField.returnTypeRef) ) - if (backingField.returnTypeRef !is FirImplicitTypeRef) { + if ( + backingField.returnTypeRef is FirErrorTypeRef || + backingField.returnTypeRef is FirResolvedTypeRef + ) { return backingField } - val resultType = backingField.initializer - ?.unwrapSmartcastExpression()?.typeRef + val inferredType = if (backingField is FirDefaultPropertyBackingField) { + data.expectedType + } else { + backingField.initializer?.unwrapSmartcastExpression()?.typeRef + } + val resultType = inferredType ?: return backingField.transformReturnTypeRef( transformer, withExpectedType( @@ -1003,4 +1015,4 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor private val FirFunction.bodyResolved: Boolean get() = body !is FirLazyBlock && body?.typeRef is FirResolvedTypeRef -} +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt index 1ecdc8d3105..920c126bfad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirLocalScope.kt @@ -48,8 +48,14 @@ class FirLocalScope private constructor( } fun storeBackingField(property: FirProperty): FirLocalScope { + val enhancedProperties = property.backingField?.symbol?.let { + properties.put(BACKING_FIELD, it) + } + return FirLocalScope( - properties.put(BACKING_FIELD, property.backingFieldSymbol), functions, classes + enhancedProperties ?: properties, + functions, + classes ) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirBackingField.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirBackingField.kt index 020929f7fee..c91606eee9a 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirBackingField.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirBackingField.kt @@ -12,9 +12,11 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyFieldDeclarationSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.fir.visitors.* /* @@ -22,20 +24,30 @@ import org.jetbrains.kotlin.fir.visitors.* * DO NOT MODIFY IT MANUALLY */ -abstract class FirBackingField : FirTypedDeclaration(), FirTypeParametersOwner, FirStatement { +abstract class FirBackingField : FirVariable(), FirTypeParametersOwner, FirStatement { abstract override val source: FirSourceElement? abstract override val moduleData: FirModuleData abstract override val resolvePhase: FirResolvePhase abstract override val origin: FirDeclarationOrigin abstract override val attributes: FirDeclarationAttributes abstract override val returnTypeRef: FirTypeRef - abstract override val symbol: FirPropertyFieldDeclarationSymbol - abstract val backingFieldSymbol: FirBackingFieldSymbol? - abstract val propertySymbol: FirPropertySymbol? - abstract val initializer: FirExpression? + abstract override val receiverTypeRef: FirTypeRef? + abstract override val deprecation: DeprecationsPerUseSite? + abstract override val containerSource: DeserializedContainerSource? + abstract override val dispatchReceiverType: ConeKotlinType? + abstract override val name: Name + abstract override val delegate: FirExpression? + abstract override val isVar: Boolean + abstract override val isVal: Boolean + abstract override val getter: FirPropertyAccessor? + abstract override val setter: FirPropertyAccessor? + abstract override val backingField: FirBackingField? + abstract override val symbol: FirBackingFieldSymbol + abstract val propertySymbol: FirPropertySymbol + abstract override val initializer: FirExpression? abstract override val annotations: List abstract override val typeParameters: List - abstract val status: FirDeclarationStatus + abstract override val status: FirDeclarationStatus override fun accept(visitor: FirVisitor, data: D): R = visitor.visitBackingField(this, data) @@ -47,15 +59,35 @@ abstract class FirBackingField : FirTypedDeclaration(), FirTypeParametersOwner, abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) - abstract fun replaceInitializer(newInitializer: FirExpression?) + abstract override fun replaceReceiverTypeRef(newReceiverTypeRef: FirTypeRef?) + + abstract override fun replaceDeprecation(newDeprecation: DeprecationsPerUseSite?) + + abstract override fun replaceGetter(newGetter: FirPropertyAccessor?) + + abstract override fun replaceSetter(newSetter: FirPropertyAccessor?) + + abstract override fun replaceInitializer(newInitializer: FirExpression?) abstract override fun transformReturnTypeRef(transformer: FirTransformer, data: D): FirBackingField - abstract fun transformInitializer(transformer: FirTransformer, data: D): FirBackingField + abstract override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformDelegate(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformGetter(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformSetter(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformBackingField(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformInitializer(transformer: FirTransformer, data: D): FirBackingField abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirBackingField abstract override fun transformTypeParameters(transformer: FirTransformer, data: D): FirBackingField - abstract fun transformStatus(transformer: FirTransformer, data: D): FirBackingField + abstract override fun transformStatus(transformer: FirTransformer, data: D): FirBackingField + + abstract override fun transformOtherChildren(transformer: FirTransformer, data: D): FirBackingField } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt index a96b9f0e0ef..419008102ea 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirProperty.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference -import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType @@ -48,7 +47,6 @@ abstract class FirProperty : FirVariable(), FirTypeParametersOwner, FirControlFl abstract override val annotations: List abstract override val controlFlowGraphReference: FirControlFlowGraphReference? abstract override val symbol: FirPropertySymbol - abstract val backingFieldSymbol: FirBackingFieldSymbol abstract val delegateFieldSymbol: FirDelegateFieldSymbol? abstract val isLocal: Boolean abstract val bodyResolveState: FirPropertyBodyResolveState diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt index 449de655299..19ff5d14991 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirBackingFieldBuilder.kt @@ -6,24 +6,29 @@ package org.jetbrains.kotlin.fir.declarations.builder import kotlin.contracts.* +import org.jetbrains.kotlin.fir.FirImplementationDetail import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl +import org.jetbrains.kotlin.fir.declarations.DeprecationsPerUseSite import org.jetbrains.kotlin.fir.declarations.FirBackingField import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.impl.FirBackingFieldImpl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyFieldDeclarationSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.visitors.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource /* * This file was generated automatically @@ -38,14 +43,25 @@ class FirBackingFieldBuilder : FirAnnotationContainerBuilder { lateinit var origin: FirDeclarationOrigin var attributes: FirDeclarationAttributes = FirDeclarationAttributes() lateinit var returnTypeRef: FirTypeRef - lateinit var symbol: FirPropertyFieldDeclarationSymbol - var backingFieldSymbol: FirBackingFieldSymbol? = null - var propertySymbol: FirPropertySymbol? = null + var receiverTypeRef: FirTypeRef? = null + var deprecation: DeprecationsPerUseSite? = null + var containerSource: DeserializedContainerSource? = null + var dispatchReceiverType: ConeKotlinType? = null + lateinit var name: Name + var delegate: FirExpression? = null + var isVar: Boolean by kotlin.properties.Delegates.notNull() + var isVal: Boolean by kotlin.properties.Delegates.notNull() + var getter: FirPropertyAccessor? = null + var setter: FirPropertyAccessor? = null + var backingField: FirBackingField? = null + lateinit var symbol: FirBackingFieldSymbol + lateinit var propertySymbol: FirPropertySymbol var initializer: FirExpression? = null override val annotations: MutableList = mutableListOf() val typeParameters: MutableList = mutableListOf() lateinit var status: FirDeclarationStatus + @OptIn(FirImplementationDetail::class) override fun build(): FirBackingField { return FirBackingFieldImpl( source, @@ -54,8 +70,18 @@ class FirBackingFieldBuilder : FirAnnotationContainerBuilder { origin, attributes, returnTypeRef, + receiverTypeRef, + deprecation, + containerSource, + dispatchReceiverType, + name, + delegate, + isVar, + isVal, + getter, + setter, + backingField, symbol, - backingFieldSymbol, propertySymbol, initializer, annotations, diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt index 700470b4265..f7f641a37bf 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirBackingFieldImpl.kt @@ -5,20 +5,25 @@ package org.jetbrains.kotlin.fir.declarations.impl +import org.jetbrains.kotlin.fir.FirImplementationDetail import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.declarations.DeprecationsPerUseSite import org.jetbrains.kotlin.fir.declarations.FirBackingField import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyFieldDeclarationSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.fir.visitors.* /* @@ -26,7 +31,7 @@ import org.jetbrains.kotlin.fir.visitors.* * DO NOT MODIFY IT MANUALLY */ -internal class FirBackingFieldImpl( +open class FirBackingFieldImpl @FirImplementationDetail constructor( override val source: FirSourceElement?, override val moduleData: FirModuleData, @Volatile @@ -34,9 +39,19 @@ internal class FirBackingFieldImpl( override val origin: FirDeclarationOrigin, override val attributes: FirDeclarationAttributes, override var returnTypeRef: FirTypeRef, - override val symbol: FirPropertyFieldDeclarationSymbol, - override val backingFieldSymbol: FirBackingFieldSymbol?, - override val propertySymbol: FirPropertySymbol?, + override var receiverTypeRef: FirTypeRef?, + override var deprecation: DeprecationsPerUseSite?, + override val containerSource: DeserializedContainerSource?, + override val dispatchReceiverType: ConeKotlinType?, + override val name: Name, + override var delegate: FirExpression?, + override val isVar: Boolean, + override val isVal: Boolean, + override var getter: FirPropertyAccessor?, + override var setter: FirPropertyAccessor?, + override var backingField: FirBackingField?, + override val symbol: FirBackingFieldSymbol, + override val propertySymbol: FirPropertySymbol, override var initializer: FirExpression?, override val annotations: MutableList, override val typeParameters: MutableList, @@ -48,6 +63,11 @@ internal class FirBackingFieldImpl( override fun acceptChildren(visitor: FirVisitor, data: D) { returnTypeRef.accept(visitor, data) + receiverTypeRef?.accept(visitor, data) + delegate?.accept(visitor, data) + getter?.accept(visitor, data) + setter?.accept(visitor, data) + backingField?.accept(visitor, data) initializer?.accept(visitor, data) annotations.forEach { it.accept(visitor, data) } typeParameters.forEach { it.accept(visitor, data) } @@ -56,10 +76,15 @@ internal class FirBackingFieldImpl( override fun transformChildren(transformer: FirTransformer, data: D): FirBackingFieldImpl { transformReturnTypeRef(transformer, data) + transformReceiverTypeRef(transformer, data) + transformDelegate(transformer, data) + transformGetter(transformer, data) + transformSetter(transformer, data) + transformBackingField(transformer, data) transformInitializer(transformer, data) - transformAnnotations(transformer, data) transformTypeParameters(transformer, data) transformStatus(transformer, data) + transformOtherChildren(transformer, data) return this } @@ -68,6 +93,31 @@ internal class FirBackingFieldImpl( return this } + override fun transformReceiverTypeRef(transformer: FirTransformer, data: D): FirBackingFieldImpl { + receiverTypeRef = receiverTypeRef?.transform(transformer, data) + return this + } + + override fun transformDelegate(transformer: FirTransformer, data: D): FirBackingFieldImpl { + delegate = delegate?.transform(transformer, data) + return this + } + + override fun transformGetter(transformer: FirTransformer, data: D): FirBackingFieldImpl { + getter = getter?.transform(transformer, data) + return this + } + + override fun transformSetter(transformer: FirTransformer, data: D): FirBackingFieldImpl { + setter = setter?.transform(transformer, data) + return this + } + + override fun transformBackingField(transformer: FirTransformer, data: D): FirBackingFieldImpl { + backingField = backingField?.transform(transformer, data) + return this + } + override fun transformInitializer(transformer: FirTransformer, data: D): FirBackingFieldImpl { initializer = initializer?.transform(transformer, data) return this @@ -88,6 +138,11 @@ internal class FirBackingFieldImpl( return this } + override fun transformOtherChildren(transformer: FirTransformer, data: D): FirBackingFieldImpl { + transformAnnotations(transformer, data) + return this + } + override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { resolvePhase = newResolvePhase } @@ -96,6 +151,22 @@ internal class FirBackingFieldImpl( returnTypeRef = newReturnTypeRef } + override fun replaceReceiverTypeRef(newReceiverTypeRef: FirTypeRef?) { + receiverTypeRef = newReceiverTypeRef + } + + override fun replaceDeprecation(newDeprecation: DeprecationsPerUseSite?) { + deprecation = newDeprecation + } + + override fun replaceGetter(newGetter: FirPropertyAccessor?) { + getter = newGetter + } + + override fun replaceSetter(newSetter: FirPropertyAccessor?) { + setter = newSetter + } + override fun replaceInitializer(newInitializer: FirExpression?) { initializer = newInitializer } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt index 0f21addc54b..d79723d2d14 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirPropertyImpl.kt @@ -63,11 +63,9 @@ internal class FirPropertyImpl( ) : FirProperty() { override val isVal: Boolean get() = !isVar override var controlFlowGraphReference: FirControlFlowGraphReference? = null - override val backingFieldSymbol: FirBackingFieldSymbol = FirBackingFieldSymbol(symbol.callableId) init { symbol.bind(this) - backingFieldSymbol.bind(this) delegateFieldSymbol?.bind(this) } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 7a1183ad5b0..9341f611093 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -1074,7 +1074,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM override fun visitBackingFieldReference(backingFieldReference: FirBackingFieldReference) { print("F|") - print(backingFieldReference.resolvedSymbol.callableId) + print(backingFieldReference.resolvedSymbol.fir.propertySymbol.callableId) print("|") } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/comparators/FirMemberDeclarationComparator.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/comparators/FirMemberDeclarationComparator.kt index c4e87374176..eaae32ce341 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/comparators/FirMemberDeclarationComparator.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/comparators/FirMemberDeclarationComparator.kt @@ -25,6 +25,7 @@ object FirMemberDeclarationComparator : Comparator { is FirTypeAlias -> 1 is FirErrorProperty -> 0 is FirValueParameter -> 0 + is FirBackingField -> 0 } private val FirMemberDeclaration.name: Name diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyBackingField.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyBackingField.kt new file mode 100644 index 00000000000..baa730afad4 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/impl/FirDefaultPropertyBackingField.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.declarations.impl + +import org.jetbrains.kotlin.fir.FirImplementationDetail +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.builtins.StandardNames.BACKING_FIELD +import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin +import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.types.FirTypeRef +import org.jetbrains.kotlin.name.CallableId + +@OptIn(FirImplementationDetail::class) +class FirDefaultPropertyBackingField( + moduleData: FirModuleData, + annotations: MutableList, + returnTypeRef: FirTypeRef, + isVar: Boolean, + propertySymbol: FirPropertySymbol, + status: FirDeclarationStatus, +) : FirBackingFieldImpl( + source = null, + moduleData = moduleData, + resolvePhase = FirResolvePhase.BODY_RESOLVE, + origin = FirDeclarationOrigin.Synthetic, + attributes = FirDeclarationAttributes(), + returnTypeRef = returnTypeRef, + receiverTypeRef = null, + deprecation = null, + containerSource = null, + dispatchReceiverType = null, + name = BACKING_FIELD, + delegate = null, + isVar = isVar, + isVal = !isVar, + getter = null, + setter = null, + backingField = null, + symbol = FirBackingFieldSymbol(CallableId(BACKING_FIELD)), + propertySymbol = propertySymbol, + initializer = null, + annotations = annotations, + typeParameters = mutableListOf(), + status = status, +) + diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt index 0d70fa099a0..1e358dcd186 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/synthetic/FirSyntheticProperty.kt @@ -80,9 +80,6 @@ class FirSyntheticProperty( override val attributes: FirDeclarationAttributes = FirDeclarationAttributes() - // ??? - override val backingFieldSymbol: FirBackingFieldSymbol = FirBackingFieldSymbol(symbol.callableId) - override val bodyResolveState: FirPropertyBodyResolveState get() = FirPropertyBodyResolveState.EVERYTHING_RESOLVED diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/declarationAttributes.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/declarationAttributes.kt index 94087903895..9bbe99312f9 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/declarationAttributes.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/declarationAttributes.kt @@ -8,6 +8,10 @@ package org.jetbrains.kotlin.fir.declarations.utils import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyBackingField +import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.name.Name private object IsFromVarargKey : FirDeclarationDataKey() @@ -42,12 +46,30 @@ val FirMemberDeclaration.containerSource: SourceElement? is FirTypeAlias -> sourceElement } +val FirProperty.hasExplicitBackingField: Boolean + get() = backingField != null && backingField !is FirDefaultPropertyBackingField + +val FirPropertySymbol.hasExplicitBackingField: Boolean + get() = fir.hasExplicitBackingField + +fun FirProperty.getExplicitBackingField(): FirBackingField? { + return if (hasExplicitBackingField) { + backingField + } else { + null + } +} + +fun FirPropertySymbol.getExplicitBackingField(): FirBackingField? { + return fir.getExplicitBackingField() +} + // See [BindingContext.BACKING_FIELD_REQUIRED] val FirProperty.hasBackingField: Boolean get() { if (isAbstract) return false if (delegate != null) return false - if (backingField != null) return true + if (hasExplicitBackingField) return true when (origin) { FirDeclarationOrigin.SubstitutionOverride -> return false FirDeclarationOrigin.IntersectionOverride -> return false diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt index 8b70732d19b..c6c5d795401 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/symbols/impl/FirVariableSymbol.kt @@ -54,7 +54,7 @@ class FirIntersectionOverridePropertySymbol( override val intersections: Collection> ) : FirPropertySymbol(callableId), FirIntersectionCallableSymbol -class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) { +class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) { val isVal: Boolean get() = fir.isVal @@ -62,7 +62,7 @@ class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol(callableId) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt index d339752d951..5038e99f2d1 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/FirTreeBuilder.kt @@ -53,7 +53,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() { val contractDescriptionOwner = sealedElement("ContractDescriptionOwner", Declaration) val simpleFunction = element("SimpleFunction", Declaration, function, contractDescriptionOwner, typeParametersOwner) val propertyAccessor = element("PropertyAccessor", Declaration, function, contractDescriptionOwner, typeParametersOwner) - val backingField = element("BackingField", Declaration, typedDeclaration, typeParametersOwner, statement) + val backingField = element("BackingField", Declaration, variable, typeParametersOwner, statement) val constructor = element("Constructor", Declaration, function, typeParameterRefsOwner) val file = element("File", Declaration, annotatedDeclaration) val packageDirective = element("PackageDirective", Other) diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index c2de6d21a90..825ad5bd320 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -199,7 +199,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() withGetter = true } - default("backingFieldSymbol", "FirBackingFieldSymbol(symbol.callableId)") useTypes(backingFieldSymbolType, delegateFieldSymbolType) } @@ -332,6 +331,10 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() kind = OpenClass } + impl(backingField) { + kind = OpenClass + } + impl(whenSubjectExpression) { default("typeRef") { value = "whenRef.value.subject!!.typeRef" diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index 01622fde55a..df627e9b479 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -315,7 +315,6 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild property.configure { +symbol("FirPropertySymbol") - +field("backingFieldSymbol", backingFieldSymbolType) +field("delegateFieldSymbol", delegateFieldSymbolType, nullable = true) +booleanField("isLocal") +field("bodyResolveState", propertyBodyResolveStateType, withReplace = true) @@ -334,11 +333,8 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild } backingField.configure { - +symbol("FirPropertyFieldDeclarationSymbol") - +field("backingFieldSymbol", backingFieldSymbolType, nullable = true).apply { - withBindThis = false - } - +field("propertySymbol", firPropertySymbolType, nullable = true).apply { + +field("symbol", backingFieldSymbolType) + +field("propertySymbol", firPropertySymbolType).apply { withBindThis = false } +initializer.withTransform().withReplace() diff --git a/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt b/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt index edd8c7fff8b..8c26cc049a1 100644 --- a/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt +++ b/idea/idea-frontend-fir/idea-frontend-fir-generator/src/org/jetbrains/kotlin/idea/frontend/api/fir/generator/HLDiagnosticConverter.kt @@ -286,7 +286,7 @@ private object FirToKtConversionCreator { importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") ), FirBackingFieldSymbol::class to HLFunctionCallConversion( - "firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir)", + "firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir.propertySymbol.fir)", KtVariableSymbol::class.createType(), importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") ), diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt index c1adceda1be..ac52aac9bc7 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtSymbolByFirBuilder.kt @@ -290,11 +290,14 @@ internal class KtSymbolByFirBuilder private constructor( } fun buildBackingFieldSymbol(fir: FirBackingFieldSymbol): KtFirBackingFieldSymbol { - return backingFieldCache.cache(fir) { KtFirBackingFieldSymbol(fir.fir, resolveState, token, this@KtSymbolByFirBuilder) } + return backingFieldCache.cache(fir) { + KtFirBackingFieldSymbol(fir.fir.propertySymbol.fir, resolveState, token, this@KtSymbolByFirBuilder) + } } fun buildBackingFieldSymbolByProperty(fir: FirProperty): KtFirBackingFieldSymbol { - val backingFieldSymbol = fir.backingFieldSymbol + val backingFieldSymbol = fir.backingField?.symbol + ?: error("FirProperty backingField is null") return buildBackingFieldSymbol(backingFieldSymbol) } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 63e4169f606..17cfceffd5c 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -2719,14 +2719,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert } add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.errorFactory) { firDiagnostic -> ValReassignmentViaBackingFieldErrorImpl( - firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir), + firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir.propertySymbol.fir), firDiagnostic as FirPsiDiagnostic, token, ) } add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.warningFactory) { firDiagnostic -> ValReassignmentViaBackingFieldWarningImpl( - firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir), + firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir.propertySymbol.fir), firDiagnostic as FirPsiDiagnostic, token, )