[FIR] Merge FirPropertyFieldDeclarationSymbol into FirBackingFieldSymbol

This commit is contained in:
Nikolay Lunyak
2021-08-13 22:04:20 +03:00
committed by TeamCityServer
parent 1291f9e460
commit aefd6c30ad
32 changed files with 372 additions and 78 deletions
@@ -169,7 +169,7 @@ internal fun checkPropertyInitializer(
!isExpect && !isExpect &&
!isInitialized && !isInitialized &&
!isExternal && !isExternal &&
property.backingField == null !property.hasExplicitBackingField
) { ) {
if (property.receiverTypeRef != null && !property.hasAccessorImplementation) { if (property.receiverTypeRef != null && !property.hasAccessorImplementation) {
reporter.reportOn(propertySource, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context) reporter.reportOn(propertySource, FirErrors.EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT, context)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.declaration 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.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.EffectiveVisibility import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibilities
@@ -231,7 +232,12 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
source: FirSourceElement, source: FirSourceElement,
context: CheckerContext context: CheckerContext
) { ) {
if (calledDeclaration == null) return if (
calledDeclaration == null ||
calledDeclaration.callableId.callableName == BACKING_FIELD
) {
return
}
val recordedEffectiveVisibility = calledDeclaration.publishedApiEffectiveVisibility ?: calledDeclaration.effectiveVisibility val recordedEffectiveVisibility = calledDeclaration.publishedApiEffectiveVisibility ?: calledDeclaration.effectiveVisibility
val calledFunEffectiveVisibility = recordedEffectiveVisibility.let { val calledFunEffectiveVisibility = recordedEffectiveVisibility.let {
if (it == EffectiveVisibility.Local) { if (it == EffectiveVisibility.Local) {
@@ -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.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirProperty 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.expressions.FirErrorExpression
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.isSubtypeOf import org.jetbrains.kotlin.fir.types.isSubtypeOf
@@ -18,6 +19,10 @@ object FirPropertyFieldTypeChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) { override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
val backingField = declaration.backingField ?: return val backingField = declaration.backingField ?: return
if (!declaration.hasExplicitBackingField) {
return
}
val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false stubTypesEqualToAnything = false
@@ -197,7 +197,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall(declarationStorage: Fir2IrDecla
is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this) is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this)
is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this) is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this)
is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this)
is FirDelegateFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) is FirDelegateFieldSymbol -> declarationStorage.getIrDelegateFieldSymbol(this)
is FirVariableSymbol<*> -> declarationStorage.getIrValueSymbol(this) is FirVariableSymbol<*> -> declarationStorage.getIrValueSymbol(this)
else -> null else -> null
} }
@@ -1223,8 +1223,16 @@ class Fir2IrDeclarationStorage(
return irProperty.symbol return irProperty.symbol
} }
fun getIrBackingFieldSymbol(firVariableSymbol: FirVariableSymbol<*>): IrSymbol { fun getIrBackingFieldSymbol(firBackingFieldSymbol: FirBackingFieldSymbol): IrSymbol {
return when (val fir = firVariableSymbol.fir) { 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 -> { is FirProperty -> {
if (fir.isLocal) { if (fir.isLocal) {
return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir) return localStorage.getDelegatedProperty(fir)?.delegate?.symbol ?: getIrVariableSymbol(fir)
@@ -9,6 +9,7 @@ import com.intellij.lang.LighterASTNode
import com.intellij.psi.TokenType import com.intellij.psi.TokenType
import com.intellij.util.diff.FlyweightCapableTreeStructure import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.KtNodeTypes.* import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -1081,7 +1082,7 @@ class DeclarationsConverter(
typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, symbol) } typeParameterList?.let { firTypeParameters += convertTypeParameters(it, typeConstraints, symbol) }
backingField = fieldDeclaration.convertBackingField(symbol, modifiers) backingField = fieldDeclaration.convertBackingField(symbol, modifiers, returnType, isVar)
if (isLocal) { if (isLocal) {
this.isLocal = true this.isLocal = true
@@ -1131,7 +1132,7 @@ class DeclarationsConverter(
isExternal = modifiers.hasExternal() isExternal = modifiers.hasExternal()
} }
val hasExplicitBackingField = backingField != null val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField
val convertedAccessors = accessors.map { val convertedAccessors = accessors.map {
convertGetterOrSetter(it, returnType, propertyVisibility, symbol, modifiers, hasExplicitBackingField) convertGetterOrSetter(it, returnType, propertyVisibility, symbol, modifiers, hasExplicitBackingField)
} }
@@ -1355,7 +1356,9 @@ class DeclarationsConverter(
private fun LighterASTNode?.convertBackingField( private fun LighterASTNode?.convertBackingField(
propertySymbol: FirPropertySymbol, propertySymbol: FirPropertySymbol,
propertyModifiers: Modifier, propertyModifiers: Modifier,
): FirBackingField? { propertyReturnType: FirTypeRef,
isVar: Boolean,
): FirBackingField {
var modifiers = Modifier() var modifiers = Modifier()
var returnType: FirTypeRef = implicitType var returnType: FirTypeRef = implicitType
var initializerExpression: LighterASTNode? = null var initializerExpression: LighterASTNode? = null
@@ -1382,14 +1385,24 @@ class DeclarationsConverter(
moduleData = baseModuleData moduleData = baseModuleData
origin = FirDeclarationOrigin.Source origin = FirDeclarationOrigin.Source
returnTypeRef = returnType returnTypeRef = returnType
symbol = FirPropertyFieldDeclarationSymbol() name = StandardNames.BACKING_FIELD
symbol = FirBackingFieldSymbol(CallableId(name))
this.status = status this.status = status
annotations += modifiers.annotations annotations += modifiers.annotations
this.propertySymbol = propertySymbol this.propertySymbol = propertySymbol
this.initializer = backingFieldInitializer this.initializer = backingFieldInitializer
this.isVar = isVar
this.isVal = !isVar
} }
} else { } else {
null FirDefaultPropertyBackingField(
moduleData = baseModuleData,
annotations = modifiers.annotations,
returnTypeRef = propertyReturnType.copyWithNewSourceKind(FirFakeSourceElementKind.DefaultAccessor),
isVar = isVar,
propertySymbol = propertySymbol,
status = status,
)
} }
} }
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.builder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.tree.IElementType import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes 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.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -473,7 +474,8 @@ open class RawFirBuilder(
private fun KtBackingField?.toFirBackingField( private fun KtBackingField?.toFirBackingField(
property: KtProperty, property: KtProperty,
propertySymbol: FirPropertySymbol, propertySymbol: FirPropertySymbol,
): FirBackingField? { propertyReturnType: FirTypeRef,
): FirBackingField {
val componentVisibility = if (this?.visibility != null && this.visibility != Visibilities.Unknown) { val componentVisibility = if (this?.visibility != null && this.visibility != Visibilities.Unknown) {
this.visibility this.visibility
} else { } else {
@@ -497,12 +499,22 @@ open class RawFirBuilder(
returnTypeRef = returnType returnTypeRef = returnType
this.status = status this.status = status
extractAnnotationsTo(this) extractAnnotationsTo(this)
symbol = FirPropertyFieldDeclarationSymbol() name = BACKING_FIELD
symbol = FirBackingFieldSymbol(CallableId(name))
this.propertySymbol = propertySymbol this.propertySymbol = propertySymbol
this.initializer = backingFieldInitializer this.initializer = backingFieldInitializer
this.isVar = property.isVar
this.isVal = !property.isVar
} }
} else { } 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( backingField = this@toFirProperty.fieldDeclaration.toFirBackingField(
this@toFirProperty, this@toFirProperty,
propertySymbol = symbol, propertySymbol = symbol,
propertyType,
) )
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL).apply { status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL).apply {
@@ -1515,9 +1528,10 @@ open class RawFirBuilder(
backingField = this@toFirProperty.fieldDeclaration.toFirBackingField( backingField = this@toFirProperty.fieldDeclaration.toFirBackingField(
this@toFirProperty, this@toFirProperty,
propertySymbol = symbol, propertySymbol = symbol,
propertyType,
) )
val hasExplicitBackingField = backingField != null val hasExplicitBackingField = backingField !is FirDefaultPropertyBackingField
getter = this@toFirProperty.getter.toFirPropertyAccessor( getter = this@toFirProperty.getter.toFirPropertyAccessor(
this@toFirProperty, this@toFirProperty,
propertyType, propertyType,
@@ -721,7 +721,7 @@ class FirCallResolver(
val candidate = candidates.single() val candidate = candidates.single()
val coneSymbol = candidate.symbol val coneSymbol = candidate.symbol
if (coneSymbol is FirBackingFieldSymbol) { if (coneSymbol is FirBackingFieldSymbol) {
coneSymbol.fir.isReferredViaField = true coneSymbol.fir.propertySymbol.fir.isReferredViaField = true
return buildBackingFieldReference { return buildBackingFieldReference {
this.source = source this.source = source
resolvedSymbol = coneSymbol resolvedSymbol = coneSymbol
@@ -65,6 +65,12 @@ abstract class FirVisibilityChecker : FirSessionComponent {
val containingDeclarations = callInfo.containingDeclarations val containingDeclarations = callInfo.containingDeclarations
val session = callInfo.session 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) return isVisible(declaration, session, useSiteFile, containingDeclarations, candidate.dispatchReceiverValue)
} }
@@ -236,9 +236,12 @@ class ScopeTowerLevel(
} }
} }
val lookupTag = candidate.dispatchReceiverClassOrNull() if (candidate !is FirBackingFieldSymbol) {
return null
}
val lookupTag = candidate.fir.propertySymbol.dispatchReceiverClassOrNull()
return when { return when {
candidate !is FirBackingFieldSymbol -> null
lookupTag != null -> { lookupTag != null -> {
bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue -> bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver { implicitReceiverValue ->
(implicitReceiverValue.type as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag == lookupTag (implicitReceiverValue.type as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag == lookupTag
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.* 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.declarations.utils.isLocal
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.builder.buildAnonymousFunctionExpression import org.jetbrains.kotlin.fir.expressions.builder.buildAnonymousFunctionExpression
@@ -524,7 +526,7 @@ class ControlFlowGraphBuilder {
// ----------------------------------- Property ----------------------------------- // ----------------------------------- Property -----------------------------------
fun enterProperty(property: FirProperty): PropertyInitializerEnterNode? { 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) val graph = ControlFlowGraph(property, "val ${property.name}", ControlFlowGraph.Kind.PropertyInitializer)
pushGraph(graph, Mode.PropertyInitializer) pushGraph(graph, Mode.PropertyInitializer)
@@ -542,7 +544,7 @@ class ControlFlowGraphBuilder {
} }
fun exitProperty(property: FirProperty): Pair<PropertyInitializerExitNode, ControlFlowGraph>? { fun exitProperty(property: FirProperty): Pair<PropertyInitializerExitNode, ControlFlowGraph>? {
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 val exitNode = exitTargetsForTry.pop() as PropertyInitializerExitNode
popAndAddEdge(exitNode) popAndAddEdge(exitNode)
val graph = popGraph() val graph = popGraph()
@@ -467,6 +467,14 @@ abstract class AbstractFirStatusResolveTransformer(
property.getter?.let { transformPropertyAccessor(it, property) } property.getter?.let { transformPropertyAccessor(it, property) }
property.setter?.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) calculateDeprecations(property)
return property return property
} }
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl 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.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.declarations.utils.isExpect import org.jetbrains.kotlin.fir.declarations.utils.isExpect
@@ -58,6 +59,7 @@ class FirStatusResolver(
is FirTypeAlias -> resolveStatus(declaration, containingClass, isLocal) is FirTypeAlias -> resolveStatus(declaration, containingClass, isLocal)
is FirConstructor -> resolveStatus(declaration, containingClass, isLocal) is FirConstructor -> resolveStatus(declaration, containingClass, isLocal)
is FirField -> resolveStatus(declaration, containingClass, isLocal) is FirField -> resolveStatus(declaration, containingClass, isLocal)
is FirBackingField -> resolveStatus(declaration, containingClass, isLocal)
else -> error("Unsupported declaration type: ${declaration.render()}") else -> error("Unsupported declaration type: ${declaration.render()}")
} }
} }
@@ -133,6 +135,14 @@ class FirStatusResolver(
return resolveStatus(field, field.status, containingClass, null, isLocal) { emptyList() } 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 { fun resolveStatus(enumEntry: FirEnumEntry, containingClass: FirClass?, isLocal: Boolean): FirResolvedDeclarationStatus {
return resolveStatus(enumEntry, enumEntry.status, containingClass, null, isLocal) { emptyList() } return resolveStatus(enumEntry, enumEntry.status, containingClass, null, isLocal) { emptyList() }
} }
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl import org.jetbrains.kotlin.fir.declarations.impl.*
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.FirSyntheticProperty
import org.jetbrains.kotlin.fir.declarations.utils.* import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
@@ -141,7 +138,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
val initializerIsAlreadyResolved = bodyResolveState >= FirPropertyBodyResolveState.INITIALIZER_RESOLVED val initializerIsAlreadyResolved = bodyResolveState >= FirPropertyBodyResolveState.INITIALIZER_RESOLVED
context.withProperty(property) { context.withProperty(property) {
context.forPropertyInitializer { context.forPropertyInitializer {
property.transformBackingField(transformer, ResolutionMode.ContextDependent)
property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate) property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate)
if (!initializerIsAlreadyResolved) { if (!initializerIsAlreadyResolved) {
property.transformChildrenWithoutComponents(returnTypeRef) property.transformChildrenWithoutComponents(returnTypeRef)
@@ -150,6 +146,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
if (property.initializer != null) { if (property.initializer != null) {
storeVariableReturnType(property) storeVariableReturnType(property)
} }
property.transformBackingField(transformer, withExpectedType(property.returnTypeRef))
} }
// In case an explicit backing field declaration // In case an explicit backing field declaration
// is present, and the default accessors haven't // is present, and the default accessors haven't
@@ -188,12 +185,19 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
private fun FirProperty.generateMissingDefaultAccessors() { private fun FirProperty.generateMissingDefaultAccessors() {
val fieldDeclaration = backingField ?: return val fieldDeclaration = backingField ?: return
if (
!this.hasExplicitBackingField ||
fieldDeclaration.returnTypeRef !is FirResolvedTypeRef
) {
return
}
val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext( val typeCheckerContext = session.typeContext.newBaseTypeCheckerContext(
errorTypesEqualToAnything = false, errorTypesEqualToAnything = false,
stubTypesEqualToAnything = false stubTypesEqualToAnything = false
) )
if (fieldDeclaration.isSubtypeOf(this, typeCheckerContext)) { if (getter == null && fieldDeclaration.isSubtypeOf(this, typeCheckerContext)) {
this.replaceGetter( this.replaceGetter(
FirDefaultPropertyGetter( FirDefaultPropertyGetter(
null, null,
@@ -341,12 +345,16 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
if (variable.delegateFieldSymbol != null) { if (variable.delegateFieldSymbol != null) {
replacePropertyReferenceTypeInDelegateAccessors(variable) replacePropertyReferenceTypeInDelegateAccessors(variable)
} }
// This ensures there's no ImplicitTypeRef
// left in the backingField (witch is always present).
variable.transformBackingField(transformer, withExpectedType(variable.returnTypeRef))
} else { } else {
val resolutionMode = withExpectedType(variable.returnTypeRef) val resolutionMode = withExpectedType(variable.returnTypeRef)
if (variable.initializer != null) { if (variable.initializer != null) {
variable.transformInitializer(transformer, resolutionMode) variable.transformInitializer(transformer, resolutionMode)
storeVariableReturnType(variable) storeVariableReturnType(variable)
} }
variable.transformBackingField(transformer, withExpectedType(variable.returnTypeRef))
variable.transformAccessors() variable.transformAccessors()
} }
variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent) variable.transformOtherChildren(transformer, ResolutionMode.ContextIndependent)
@@ -875,18 +883,22 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
backingField: FirBackingField, backingField: FirBackingField,
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement {
if (backingField.returnTypeRef is FirErrorTypeRef) {
return backingField
}
backingField.transformInitializer( backingField.transformInitializer(
transformer, transformer,
withExpectedType(backingField.returnTypeRef) withExpectedType(backingField.returnTypeRef)
) )
if (backingField.returnTypeRef !is FirImplicitTypeRef) { if (
backingField.returnTypeRef is FirErrorTypeRef ||
backingField.returnTypeRef is FirResolvedTypeRef
) {
return backingField return backingField
} }
val resultType = backingField.initializer val inferredType = if (backingField is FirDefaultPropertyBackingField) {
?.unwrapSmartcastExpression()?.typeRef data.expectedType
} else {
backingField.initializer?.unwrapSmartcastExpression()?.typeRef
}
val resultType = inferredType
?: return backingField.transformReturnTypeRef( ?: return backingField.transformReturnTypeRef(
transformer, transformer,
withExpectedType( withExpectedType(
@@ -48,8 +48,14 @@ class FirLocalScope private constructor(
} }
fun storeBackingField(property: FirProperty): FirLocalScope { fun storeBackingField(property: FirProperty): FirLocalScope {
val enhancedProperties = property.backingField?.symbol?.let {
properties.put(BACKING_FIELD, it)
}
return FirLocalScope( return FirLocalScope(
properties.put(BACKING_FIELD, property.backingFieldSymbol), functions, classes enhancedProperties ?: properties,
functions,
classes
) )
} }
@@ -12,9 +12,11 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol 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.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef 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.* import org.jetbrains.kotlin.fir.visitors.*
/* /*
@@ -22,20 +24,30 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY * 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 source: FirSourceElement?
abstract override val moduleData: FirModuleData abstract override val moduleData: FirModuleData
abstract override val resolvePhase: FirResolvePhase abstract override val resolvePhase: FirResolvePhase
abstract override val origin: FirDeclarationOrigin abstract override val origin: FirDeclarationOrigin
abstract override val attributes: FirDeclarationAttributes abstract override val attributes: FirDeclarationAttributes
abstract override val returnTypeRef: FirTypeRef abstract override val returnTypeRef: FirTypeRef
abstract override val symbol: FirPropertyFieldDeclarationSymbol abstract override val receiverTypeRef: FirTypeRef?
abstract val backingFieldSymbol: FirBackingFieldSymbol? abstract override val deprecation: DeprecationsPerUseSite?
abstract val propertySymbol: FirPropertySymbol? abstract override val containerSource: DeserializedContainerSource?
abstract val initializer: FirExpression? 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<FirAnnotationCall> abstract override val annotations: List<FirAnnotationCall>
abstract override val typeParameters: List<FirTypeParameter> abstract override val typeParameters: List<FirTypeParameter>
abstract val status: FirDeclarationStatus abstract override val status: FirDeclarationStatus
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitBackingField(this, data) override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitBackingField(this, data)
@@ -47,15 +59,35 @@ abstract class FirBackingField : FirTypedDeclaration(), FirTypeParametersOwner,
abstract override fun replaceReturnTypeRef(newReturnTypeRef: FirTypeRef) 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 <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D): FirBackingField abstract override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D): FirBackingField
abstract fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirBackingField abstract override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformDelegate(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformBackingField(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirBackingField abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirBackingField abstract override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirBackingField
abstract fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirBackingField abstract override fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirBackingField
abstract override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBackingField
} }
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference 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.FirDelegateFieldSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -48,7 +47,6 @@ abstract class FirProperty : FirVariable(), FirTypeParametersOwner, FirControlFl
abstract override val annotations: List<FirAnnotationCall> abstract override val annotations: List<FirAnnotationCall>
abstract override val controlFlowGraphReference: FirControlFlowGraphReference? abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
abstract override val symbol: FirPropertySymbol abstract override val symbol: FirPropertySymbol
abstract val backingFieldSymbol: FirBackingFieldSymbol
abstract val delegateFieldSymbol: FirDelegateFieldSymbol? abstract val delegateFieldSymbol: FirDelegateFieldSymbol?
abstract val isLocal: Boolean abstract val isLocal: Boolean
abstract val bodyResolveState: FirPropertyBodyResolveState abstract val bodyResolveState: FirPropertyBodyResolveState
@@ -6,24 +6,29 @@
package org.jetbrains.kotlin.fir.declarations.builder package org.jetbrains.kotlin.fir.declarations.builder
import kotlin.contracts.* import kotlin.contracts.*
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl 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.FirBackingField
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus 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.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.declarations.impl.FirBackingFieldImpl import org.jetbrains.kotlin.fir.declarations.impl.FirBackingFieldImpl
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol 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.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.visitors.* 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 * This file was generated automatically
@@ -38,14 +43,25 @@ class FirBackingFieldBuilder : FirAnnotationContainerBuilder {
lateinit var origin: FirDeclarationOrigin lateinit var origin: FirDeclarationOrigin
var attributes: FirDeclarationAttributes = FirDeclarationAttributes() var attributes: FirDeclarationAttributes = FirDeclarationAttributes()
lateinit var returnTypeRef: FirTypeRef lateinit var returnTypeRef: FirTypeRef
lateinit var symbol: FirPropertyFieldDeclarationSymbol var receiverTypeRef: FirTypeRef? = null
var backingFieldSymbol: FirBackingFieldSymbol? = null var deprecation: DeprecationsPerUseSite? = null
var propertySymbol: FirPropertySymbol? = 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<Boolean>()
var isVal: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
var getter: FirPropertyAccessor? = null
var setter: FirPropertyAccessor? = null
var backingField: FirBackingField? = null
lateinit var symbol: FirBackingFieldSymbol
lateinit var propertySymbol: FirPropertySymbol
var initializer: FirExpression? = null var initializer: FirExpression? = null
override val annotations: MutableList<FirAnnotationCall> = mutableListOf() override val annotations: MutableList<FirAnnotationCall> = mutableListOf()
val typeParameters: MutableList<FirTypeParameter> = mutableListOf() val typeParameters: MutableList<FirTypeParameter> = mutableListOf()
lateinit var status: FirDeclarationStatus lateinit var status: FirDeclarationStatus
@OptIn(FirImplementationDetail::class)
override fun build(): FirBackingField { override fun build(): FirBackingField {
return FirBackingFieldImpl( return FirBackingFieldImpl(
source, source,
@@ -54,8 +70,18 @@ class FirBackingFieldBuilder : FirAnnotationContainerBuilder {
origin, origin,
attributes, attributes,
returnTypeRef, returnTypeRef,
receiverTypeRef,
deprecation,
containerSource,
dispatchReceiverType,
name,
delegate,
isVar,
isVal,
getter,
setter,
backingField,
symbol, symbol,
backingFieldSymbol,
propertySymbol, propertySymbol,
initializer, initializer,
annotations, annotations,
@@ -5,20 +5,25 @@
package org.jetbrains.kotlin.fir.declarations.impl package org.jetbrains.kotlin.fir.declarations.impl
import org.jetbrains.kotlin.fir.FirImplementationDetail
import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement 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.FirBackingField
import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.FirDeclarationStatus 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.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.impl.FirBackingFieldSymbol 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.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.FirTypeRef 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.* import org.jetbrains.kotlin.fir.visitors.*
/* /*
@@ -26,7 +31,7 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY * DO NOT MODIFY IT MANUALLY
*/ */
internal class FirBackingFieldImpl( open class FirBackingFieldImpl @FirImplementationDetail constructor(
override val source: FirSourceElement?, override val source: FirSourceElement?,
override val moduleData: FirModuleData, override val moduleData: FirModuleData,
@Volatile @Volatile
@@ -34,9 +39,19 @@ internal class FirBackingFieldImpl(
override val origin: FirDeclarationOrigin, override val origin: FirDeclarationOrigin,
override val attributes: FirDeclarationAttributes, override val attributes: FirDeclarationAttributes,
override var returnTypeRef: FirTypeRef, override var returnTypeRef: FirTypeRef,
override val symbol: FirPropertyFieldDeclarationSymbol, override var receiverTypeRef: FirTypeRef?,
override val backingFieldSymbol: FirBackingFieldSymbol?, override var deprecation: DeprecationsPerUseSite?,
override val propertySymbol: FirPropertySymbol?, 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 var initializer: FirExpression?,
override val annotations: MutableList<FirAnnotationCall>, override val annotations: MutableList<FirAnnotationCall>,
override val typeParameters: MutableList<FirTypeParameter>, override val typeParameters: MutableList<FirTypeParameter>,
@@ -48,6 +63,11 @@ internal class FirBackingFieldImpl(
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) { override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
returnTypeRef.accept(visitor, data) 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) initializer?.accept(visitor, data)
annotations.forEach { it.accept(visitor, data) } annotations.forEach { it.accept(visitor, data) }
typeParameters.forEach { it.accept(visitor, data) } typeParameters.forEach { it.accept(visitor, data) }
@@ -56,10 +76,15 @@ internal class FirBackingFieldImpl(
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl { override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
transformReturnTypeRef(transformer, data) transformReturnTypeRef(transformer, data)
transformReceiverTypeRef(transformer, data)
transformDelegate(transformer, data)
transformGetter(transformer, data)
transformSetter(transformer, data)
transformBackingField(transformer, data)
transformInitializer(transformer, data) transformInitializer(transformer, data)
transformAnnotations(transformer, data)
transformTypeParameters(transformer, data) transformTypeParameters(transformer, data)
transformStatus(transformer, data) transformStatus(transformer, data)
transformOtherChildren(transformer, data)
return this return this
} }
@@ -68,6 +93,31 @@ internal class FirBackingFieldImpl(
return this return this
} }
override fun <D> transformReceiverTypeRef(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
receiverTypeRef = receiverTypeRef?.transform(transformer, data)
return this
}
override fun <D> transformDelegate(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
delegate = delegate?.transform(transformer, data)
return this
}
override fun <D> transformGetter(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
getter = getter?.transform(transformer, data)
return this
}
override fun <D> transformSetter(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
setter = setter?.transform(transformer, data)
return this
}
override fun <D> transformBackingField(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
backingField = backingField?.transform(transformer, data)
return this
}
override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl { override fun <D> transformInitializer(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
initializer = initializer?.transform(transformer, data) initializer = initializer?.transform(transformer, data)
return this return this
@@ -88,6 +138,11 @@ internal class FirBackingFieldImpl(
return this return this
} }
override fun <D> transformOtherChildren(transformer: FirTransformer<D>, data: D): FirBackingFieldImpl {
transformAnnotations(transformer, data)
return this
}
override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) { override fun replaceResolvePhase(newResolvePhase: FirResolvePhase) {
resolvePhase = newResolvePhase resolvePhase = newResolvePhase
} }
@@ -96,6 +151,22 @@ internal class FirBackingFieldImpl(
returnTypeRef = newReturnTypeRef 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?) { override fun replaceInitializer(newInitializer: FirExpression?) {
initializer = newInitializer initializer = newInitializer
} }
@@ -63,11 +63,9 @@ internal class FirPropertyImpl(
) : FirProperty() { ) : FirProperty() {
override val isVal: Boolean get() = !isVar override val isVal: Boolean get() = !isVar
override var controlFlowGraphReference: FirControlFlowGraphReference? = null override var controlFlowGraphReference: FirControlFlowGraphReference? = null
override val backingFieldSymbol: FirBackingFieldSymbol = FirBackingFieldSymbol(symbol.callableId)
init { init {
symbol.bind(this) symbol.bind(this)
backingFieldSymbol.bind(this)
delegateFieldSymbol?.bind(this) delegateFieldSymbol?.bind(this)
} }
@@ -1074,7 +1074,7 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
override fun visitBackingFieldReference(backingFieldReference: FirBackingFieldReference) { override fun visitBackingFieldReference(backingFieldReference: FirBackingFieldReference) {
print("F|") print("F|")
print(backingFieldReference.resolvedSymbol.callableId) print(backingFieldReference.resolvedSymbol.fir.propertySymbol.callableId)
print("|") print("|")
} }
@@ -25,6 +25,7 @@ object FirMemberDeclarationComparator : Comparator<FirMemberDeclaration> {
is FirTypeAlias -> 1 is FirTypeAlias -> 1
is FirErrorProperty -> 0 is FirErrorProperty -> 0
is FirValueParameter -> 0 is FirValueParameter -> 0
is FirBackingField -> 0
} }
private val FirMemberDeclaration.name: Name private val FirMemberDeclaration.name: Name
@@ -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<FirAnnotationCall>,
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,
)
@@ -80,9 +80,6 @@ class FirSyntheticProperty(
override val attributes: FirDeclarationAttributes = FirDeclarationAttributes() override val attributes: FirDeclarationAttributes = FirDeclarationAttributes()
// ???
override val backingFieldSymbol: FirBackingFieldSymbol = FirBackingFieldSymbol(symbol.callableId)
override val bodyResolveState: FirPropertyBodyResolveState override val bodyResolveState: FirPropertyBodyResolveState
get() = FirPropertyBodyResolveState.EVERYTHING_RESOLVED get() = FirPropertyBodyResolveState.EVERYTHING_RESOLVED
@@ -8,6 +8,10 @@ package org.jetbrains.kotlin.fir.declarations.utils
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.declarations.* 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 import org.jetbrains.kotlin.name.Name
private object IsFromVarargKey : FirDeclarationDataKey() private object IsFromVarargKey : FirDeclarationDataKey()
@@ -42,12 +46,30 @@ val FirMemberDeclaration.containerSource: SourceElement?
is FirTypeAlias -> 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] // See [BindingContext.BACKING_FIELD_REQUIRED]
val FirProperty.hasBackingField: Boolean val FirProperty.hasBackingField: Boolean
get() { get() {
if (isAbstract) return false if (isAbstract) return false
if (delegate != null) return false if (delegate != null) return false
if (backingField != null) return true if (hasExplicitBackingField) return true
when (origin) { when (origin) {
FirDeclarationOrigin.SubstitutionOverride -> return false FirDeclarationOrigin.SubstitutionOverride -> return false
FirDeclarationOrigin.IntersectionOverride -> return false FirDeclarationOrigin.IntersectionOverride -> return false
@@ -54,7 +54,7 @@ class FirIntersectionOverridePropertySymbol(
override val intersections: Collection<FirCallableSymbol<*>> override val intersections: Collection<FirCallableSymbol<*>>
) : FirPropertySymbol(callableId), FirIntersectionCallableSymbol ) : FirPropertySymbol(callableId), FirIntersectionCallableSymbol
class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirProperty>(callableId) { class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirBackingField>(callableId) {
val isVal: Boolean val isVal: Boolean
get() = fir.isVal get() = fir.isVal
@@ -62,7 +62,7 @@ class FirBackingFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirPrope
get() = fir.isVar get() = fir.isVar
val getterSymbol: FirPropertyAccessorSymbol? val getterSymbol: FirPropertyAccessorSymbol?
get() = fir.getter?.symbol get() = fir.propertySymbol.fir.getter?.symbol
} }
class FirDelegateFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirProperty>(callableId) class FirDelegateFieldSymbol(callableId: CallableId) : FirVariableSymbol<FirProperty>(callableId)
@@ -53,7 +53,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val contractDescriptionOwner = sealedElement("ContractDescriptionOwner", Declaration) val contractDescriptionOwner = sealedElement("ContractDescriptionOwner", Declaration)
val simpleFunction = element("SimpleFunction", Declaration, function, contractDescriptionOwner, typeParametersOwner) val simpleFunction = element("SimpleFunction", Declaration, function, contractDescriptionOwner, typeParametersOwner)
val propertyAccessor = element("PropertyAccessor", 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 constructor = element("Constructor", Declaration, function, typeParameterRefsOwner)
val file = element("File", Declaration, annotatedDeclaration) val file = element("File", Declaration, annotatedDeclaration)
val packageDirective = element("PackageDirective", Other) val packageDirective = element("PackageDirective", Other)
@@ -199,7 +199,6 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
withGetter = true withGetter = true
} }
default("backingFieldSymbol", "FirBackingFieldSymbol(symbol.callableId)")
useTypes(backingFieldSymbolType, delegateFieldSymbolType) useTypes(backingFieldSymbolType, delegateFieldSymbolType)
} }
@@ -332,6 +331,10 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
kind = OpenClass kind = OpenClass
} }
impl(backingField) {
kind = OpenClass
}
impl(whenSubjectExpression) { impl(whenSubjectExpression) {
default("typeRef") { default("typeRef") {
value = "whenRef.value.subject!!.typeRef" value = "whenRef.value.subject!!.typeRef"
@@ -315,7 +315,6 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
property.configure { property.configure {
+symbol("FirPropertySymbol") +symbol("FirPropertySymbol")
+field("backingFieldSymbol", backingFieldSymbolType)
+field("delegateFieldSymbol", delegateFieldSymbolType, nullable = true) +field("delegateFieldSymbol", delegateFieldSymbolType, nullable = true)
+booleanField("isLocal") +booleanField("isLocal")
+field("bodyResolveState", propertyBodyResolveStateType, withReplace = true) +field("bodyResolveState", propertyBodyResolveStateType, withReplace = true)
@@ -334,11 +333,8 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
} }
backingField.configure { backingField.configure {
+symbol("FirPropertyFieldDeclarationSymbol") +field("symbol", backingFieldSymbolType)
+field("backingFieldSymbol", backingFieldSymbolType, nullable = true).apply { +field("propertySymbol", firPropertySymbolType).apply {
withBindThis = false
}
+field("propertySymbol", firPropertySymbolType, nullable = true).apply {
withBindThis = false withBindThis = false
} }
+initializer.withTransform().withReplace() +initializer.withTransform().withReplace()
@@ -286,7 +286,7 @@ private object FirToKtConversionCreator {
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
), ),
FirBackingFieldSymbol::class to HLFunctionCallConversion( FirBackingFieldSymbol::class to HLFunctionCallConversion(
"firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir)", "firSymbolBuilder.variableLikeBuilder.buildVariableSymbol({0}.fir.propertySymbol.fir)",
KtVariableSymbol::class.createType(), KtVariableSymbol::class.createType(),
importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty") importsToAdd = listOf("org.jetbrains.kotlin.fir.declarations.FirProperty")
), ),
@@ -290,11 +290,14 @@ internal class KtSymbolByFirBuilder private constructor(
} }
fun buildBackingFieldSymbol(fir: FirBackingFieldSymbol): KtFirBackingFieldSymbol { 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 { fun buildBackingFieldSymbolByProperty(fir: FirProperty): KtFirBackingFieldSymbol {
val backingFieldSymbol = fir.backingFieldSymbol val backingFieldSymbol = fir.backingField?.symbol
?: error("FirProperty backingField is null")
return buildBackingFieldSymbol(backingFieldSymbol) return buildBackingFieldSymbol(backingFieldSymbol)
} }
@@ -2719,14 +2719,14 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
} }
add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.errorFactory) { firDiagnostic -> add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.errorFactory) { firDiagnostic ->
ValReassignmentViaBackingFieldErrorImpl( ValReassignmentViaBackingFieldErrorImpl(
firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir), firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir.propertySymbol.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )
} }
add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.warningFactory) { firDiagnostic -> add(FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD.warningFactory) { firDiagnostic ->
ValReassignmentViaBackingFieldWarningImpl( ValReassignmentViaBackingFieldWarningImpl(
firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir), firSymbolBuilder.variableLikeBuilder.buildVariableSymbol(firDiagnostic.a.fir.propertySymbol.fir),
firDiagnostic as FirPsiDiagnostic, firDiagnostic as FirPsiDiagnostic,
token, token,
) )