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 99e3d79873b..82451ce0a3e 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 @@ -550,7 +550,7 @@ class Fir2IrDeclarationStorage( if (irParent != null) { parent = irParent } - if (!isFakeOverride && thisReceiverOwner != null) { + if (correspondingProperty is Fir2IrLazyProperty && !isFakeOverride && thisReceiverOwner != null) { populateOverriddenSymbols(thisReceiverOwner) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 1a5f3d2fae0..1b3192a64fb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -264,7 +264,7 @@ class Fir2IrVisitor( if (property.isLocal) return visitLocalVariable(property) val irProperty = declarationStorage.getCachedIrProperty(property)!! return conversionScope.withProperty(irProperty) { - memberGenerator.convertPropertyContent(irProperty, property) + memberGenerator.convertPropertyContent(irProperty, property, containingClass = conversionScope.containerFirClass()) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index 58310aa7d2d..dfa4e979c2d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.util.* @@ -188,17 +189,23 @@ internal class ClassMemberGenerator( return irFunction } - fun convertPropertyContent(irProperty: IrProperty, property: FirProperty): IrProperty { + fun convertPropertyContent(irProperty: IrProperty, property: FirProperty, containingClass: FirClass<*>?): IrProperty { val initializer = property.initializer val delegate = property.delegate val propertyType = property.returnTypeRef.toIrType() irProperty.initializeBackingField(property, initializerExpression = initializer ?: delegate) irProperty.getter?.setPropertyAccessorContent( - property, property.getter, irProperty, propertyType, property.getter is FirDefaultPropertyGetter + property, property.getter, irProperty, propertyType, + property.getter is FirDefaultPropertyGetter, + isGetter = true, + containingClass = containingClass ) if (property.isVar) { irProperty.setter?.setPropertyAccessorContent( - property, property.setter, irProperty, propertyType, property.setter is FirDefaultPropertySetter + property, property.setter, irProperty, propertyType, + property.setter is FirDefaultPropertySetter, + isGetter = false, + containingClass = containingClass ) } annotationGenerator.generate(irProperty, property) @@ -221,12 +228,14 @@ internal class ClassMemberGenerator( annotationGenerator.generate(irField, property) } - private fun IrFunction.setPropertyAccessorContent( + private fun IrSimpleFunction.setPropertyAccessorContent( property: FirProperty, propertyAccessor: FirPropertyAccessor?, correspondingProperty: IrProperty, propertyType: IrType, - isDefault: Boolean + isDefault: Boolean, + isGetter: Boolean, + containingClass: FirClass<*>? ) { conversionScope.withFunction(this) { applyParentFromStackTo(this) @@ -258,6 +267,28 @@ internal class ClassMemberGenerator( declarationStorage.leaveScope(this) } } + if (containingClass != null) { + val scope = containingClass.unsubstitutedScope(session, scopeSession) + scope.processPropertiesByName(property.name) {} + val overriddenSet = mutableSetOf() + scope.processDirectlyOverriddenProperties(property.symbol) { + if (it.fir.visibility == Visibilities.PRIVATE) { + return@processDirectlyOverriddenProperties ProcessorAction.NEXT + } + val overridden = declarationStorage.getIrPropertyOrFieldSymbol(it) + if (overridden is IrPropertySymbol) { + val accessorSymbol = + if (isGetter) overridden.owner.getter?.symbol + else overridden.owner.setter?.symbol + if (accessorSymbol != null) { + overriddenSet += accessorSymbol + } + } + ProcessorAction.NEXT + } + this.overriddenSymbols = overriddenSet.toList() + } + } annotationGenerator.generate(this, property) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt index 721edb15731..46a21de6c49 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassMembersEnhancementScope.kt @@ -21,15 +21,26 @@ class JavaClassMembersEnhancementScope( private val useSiteMemberScope: JavaClassUseSiteMemberScope, ) : FirTypeScope() { private val overriddenFunctions = mutableMapOf, Collection>>() + private val overriddenProperties = mutableMapOf>() private val overrideBindCache = mutableMapOf?, List>>>() private val signatureEnhancement = FirSignatureEnhancement(owner.fir, session) { - overriddenMembers() + overriddenMembers(name) } override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) { useSiteMemberScope.processPropertiesByName(name) process@{ original -> - processor(signatureEnhancement.enhancedProperty(original, name)) + val enhancedPropertySymbol = signatureEnhancement.enhancedProperty(original, name) + + if (enhancedPropertySymbol is FirPropertySymbol) { + val enhancedProperty = enhancedPropertySymbol.fir + overriddenProperties[enhancedPropertySymbol] = + enhancedProperty + .overriddenMembers(enhancedProperty.name) + .mapNotNull { it.symbol as? FirPropertySymbol } + } + + processor(enhancedPropertySymbol) } return super.processPropertiesByName(name, processor) @@ -37,23 +48,24 @@ class JavaClassMembersEnhancementScope( override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { useSiteMemberScope.processFunctionsByName(name) process@{ original -> - val enhancedFunction = signatureEnhancement.enhancedFunction(original, name) + val enhancedFunctionSymbol = signatureEnhancement.enhancedFunction(original, name) + val enhancedFunction = enhancedFunctionSymbol.fir as? FirSimpleFunction - overriddenFunctions[enhancedFunction] = - (enhancedFunction.fir as? FirSimpleFunction) - ?.overriddenMembers() + overriddenFunctions[enhancedFunctionSymbol] = + enhancedFunction + ?.overriddenMembers(enhancedFunction.name) ?.mapNotNull { it.symbol as? FirFunctionSymbol<*> } .orEmpty() - processor(enhancedFunction) + processor(enhancedFunctionSymbol) } return super.processFunctionsByName(name, processor) } - private fun FirSimpleFunction.overriddenMembers(): List> { - val backMap = overrideBindCache.getOrPut(this.name) { - useSiteMemberScope.bindOverrides(this.name) + private fun FirCallableMemberDeclaration<*>.overriddenMembers(name: Name): List> { + val backMap = overrideBindCache.getOrPut(name) { + useSiteMemberScope.bindOverrides(name) useSiteMemberScope .overrideByBase .toList() @@ -76,5 +88,16 @@ class JavaClassMembersEnhancementScope( override fun processOverriddenFunctionsWithDepth( functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction - ): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, overriddenFunctions, useSiteMemberScope) + ): ProcessorAction = doProcessOverriddenCallables( + functionSymbol, processor, overriddenFunctions, useSiteMemberScope, + FirTypeScope::processOverriddenFunctionsWithDepth + ) + + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction = doProcessOverriddenCallables( + propertySymbol, processor, overriddenProperties, useSiteMemberScope, + FirTypeScope::processOverriddenPropertiesWithDepth + ) } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt index 7656e307673..df40751d561 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/scopes/JavaClassUseSiteMemberScope.kt @@ -109,6 +109,9 @@ class JavaClassUseSiteMemberScope( when (val overriddenBy = it.getOverridden(overrideCandidates)) { null -> processor(it) is FirAccessorSymbol -> processor(overriddenBy) + is FirPropertySymbol -> if (it is FirPropertySymbol) { + directOverriddenProperties.getOrPut(overriddenBy) { mutableListOf() }.add(it) + } } } } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt index 20d9c477925..83e9ea2237c 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/scopes/jvm/JvmMappedScope.kt @@ -11,10 +11,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction -import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.name.Name class JvmMappedScope( @@ -70,6 +67,11 @@ class JvmMappedScope( declaredMemberScope.processPropertiesByName(name, processor) } + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction = ProcessorAction.NONE + override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt index a528669812c..b2a1f6b9238 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirOverrideScope.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.builder.FirPropertyBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirSimpleFunctionBuilder import org.jetbrains.kotlin.fir.declarations.builder.FirValueParameterBuilder import org.jetbrains.kotlin.fir.expressions.FirExpression @@ -16,6 +17,7 @@ import org.jetbrains.kotlin.fir.scopes.FirOverrideChecker import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol abstract class AbstractFirOverrideScope( @@ -92,4 +94,23 @@ abstract class AbstractFirOverrideScope( isVararg = parameter.isVararg } + protected open fun createPropertyCopy( + firProperty: FirProperty, + newSymbol: FirPropertySymbol + ): FirPropertyBuilder = + FirPropertyBuilder().apply { + source = firProperty.source + session = firProperty.session + origin = FirDeclarationOrigin.FakeOverride + returnTypeRef = firProperty.returnTypeRef + receiverTypeRef = firProperty.receiverTypeRef + isVar = firProperty.isVar + isLocal = firProperty.isLocal + getter = firProperty.getter + setter = firProperty.setter + name = firProperty.name + status = firProperty.status + symbol = newSymbol + } + } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt index ae28fc07eca..701dd1620a5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/AbstractFirUseSiteMemberScope.kt @@ -24,7 +24,8 @@ abstract class AbstractFirUseSiteMemberScope( ) : AbstractFirOverrideScope(session, overrideChecker) { private val functions = hashMapOf>>() - private val directOverridden = hashMapOf, Collection>>() + private val directOverriddenFunctions = hashMapOf, Collection>>() + protected val directOverriddenProperties = hashMapOf>() override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { functions.getOrPut(name) { @@ -41,7 +42,7 @@ abstract class AbstractFirUseSiteMemberScope( declaredMemberScope.processFunctionsByName(name) { if (it.isStatic) return@processFunctionsByName val directOverridden = computeDirectOverridden(it) - this@AbstractFirUseSiteMemberScope.directOverridden[it] = directOverridden + this@AbstractFirUseSiteMemberScope.directOverriddenFunctions[it] = directOverridden val symbol = processInheritedDefaultParameters(it, directOverridden) overrideCandidates += symbol add(symbol) @@ -106,7 +107,20 @@ abstract class AbstractFirUseSiteMemberScope( override fun processOverriddenFunctionsWithDepth( functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction - ): ProcessorAction = doProcessOverriddenFunctions(functionSymbol, processor, directOverridden, superTypesScope) + ): ProcessorAction = + doProcessOverriddenCallables( + functionSymbol, processor, directOverriddenFunctions, superTypesScope, + FirTypeScope::processOverriddenFunctionsWithDepth + ) + + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction = + doProcessOverriddenCallables( + propertySymbol, processor, directOverriddenProperties, superTypesScope, + FirTypeScope::processOverriddenPropertiesWithDepth + ) override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { declaredMemberScope.processClassifiersByNameWithSubstitution(name, processor) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt index 7c921821b06..a83f0af3915 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassSubstitutionScope.kt @@ -102,6 +102,22 @@ class FirClassSubstitutionScope( } } + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction { + if (!useSiteMemberScope.processOverriddenPropertiesWithDepth(propertySymbol, processor)) { + return ProcessorAction.STOP + } + val unwrapped = propertySymbol.overriddenSymbol ?: return ProcessorAction.NEXT + if (!processor(unwrapped, 1)) { + return ProcessorAction.STOP + } + return useSiteMemberScope.processOverriddenPropertiesWithDepth(unwrapped) { symbol, depth -> + processor(symbol, depth + 1) + } + } + override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { useSiteMemberScope.processClassifiersByNameWithSubstitution(name) { symbol, substitutor -> processor(symbol, substitutor.chain(this.substitutor)) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt index d9093fb0880..d8b87d92d94 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassUseSiteMemberScope.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.FirTypeScope +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.isStatic import org.jetbrains.kotlin.name.Name @@ -30,6 +31,8 @@ class FirClassUseSiteMemberScope( val overriddenBy = it.getOverridden(seen) if (overriddenBy == null) { processor(it) + } else if (overriddenBy is FirPropertySymbol && it is FirPropertySymbol) { + directOverriddenProperties.getOrPut(overriddenBy) { mutableListOf() }.add(it) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt index 979a03e9c17..3bd0bd89793 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirIntegerLiteralTypeScope.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralType import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralTypeImpl @@ -100,6 +101,11 @@ class FirIntegerLiteralTypeScope(private val session: FirSession, val isUnsigned functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction ): ProcessorAction = ProcessorAction.NEXT + + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction = ProcessorAction.NEXT } @OptIn(FirImplementationDetail::class) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt index 0cc50be998a..8af81d6f879 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirTypeIntersectionScope.kt @@ -38,7 +38,7 @@ class FirTypeIntersectionScope private constructor( private val overriddenSymbols: MutableMap, Collection>> = mutableMapOf() - private val intersectionOverrides: MutableMap = mutableMapOf() + private val intersectionOverrides: MutableMap, FirCallableSymbol<*>> = mutableMapOf() override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) { if (!processCallablesByName(name, processor, absentFunctions, FirScope::processFunctionsByName)) { @@ -94,11 +94,20 @@ class FirTypeIntersectionScope private constructor( val extractedOverrides = extractBothWaysOverridable(maxByVisibility, allMembers) val mostSpecific = selectMostSpecificMember(extractedOverrides) - if (extractedOverrides.size > 1 && mostSpecific is FirNamedFunctionSymbol) { - // TODO: same code for properties + if (extractedOverrides.size > 1) { val intersectionOverride = intersectionOverrides.getOrPut(mostSpecific) { @Suppress("UNCHECKED_CAST") - createIntersectionOverride(mostSpecific, extractedOverrides as Collection) + when (mostSpecific) { + is FirNamedFunctionSymbol -> { + createIntersectionOverride(mostSpecific, extractedOverrides as Collection) + } + is FirPropertySymbol -> { + createIntersectionOverride(mostSpecific) + } + else -> { + throw IllegalStateException("Should not be here") + } + } } overriddenSymbols[intersectionOverride] = extractedOverrides @Suppress("UNCHECKED_CAST") @@ -140,6 +149,17 @@ class FirTypeIntersectionScope private constructor( return newSymbol } + private fun createIntersectionOverride(mostSpecific: FirPropertySymbol): FirPropertySymbol { + val newSymbol = FirPropertySymbol(mostSpecific.callableId, mostSpecific.isFakeOverride, mostSpecific) + val mostSpecificProperty = mostSpecific.fir + createPropertyCopy(mostSpecific.fir, newSymbol).apply { + resolvePhase = mostSpecificProperty.resolvePhase + origin = FirDeclarationOrigin.IntersectionOverride + typeParameters += mostSpecificProperty.typeParameters + }.build() + return newSymbol + } + private fun > selectMostSpecificMember(overridables: Collection): D { require(overridables.isNotEmpty()) { "Should have at least one overridable symbol" } if (overridables.size == 1) { @@ -275,8 +295,8 @@ class FirTypeIntersectionScope private constructor( } @Suppress("UNCHECKED_CAST") - private fun getDirectOverriddenSymbols(functionSymbol: FirFunctionSymbol<*>): Collection> = - overriddenSymbols[functionSymbol].orEmpty() as Collection> + private fun > getDirectOverriddenSymbols(symbol: S): Collection = + overriddenSymbols[symbol].orEmpty() as Collection override fun processOverriddenFunctionsWithDepth( functionSymbol: FirFunctionSymbol<*>, @@ -297,6 +317,25 @@ class FirTypeIntersectionScope private constructor( return ProcessorAction.NEXT } + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction { + for (overridden in getDirectOverriddenSymbols(propertySymbol)) { + val overriddenDepth = if (overridden.overriddenSymbol != null) 0 else 1 + if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP + // TODO: Preserve the scope where directOverridden came from + for (scope in scopes) { + if (!scope.processOverriddenPropertiesWithDepth(overridden) { symbol, depth -> + processor(symbol, depth + overriddenDepth) + } + ) return ProcessorAction.STOP + } + } + + return ProcessorAction.NEXT + } + companion object { fun prepareIntersectionScope( session: FirSession, diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt index c4d4b8ad88d..c5d5e407789 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/scopes/FirTypeScope.kt @@ -5,11 +5,12 @@ package org.jetbrains.kotlin.fir.scopes +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol abstract class FirTypeScope : FirScope() { - // Currently, this function has very weak guarantees + // Currently, this function and its property brother both have very weak guarantees // - It may silently do nothing on symbols originated from different scope instance // - It may return the same overridden symbols more then once in case of substitution // - It doesn't guarantee any specific order in which overridden tree will be traversed @@ -38,26 +39,51 @@ abstract class FirTypeScope : FirScope() { } } - // This is just a helper for a common implementation - protected fun doProcessOverriddenFunctions( - functionSymbol: FirFunctionSymbol<*>, - processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction, - directOverriddenMap: Map, Collection>>, - baseScope: FirTypeScope - ): ProcessorAction { - val directOverridden = - directOverriddenMap[functionSymbol] ?: return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor) + // ------------------------------------------------------------------------------------ - for (overridden in directOverridden) { - val overriddenDepth = if (overridden is FirNamedFunctionSymbol && overridden.overriddenSymbol != null) 0 else 1 + abstract fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction + + inline fun processOverriddenProperties( + propertySymbol: FirPropertySymbol, + crossinline processor: (FirPropertySymbol) -> ProcessorAction + ): ProcessorAction = processOverriddenPropertiesWithDepth(propertySymbol) { symbol, _ -> + processor(symbol) + } + + inline fun processDirectlyOverriddenProperties( + propertySymbol: FirPropertySymbol, + crossinline processor: (FirPropertySymbol) -> ProcessorAction + ): ProcessorAction = processOverriddenPropertiesWithDepth(propertySymbol) { symbol, depth -> + if (depth == 1) { + processor(symbol) + } else { + ProcessorAction.NEXT + } + } + + // ------------------------------------------------------------------------------------ + + // This is just a helper for a common implementation + protected fun > doProcessOverriddenCallables( + callableSymbol: S, + processor: (S, Int) -> ProcessorAction, + directOverriddenMap: Map>, + baseScope: FirTypeScope, + processOverriddenCallablesWithDepth: FirTypeScope.(S, (S, Int) -> ProcessorAction) -> ProcessorAction + ): ProcessorAction { + for (overridden in directOverriddenMap[callableSymbol].orEmpty()) { + val overriddenDepth = if (overridden.overriddenSymbol != null) 0 else 1 if (!processor(overridden, overriddenDepth)) return ProcessorAction.STOP - if (!baseScope.processOverriddenFunctionsWithDepth(overridden) { symbol, depth -> + if (!baseScope.processOverriddenCallablesWithDepth(overridden) { symbol, depth -> processor(symbol, depth + overriddenDepth) } ) return ProcessorAction.STOP } - return baseScope.processOverriddenFunctionsWithDepth(functionSymbol, processor) + return baseScope.processOverriddenCallablesWithDepth(callableSymbol, processor) } object Empty : FirTypeScope() { @@ -65,5 +91,10 @@ abstract class FirTypeScope : FirScope() { functionSymbol: FirFunctionSymbol<*>, processor: (FirFunctionSymbol<*>, Int) -> ProcessorAction ): ProcessorAction = ProcessorAction.NEXT + + override fun processOverriddenPropertiesWithDepth( + propertySymbol: FirPropertySymbol, + processor: (FirPropertySymbol, Int) -> ProcessorAction + ): ProcessorAction = ProcessorAction.NEXT } }