diff --git a/compiler/fir/analysis-tests/testData/resolve/arguments/kt41940.fir.txt b/compiler/fir/analysis-tests/testData/resolve/arguments/kt41940.fir.txt index 9a68a08246c..4bf790068f5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/arguments/kt41940.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/arguments/kt41940.fir.txt @@ -1,4 +1,4 @@ FILE: main.kt public final fun test(list: R|kotlin/collections/List|, string: R|kotlin/String|): R|kotlin/Unit| { - Q|Matchers|.R|/Matchers.assertThat|, kotlin/collections/List?>|>(R|/list|, Q|Matchers|.R|/Matchers.hasItem|(R|/string|)) + R|/Matchers.assertThat|, kotlin/collections/List?>|>(R|/list|, R|/Matchers.hasItem|(R|/string|)) } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.fir.txt index bc9127a1f14..c7939573405 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/FlexiblePrimitiveOverloading.fir.txt @@ -1,4 +1,4 @@ FILE: FlexiblePrimitiveOverloading.kt public final fun foo(): R|kotlin/Unit| { - Q|java/lang/Integer|.R|java/lang/Integer.getInteger|(String(text), Int(239)) + R|java/lang/Integer.getInteger|(String(text), Int(239)) } 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 c3dc200c65e..d5d3bdd0c9d 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 @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.scopes.FirTypeScope import org.jetbrains.kotlin.fir.scopes.ProcessorAction +import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -227,26 +228,24 @@ private fun FirCallableSymbol<*>.toSymbolForCall( isDelegate: Boolean = false, isReference: Boolean = false ): IrSymbol? { - val dispatchReceiverType = when (dispatchReceiver) { + val fakeOverrideOwnerLookupTag = fir.importedFromObjectOrStaticData.takeIf { isStatic }?.let { + ConeClassLikeLookupTagImpl(it.objectClassId) + } ?: when (dispatchReceiver) { is FirNoReceiverExpression -> { val containingClass = containingClassLookupTag() if (containingClass != null && containingClass.classId != StandardClassIds.Any) { // Make sure that symbol is not extension and is not from inline class - ((explicitReceiver as? FirResolvedQualifier)?.symbol as? FirClassSymbol)?.defaultType() + ((explicitReceiver as? FirResolvedQualifier)?.symbol as? FirClassSymbol)?.toLookupTag() } else { null } } - is FirResolvedQualifier -> { - if (isStatic) (dispatchReceiver.symbol as? FirClassSymbol)?.defaultType() else dispatchReceiver.typeRef.coneType - } - else -> { - dispatchReceiver.typeRef.coneType + if (isStatic && dispatchReceiver is FirResolvedQualifier) (dispatchReceiver.symbol as? FirClassSymbol)?.toLookupTag() + else dispatchReceiver.typeRef.coneType.let { it.findClassRepresentation(it, declarationStorage.session) } } } - val dispatchReceiverLookupTag = dispatchReceiverType?.findClassRepresentation(dispatchReceiverType, declarationStorage.session) return when (this) { is FirSimpleSyntheticPropertySymbol -> { @@ -255,7 +254,7 @@ private fun FirCallableSymbol<*>.toSymbolForCall( } else { (fir as? FirSyntheticProperty)?.let { syntheticProperty -> if (isReference) { - declarationStorage.getIrPropertySymbol(this, dispatchReceiverLookupTag) + declarationStorage.getIrPropertySymbol(this, fakeOverrideOwnerLookupTag) } else { val delegateSymbol = if (preferGetter) { syntheticProperty.getter.delegate.symbol @@ -270,8 +269,8 @@ private fun FirCallableSymbol<*>.toSymbolForCall( } } - is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this, dispatchReceiverLookupTag) - is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this, dispatchReceiverLookupTag) + is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this, fakeOverrideOwnerLookupTag) + is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this, fakeOverrideOwnerLookupTag) is FirFieldSymbol -> declarationStorage.getIrFieldSymbol(this) is FirBackingFieldSymbol -> declarationStorage.getIrBackingFieldSymbol(this) is FirDelegateFieldSymbol -> declarationStorage.getIrDelegateFieldSymbol(this) 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 18f90cee81e..86ae8fa850e 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 @@ -431,13 +431,13 @@ class Fir2IrDeclarationStorage( fun getCachedIrFunction( function: FirSimpleFunction, - dispatchReceiverLookupTag: ConeClassLikeLookupTag?, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, signatureCalculator: () -> IdSignature? ): IrSimpleFunction? { if (function.visibility == Visibilities.Local) { return localStorage.getLocalFunction(function) } - return getCachedIrCallable(function, dispatchReceiverLookupTag, functionCache, signatureCalculator) { signature -> + return getCachedIrCallable(function, fakeOverrideOwnerLookupTag, functionCache, signatureCalculator) { signature -> symbolTable.referenceSimpleFunctionIfAny(signature)?.owner } } @@ -470,7 +470,7 @@ class Fir2IrDeclarationStorage( return createIrFunction( function, irParent, - containingClass = function.containingClassLookupTag(), + fakeOverrideOwnerLookupTag = function.containingClassLookupTag(), isLocal = isLocal, forceTopLevelPrivate = forceTopLevelPrivate ) @@ -482,7 +482,7 @@ class Fir2IrDeclarationStorage( thisReceiverOwner: IrClass? = irParent as? IrClass, predefinedOrigin: IrDeclarationOrigin? = null, isLocal: Boolean = false, - containingClass: ConeClassLikeLookupTag? = null, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, forceTopLevelPrivate: Boolean = false, ): IrSimpleFunction = convertCatching(function) { val simpleFunction = function as? FirSimpleFunction @@ -513,7 +513,7 @@ class Fir2IrDeclarationStorage( function.dispatchReceiverType?.isPrimitive != true && function.containerSource == null && updatedOrigin != IrDeclarationOrigin.FAKE_OVERRIDE && !function.isOverride ) { - signatureComposer.composeSignature(function, containingClass, forceTopLevelPrivate) + signatureComposer.composeSignature(function, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) } if (irParent is Fir2IrLazyClass && signature != null) { // For private functions signature is null, fallback to non-lazy function @@ -670,14 +670,14 @@ class Fir2IrDeclarationStorage( startOffset: Int, endOffset: Int, dontUseSignature: Boolean = false, - containingClass: ConeClassLikeLookupTag? = null, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, propertyAccessorForAnnotations: FirPropertyAccessor? = propertyAccessor, forceTopLevelPrivate: Boolean = false, ): IrSimpleFunction = convertCatching(propertyAccessor ?: property) { val prefix = if (isSetter) "set" else "get" val signature = runUnless(dontUseSignature) { - signatureComposer.composeAccessorSignature(property, isSetter, containingClass, forceTopLevelPrivate) + signatureComposer.composeAccessorSignature(property, isSetter, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) } val containerSource = (correspondingProperty as? IrProperty)?.containerSource return declareIrAccessor( @@ -811,7 +811,7 @@ class Fir2IrDeclarationStorage( createIrProperty( field.toStubProperty(), irParent, - containingClass = containingClassId?.let { ConeClassLikeLookupTagImpl(it) } + fakeOverrideOwnerLookupTag = containingClassId?.let { ConeClassLikeLookupTagImpl(it) } ) } } @@ -839,7 +839,7 @@ class Fir2IrDeclarationStorage( thisReceiverOwner: IrClass? = irParent as? IrClass, predefinedOrigin: IrDeclarationOrigin? = null, isLocal: Boolean = false, - containingClass: ConeClassLikeLookupTag? = (irParent as? IrClass)?.classId?.let { ConeClassLikeLookupTagImpl(it) }, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = (irParent as? IrClass)?.classId?.let { ConeClassLikeLookupTagImpl(it) }, forceTopLevelPrivate: Boolean = false, ): IrProperty = convertCatching(property) { val origin = @@ -853,7 +853,7 @@ class Fir2IrDeclarationStorage( property.dispatchReceiverType?.isPrimitive != true && property.containerSource == null && origin != IrDeclarationOrigin.FAKE_OVERRIDE && !property.isOverride ) { - signatureComposer.composeSignature(property, containingClass, forceTopLevelPrivate) + signatureComposer.composeSignature(property, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) } if (irParent is Fir2IrLazyClass && signature != null) { // For private functions signature is null, fallback to non-lazy property @@ -928,7 +928,7 @@ class Fir2IrDeclarationStorage( else -> origin }, startOffset, endOffset, - dontUseSignature = signature == null, containingClass, + dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, property.unwrapFakeOverrides().getter, forceTopLevelPrivate = forceTopLevelPrivate, ) @@ -941,7 +941,7 @@ class Fir2IrDeclarationStorage( else -> origin }, startOffset, endOffset, - dontUseSignature = signature == null, containingClass, + dontUseSignature = signature == null, fakeOverrideOwnerLookupTag, property.unwrapFakeOverrides().setter, forceTopLevelPrivate = forceTopLevelPrivate, ) @@ -958,22 +958,22 @@ class Fir2IrDeclarationStorage( fun getCachedIrProperty( property: FirProperty, - dispatchReceiverLookupTag: ConeClassLikeLookupTag?, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, signatureCalculator: () -> IdSignature? ): IrProperty? { - return getCachedIrCallable(property, dispatchReceiverLookupTag, propertyCache, signatureCalculator) { signature -> + return getCachedIrCallable(property, fakeOverrideOwnerLookupTag, propertyCache, signatureCalculator) { signature -> symbolTable.referencePropertyIfAny(signature)?.owner } } private inline fun getCachedIrCallable( declaration: FC, - dispatchReceiverLookupTag: ConeClassLikeLookupTag?, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, cache: MutableMap, signatureCalculator: () -> IdSignature?, referenceIfAny: (IdSignature) -> IC? ): IC? { - val isFakeOverride = dispatchReceiverLookupTag != null && dispatchReceiverLookupTag != declaration.containingClassLookupTag() + val isFakeOverride = fakeOverrideOwnerLookupTag != null && fakeOverrideOwnerLookupTag != declaration.containingClassLookupTag() if (!isFakeOverride) { cache[declaration]?.let { return it } } @@ -1238,7 +1238,7 @@ class Fir2IrDeclarationStorage( val fir = firConstructorSymbol.fir return getIrCallableSymbol( firConstructorSymbol, - dispatchReceiverLookupTag = null, + fakeOverrideOwnerLookupTag = null, getCachedIrDeclaration = { constructor: FirConstructor, _, calculator -> getCachedIrConstructor(constructor, calculator) }, createIrDeclaration = { parent, origin -> createIrConstructor(fir, parent as IrClass, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate) @@ -1265,7 +1265,7 @@ class Fir2IrDeclarationStorage( fun getIrFunctionSymbol( firFunctionSymbol: FirFunctionSymbol<*>, - dispatchReceiverLookupTag: ConeClassLikeLookupTag? = null, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, forceTopLevelPrivate: Boolean = false, ): IrFunctionSymbol { return when (val fir = firFunctionSymbol.fir) { @@ -1277,20 +1277,20 @@ class Fir2IrDeclarationStorage( createIrFunction(fir, irParent, predefinedOrigin = declarationOrigin).symbol } is FirSimpleFunction -> { - val unmatchedReceiver = dispatchReceiverLookupTag != firFunctionSymbol.containingClassLookupTag() + val unmatchedReceiver = fakeOverrideOwnerLookupTag != firFunctionSymbol.containingClassLookupTag() if (unmatchedReceiver) { - generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag) + generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag) } val originalSymbol = getIrCallableSymbol( firFunctionSymbol, - dispatchReceiverLookupTag, + fakeOverrideOwnerLookupTag, getCachedIrDeclaration = ::getCachedIrFunction, createIrDeclaration = { parent, origin -> createIrFunction( fir, parent, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate, - containingClass = dispatchReceiverLookupTag, + fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag, ) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> @@ -1298,9 +1298,9 @@ class Fir2IrDeclarationStorage( }, forceTopLevelPrivate = forceTopLevelPrivate ) as IrFunctionSymbol - if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) { + if (unmatchedReceiver && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) { val originalFunction = originalSymbol.owner as IrSimpleFunction - dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol + fakeOverrideOwnerLookupTag.findIrFakeOverride(fir.name, originalFunction) as IrFunctionSymbol? ?: originalSymbol } else { originalSymbol } @@ -1338,7 +1338,7 @@ class Fir2IrDeclarationStorage( fun getIrPropertySymbol( firPropertySymbol: FirPropertySymbol, - dispatchReceiverLookupTag: ConeClassLikeLookupTag? = null, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag? = null, forceTopLevelPrivate: Boolean = false, ): IrSymbol { val fir = firPropertySymbol.fir @@ -1346,19 +1346,19 @@ class Fir2IrDeclarationStorage( return localStorage.getDelegatedProperty(fir)?.symbol ?: getIrVariableSymbol(fir) } val containingClassLookupTag = firPropertySymbol.containingClassLookupTag() - val unmatchedReceiver = dispatchReceiverLookupTag != containingClassLookupTag + val unmatchedReceiver = fakeOverrideOwnerLookupTag != containingClassLookupTag if (unmatchedReceiver) { - generateLazyFakeOverrides(fir.name, dispatchReceiverLookupTag) + generateLazyFakeOverrides(fir.name, fakeOverrideOwnerLookupTag) } fun ConeClassLikeLookupTag?.getIrCallableSymbol() = getIrCallableSymbol( firPropertySymbol, - dispatchReceiverLookupTag = this, + fakeOverrideOwnerLookupTag = this, getCachedIrDeclaration = ::getCachedIrProperty, createIrDeclaration = { parent, origin -> createIrProperty( fir, parent, predefinedOrigin = origin, forceTopLevelPrivate = forceTopLevelPrivate, - containingClass = dispatchReceiverLookupTag, + fakeOverrideOwnerLookupTag = fakeOverrideOwnerLookupTag, ) }, createIrLazyDeclaration = { signature, lazyParent, declarationOrigin -> @@ -1367,7 +1367,7 @@ class Fir2IrDeclarationStorage( forceTopLevelPrivate = forceTopLevelPrivate ) - val originalSymbol = dispatchReceiverLookupTag.getIrCallableSymbol() + val originalSymbol = fakeOverrideOwnerLookupTag.getIrCallableSymbol() val originalProperty = originalSymbol.owner as IrProperty fun IrProperty.isIllegalFakeOverride(): Boolean { @@ -1379,7 +1379,7 @@ class Fir2IrDeclarationStorage( return false } - if (dispatchReceiverLookupTag != null && + if (fakeOverrideOwnerLookupTag != null && firPropertySymbol is FirSyntheticPropertySymbol && originalProperty.isIllegalFakeOverride() ) { @@ -1387,8 +1387,8 @@ class Fir2IrDeclarationStorage( return containingClassLookupTag.getIrCallableSymbol() } - return if (unmatchedReceiver && dispatchReceiverLookupTag is ConeClassLookupTagWithFixedSymbol) { - dispatchReceiverLookupTag.findIrFakeOverride(fir.name, originalProperty) as IrPropertySymbol + return if (unmatchedReceiver && fakeOverrideOwnerLookupTag is ConeClassLookupTagWithFixedSymbol) { + fakeOverrideOwnerLookupTag.findIrFakeOverride(fir.name, originalProperty) as IrPropertySymbol } else { originalSymbol } @@ -1429,8 +1429,8 @@ class Fir2IrDeclarationStorage( }?.symbol } - private fun generateLazyFakeOverrides(name: Name, dispatchReceiverLookupTag: ConeClassLikeLookupTag?) { - val firClassSymbol = dispatchReceiverLookupTag?.toSymbol(session) as? FirClassSymbol + private fun generateLazyFakeOverrides(name: Name, fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?) { + val firClassSymbol = fakeOverrideOwnerLookupTag?.toSymbol(session) as? FirClassSymbol if (firClassSymbol != null) { val irClass = classifierStorage.getIrClassSymbol(firClassSymbol).owner if (irClass is Fir2IrLazyClass) { @@ -1445,7 +1445,7 @@ class Fir2IrDeclarationStorage( I : IrSymbolOwner, > getIrCallableSymbol( firSymbol: FS, - dispatchReceiverLookupTag: ConeClassLikeLookupTag?, + fakeOverrideOwnerLookupTag: ConeClassLikeLookupTag?, getCachedIrDeclaration: (firDeclaration: F, dispatchReceiverLookupTag: ConeClassLikeLookupTag?, () -> IdSignature?) -> I?, createIrDeclaration: (parent: IrDeclarationParent?, origin: IrDeclarationOrigin) -> I, createIrLazyDeclaration: (signature: IdSignature, lazyOwner: IrDeclarationParent, origin: IrDeclarationOrigin) -> I, @@ -1453,9 +1453,9 @@ class Fir2IrDeclarationStorage( ): IrSymbol { val fir = firSymbol.fir as F val irParent by lazy { findIrParent(fir) } - val signature by lazy { signatureComposer.composeSignature(fir, dispatchReceiverLookupTag, forceTopLevelPrivate) } + val signature by lazy { signatureComposer.composeSignature(fir, fakeOverrideOwnerLookupTag, forceTopLevelPrivate) } synchronized(symbolTable.lock) { - getCachedIrDeclaration(fir, dispatchReceiverLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) { + getCachedIrDeclaration(fir, fakeOverrideOwnerLookupTag.takeIf { it !is ConeClassLookupTagWithFixedSymbol }) { // Parent calculation provokes declaration calculation for some members from IrBuiltIns @Suppress("UNUSED_EXPRESSION") irParent signature diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt index 8c61d999cf7..a2b0151dce9 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt @@ -212,7 +212,7 @@ class DelegatedMemberGenerator( val delegateFunction = declarationStorage.createIrFunction( delegateOverride, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, - containingClass = firSubClass.symbol.toLookupTag() + fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag() ) val baseSymbols = mutableListOf() // the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their @@ -293,7 +293,7 @@ class DelegatedMemberGenerator( val delegateProperty = declarationStorage.createIrProperty( firDelegateProperty, subClass, predefinedOrigin = IrDeclarationOrigin.DELEGATED_MEMBER, - containingClass = firSubClass.symbol.toLookupTag() + fakeOverrideOwnerLookupTag = firSubClass.symbol.toLookupTag() ) // the overridden symbols should be collected only after all fake overrides for all superclases are created and bound to their // overridden symbols, otherwise in some cases they will be left in inconsistent state leading to the errors in IR diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt index af94731ea43..70cadc79165 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/Candidate.kt @@ -36,6 +36,7 @@ class Candidate( private val baseSystem: ConstraintStorage, override val callInfo: CallInfo, val originScope: FirScope?, + val importedQualifierForStatic: FirExpression? = null, val isFromCompanionObjectTypeScope: Boolean = false ) : AbstractCandidate() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 90f45de3089..b7147b95848 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -49,6 +49,7 @@ class CandidateFactory private constructor( explicitReceiverKind: ExplicitReceiverKind, scope: FirScope?, dispatchReceiverValue: ReceiverValue? = null, + importedQualifierForStatic: FirExpression? = null, givenExtensionReceiverOptions: List = emptyList(), objectsByName: Boolean = false ): Candidate { @@ -56,10 +57,15 @@ class CandidateFactory private constructor( val symbol = symbol.unwrapIntegerOperatorSymbolIfNeeded(callInfo) val result = Candidate( - symbol, dispatchReceiverValue, givenExtensionReceiverOptions, - explicitReceiverKind, context.inferenceComponents.constraintSystemFactory, baseSystem, + symbol, + dispatchReceiverValue, + givenExtensionReceiverOptions, + explicitReceiverKind, + context.inferenceComponents.constraintSystemFactory, + baseSystem, callInfo, scope, + importedQualifierForStatic, isFromCompanionObjectTypeScope = when (explicitReceiverKind) { ExplicitReceiverKind.EXTENSION_RECEIVER -> givenExtensionReceiverOptions.singleOrNull().isCandidateFromCompanionObjectTypeScope() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 5b9a0c449cd..04fe299e054 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -540,7 +540,10 @@ internal object CheckVisibility : CheckerStage() { sink.yieldDiagnostic(VisibilityError) } - if (!visibilityChecker.isVisible(declaration, candidate.callInfo, dispatchReceiverValue = null)) { + if (!visibilityChecker.isVisible( + declaration, candidate.callInfo, dispatchReceiverValue = null, importedQualifierForStatic = null + ) + ) { sink.yieldDiagnostic(VisibilityError) } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/VisibilityUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/VisibilityUtils.kt index 7a547f8ee08..65bfb3d7724 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/VisibilityUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/VisibilityUtils.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.getExplicitBackingField import org.jetbrains.kotlin.fir.declarations.utils.isStatic import org.jetbrains.kotlin.fir.declarations.utils.visibility +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment @@ -27,10 +28,11 @@ import org.jetbrains.kotlin.utils.addToStdlib.runIf fun FirVisibilityChecker.isVisible( declaration: FirMemberDeclaration, callInfo: CallInfo, - dispatchReceiverValue: ReceiverValue? + dispatchReceiverValue: ReceiverValue?, + importedQualifierForStatic: FirExpression? ): Boolean { val staticQualifierForCallable = runIf(declaration is FirCallableDeclaration && declaration.isStatic) { - val explicitReceiver = callInfo.explicitReceiver ?: (dispatchReceiverValue as? ExpressionReceiverValue)?.explicitReceiver + val explicitReceiver = callInfo.explicitReceiver ?: importedQualifierForStatic (explicitReceiver as? FirResolvedQualifier)?.symbol?.fir as? FirRegularClass } return isVisible( @@ -49,19 +51,21 @@ fun FirVisibilityChecker.isVisible( candidate: Candidate ): Boolean { val callInfo = candidate.callInfo + val dispatchReceiverValue = candidate.dispatchReceiverValue + val importedQualifierForStatic = candidate.importedQualifierForStatic - if (!isVisible(declaration, callInfo, candidate.dispatchReceiverValue)) { + if (!isVisible(declaration, callInfo, dispatchReceiverValue, importedQualifierForStatic)) { val dispatchReceiverWithoutSmartCastType = - removeSmartCastTypeForAttemptToFitVisibility(candidate.dispatchReceiverValue, candidate.callInfo.session) ?: return false + removeSmartCastTypeForAttemptToFitVisibility(dispatchReceiverValue, candidate.callInfo.session) ?: return false - if (!isVisible(declaration, callInfo, dispatchReceiverWithoutSmartCastType)) return false + if (!isVisible(declaration, callInfo, dispatchReceiverWithoutSmartCastType, importedQualifierForStatic)) return false candidate.dispatchReceiverValue = dispatchReceiverWithoutSmartCastType } val backingField = declaration.getBackingFieldIfApplicable() if (backingField != null) { - candidate.hasVisibleBackingField = isVisible(backingField, callInfo, candidate.dispatchReceiverValue) + candidate.hasVisibleBackingField = isVisible(backingField, callInfo, dispatchReceiverValue, importedQualifierForStatic) } return true diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt index 3e8714d9cf6..f6e0d2097de 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevelHandler.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol @@ -74,6 +75,7 @@ private class TowerScopeLevelProcessor( override fun consumeCandidate( symbol: FirBasedSymbol<*>, dispatchReceiverValue: ReceiverValue?, + importedQualifierForStatic: FirExpression?, givenExtensionReceiverOptions: List, scope: FirScope, objectsByName: Boolean @@ -85,6 +87,7 @@ private class TowerScopeLevelProcessor( explicitReceiverKind, scope, dispatchReceiverValue, + importedQualifierForStatic, givenExtensionReceiverOptions, objectsByName ), candidateFactory.context 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 7a86faaaa4e..c00585041cc 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 @@ -7,9 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.ContextReceiverGroup +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirConstructor import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId import org.jetbrains.kotlin.fir.declarations.utils.isInner +import org.jetbrains.kotlin.fir.declarations.utils.isStatic +import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirSmartCastExpression import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.resolve.* @@ -25,6 +28,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.StandardClassIds.Annotations.HidesMembers import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.utils.SmartList +import org.jetbrains.kotlin.utils.addToStdlib.runIf enum class ProcessResult { FOUND, SCOPE_EMPTY; @@ -53,6 +57,7 @@ abstract class TowerScopeLevel { fun consumeCandidate( symbol: T, dispatchReceiverValue: ReceiverValue?, + importedQualifierForStatic: FirExpression?, givenExtensionReceiverOptions: List, scope: FirScope, objectsByName: Boolean = false @@ -132,7 +137,13 @@ class MemberScopeTowerLevel( ) withSynthetic?.processScopeMembers { symbol -> empty = false - output.consumeCandidate(symbol, dispatchReceiverValue, givenExtensionReceiverOptions = emptyList(), scope) + output.consumeCandidate( + symbol, + dispatchReceiverValue, + importedQualifierForStatic = null, + givenExtensionReceiverOptions = emptyList(), + scope + ) } } return if (empty) ProcessResult.SCOPE_EMPTY else ProcessResult.FOUND @@ -158,7 +169,7 @@ class MemberScopeTowerLevel( val candidates = mutableListOf>() for (group in overridableGroups) { val visibleCandidates = group.filter { - visibilityChecker.isVisible(it.member.fir, callInfo, dispatchReceiverValue) + visibilityChecker.isVisible(it.member.fir, callInfo, dispatchReceiverValue, importedQualifierForStatic = null) } val visibleCandidatesFromSmartcast = visibleCandidates.filter { candidatesMapping.getValue(it) } @@ -192,12 +203,12 @@ class MemberScopeTowerLevel( for ((candidate, scope) in candidatesWithScope) { if (candidate.hasConsistentExtensionReceiver(givenExtensionReceiverOptions)) { output.consumeCandidate( - candidate, dispatchReceiverValue, + candidate, + dispatchReceiverValue, + importedQualifierForStatic = null, givenExtensionReceiverOptions, scope ) - } else if (candidate is FirClassLikeSymbol<*>) { - output.consumeCandidate(candidate, null, givenExtensionReceiverOptions, scope) } } } @@ -215,7 +226,6 @@ class MemberScopeTowerLevel( processor = { lookupCtx.recordCallableMemberLookup(it) // WARNING, DO NOT CAST FUNCTIONAL TYPE ITSELF - @Suppress("UNCHECKED_CAST") consumer(it as FirFunctionSymbol<*>) } ) @@ -313,21 +323,27 @@ class ScopeTowerLevel( fun areThereExtensionReceiverOptions(): Boolean = givenExtensionReceiverOptions.isNotEmpty() - private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { - candidate.fir.importedFromObjectOrStaticData?.let { data -> - val objectClassId = data.objectClassId - val symbol = session.symbolProvider.getClassLikeSymbolByClassId(objectClassId) - if (symbol is FirRegularClassSymbol) { - val resolvedQualifier = buildResolvedQualifier { - packageFqName = objectClassId.packageFqName - relativeClassFqName = objectClassId.relativeClassName - this.symbol = symbol - }.apply { - resultType = bodyResolveComponents.typeForQualifier(this) - } - return ExpressionReceiverValue(resolvedQualifier) + private fun FirCallableDeclaration.importedQualifierForObjectOrStatic(): FirExpression? { + val objectClassId = importedFromObjectOrStaticData?.objectClassId ?: return null + val symbol = session.symbolProvider.getClassLikeSymbolByClassId(objectClassId) + if (symbol is FirRegularClassSymbol) { + return buildResolvedQualifier { + packageFqName = objectClassId.packageFqName + relativeClassFqName = objectClassId.relativeClassName + this.symbol = symbol + }.apply { + resultType = bodyResolveComponents.typeForQualifier(this) } } + return null + } + + private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { + if (candidate.fir.isStatic) return null + val importedQualifierReceiver = candidate.fir.importedQualifierForObjectOrStatic() + if (importedQualifierReceiver != null) { + return ExpressionReceiverValue(importedQualifierReceiver) + } if (candidate !is FirBackingFieldSymbol) { return null @@ -381,13 +397,22 @@ class ScopeTowerLevel( val receiverExpected = withHideMembersOnly || areThereExtensionReceiverOptions() if (candidateReceiverTypeRef == null == receiverExpected) return val dispatchReceiverValue = dispatchReceiverValue(candidate) - if (dispatchReceiverValue == null && shouldSkipCandidateWithInconsistentExtensionReceiver(candidate)) { + val isStatic = candidate.fir.isStatic + val importedQualifierForStatic = runIf(isStatic) { + candidate.fir.importedQualifierForObjectOrStatic() + } + if (dispatchReceiverValue == null && + importedQualifierForStatic == null && + shouldSkipCandidateWithInconsistentExtensionReceiver(candidate) + ) { return } - val unwrappedCandidate = candidate.fir.importedFromObjectOrStaticData?.original?.symbol ?: candidate + val unwrappedCandidate = candidate.fir.importedFromObjectOrStaticData?.original?.symbol.takeIf { !isStatic } ?: candidate @Suppress("UNCHECKED_CAST") processor.consumeCandidate( - unwrappedCandidate as T, dispatchReceiverValue, + unwrappedCandidate as T, + dispatchReceiverValue, + importedQualifierForStatic, givenExtensionReceiverOptions, scope ) @@ -433,7 +458,9 @@ class ScopeTowerLevel( scope.processClassifiersByName(info.name) { empty = false processor.consumeCandidate( - it, dispatchReceiverValue = null, + it, + dispatchReceiverValue = null, + importedQualifierForStatic = null, givenExtensionReceiverOptions = emptyList(), scope = scope, objectsByName = true