diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt index a2370924baa..bd13cd4cc22 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt @@ -77,53 +77,71 @@ object ExpectedActualResolver { else -> return null // do not report anything for incorrect code, e.g. 'actual' local function } - candidates.filter { declaration -> - actual != declaration && declaration.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && declaration.isExpect - }.groupBy { declaration -> - // TODO: optimize by caching this per actual-expected class pair, do not create a new substitutor for each actual member - var expectedClass: ClassDescriptor? = null - var actualClass: ClassDescriptor? = null - val substitutor = - when (container) { - is ClassDescriptor -> { - actualClass = container - expectedClass = declaration.containingDeclaration as ClassDescriptor - // TODO: this might not work for members of inner generic classes - runIf(expectedClass.declaredTypeParameters.size == container.declaredTypeParameters.size) { - context.createExpectActualTypeParameterSubstitutor( - expectedClass.declaredTypeParameters, - container.declaredTypeParameters, - parentSubstitutor = null - ) - } - } - else -> null - } - AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( - expectDeclaration = declaration, - actualDeclaration = actual, - parentSubstitutor = substitutor, - expectContainingClass = expectedClass, - actualContainingClass = actualClass, - context - ) - } + matchActualCallableAgainstPotentialExpects(actual, candidates, container, context) } is ClassifierDescriptorWithTypeParameters -> { - context.findClassifiersFromModule(actual.classId, actual.module, moduleFilter).filter { declaration -> - actual != declaration && declaration is ClassDescriptor && declaration.isExpect - }.groupBy { expected -> - AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility( - expected as ClassDescriptor, - actual, - context - ) - } + val candidates = context.findClassifiersFromModule(actual.classId, actual.module, moduleFilter) + matchActualClassAgainstPotentialExpects(actual, candidates, context) } else -> null } } + private fun matchActualCallableAgainstPotentialExpects( + actual: CallableMemberDescriptor, + candidates: Collection, + container: DeclarationDescriptor, + context: ClassicExpectActualMatchingContext, + ): Map, List> { + return candidates.filter { declaration -> + actual != declaration && declaration.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && declaration.isExpect + }.groupBy { declaration -> + // TODO: optimize by caching this per actual-expected class pair, do not create a new substitutor for each actual member + var expectedClass: ClassDescriptor? = null + var actualClass: ClassDescriptor? = null + val substitutor = + when (container) { + is ClassDescriptor -> { + actualClass = container + expectedClass = declaration.containingDeclaration as ClassDescriptor + // TODO: this might not work for members of inner generic classes + runIf(expectedClass.declaredTypeParameters.size == container.declaredTypeParameters.size) { + context.createExpectActualTypeParameterSubstitutor( + expectedClass.declaredTypeParameters, + container.declaredTypeParameters, + parentSubstitutor = null + ) + } + } + else -> null + } + AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( + expectDeclaration = declaration, + actualDeclaration = actual, + parentSubstitutor = substitutor, + expectContainingClass = expectedClass, + actualContainingClass = actualClass, + context + ) + } + } + + private fun matchActualClassAgainstPotentialExpects( + actual: ClassifierDescriptorWithTypeParameters, + candidates: Collection, + context: ClassicExpectActualMatchingContext, + ): Map, List> { + return candidates.filter { declaration -> + actual != declaration && declaration is ClassDescriptor && declaration.isExpect + }.groupBy { expected -> + AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility( + expected as ClassDescriptor, + actual, + context + ) + } + } + private fun CallableMemberDescriptor.findNamesakesFromModule( context: ClassicExpectActualMatchingContext, module: ModuleDescriptor,