diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt index e97ee8bf357..1cb8a471f3b 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirExpectActualMatcherLazyResolver.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.mpp.FirExpectActualMatcherTransformer +import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase internal object LLFirExpectActualMatcherLazyResolver : LLFirLazyResolver(FirResolvePhase.EXPECT_ACTUAL_MATCHING) { override fun resolve( @@ -48,6 +49,16 @@ private class LLFirExpectActualMatchingTargetResolver( ) : LLFirTargetResolver(target, lockProvider, FirResolvePhase.EXPECT_ACTUAL_MATCHING) { private val enabled = session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) + @Deprecated("Should never be called directly, only for override purposes, please use withRegularClass", level = DeprecationLevel.ERROR) + override fun withRegularClassImpl(firClass: FirRegularClass, action: () -> Unit) { + if (enabled) { + // Resolve outer classes before resolving inner declarations. It's the requirement of FirExpectActualResolver + firClass.lazyResolveToPhase(resolverPhase.previous) + performResolve(firClass) + } + action() + } + private val transformer = object : FirExpectActualMatcherTransformer(session, scopeSession) { override fun transformRegularClass(regularClass: FirRegularClass, data: Nothing?): FirStatement { transformMemberDeclaration(regularClass) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt index b285c96df62..2dc8ef39e35 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/mpp/FirExpectActualResolver.kt @@ -8,9 +8,9 @@ package org.jetbrains.kotlin.fir.resolve.transformers.mpp import org.jetbrains.kotlin.fir.FirExpectActualMatchingContext import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.ExpectForActualMatchingData +import org.jetbrains.kotlin.fir.declarations.expectForActual import org.jetbrains.kotlin.fir.declarations.fullyExpandedClass import org.jetbrains.kotlin.fir.declarations.utils.isExpect -import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.providers.dependenciesSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope @@ -34,15 +34,15 @@ object FirExpectActualResolver { is FirCallableSymbol<*> -> { val callableId = actualSymbol.callableId val classId = callableId.classId - var expectContainingClass: FirRegularClassSymbol? = null var actualContainingClass: FirRegularClassSymbol? = null + var expectContainingClass: FirRegularClassSymbol? = null val candidates = when { classId != null -> { - expectContainingClass = useSiteSession.dependenciesSymbolProvider.getClassLikeSymbolByClassId(classId)?.let { - it.fullyExpandedClass(it.moduleData.session) - } actualContainingClass = useSiteSession.symbolProvider.getClassLikeSymbolByClassId(classId) ?.fullyExpandedClass(useSiteSession) + expectContainingClass = actualContainingClass?.fir?.expectForActual + ?.get(ExpectActualMatchingCompatibility.MatchedSuccessfully) + ?.singleOrNull() as? FirRegularClassSymbol when (actualSymbol) { is FirConstructorSymbol -> expectContainingClass?.getConstructors(expectScopeSession) diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualClassWithDifferentConstructors.ll.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualClassWithDifferentConstructors.ll.kt index 649563e8234..42f73391273 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualClassWithDifferentConstructors.ll.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualClassWithDifferentConstructors.ll.kt @@ -46,7 +46,7 @@ actual class Bar5 { } class Bar6 { - actual constructor() + actual constructor() } actual class Bar7 actual constructor(s: String) { diff --git a/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualMissing.fir.kt b/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualMissing.fir.kt index 706414a06e9..a0d2ee32076 100644 --- a/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualMissing.fir.kt +++ b/compiler/testData/diagnostics/tests/multiplatform/headerClass/actualMissing.fir.kt @@ -9,5 +9,5 @@ expect class A { // FILE: jvm.kt class A { - actual fun foo() {} + actual fun foo() {} }