[FE1.0] Optimize search of expect class member in annotation checker

In the following scenario, when we search corresponding expect member
for actual `A.B`, we can skip checking compatibility of `B` scope.
```
class A {
  class B {
    fun foo() {}
  }
}
actual typealias AImpl = A
```

This is because:

1. Annotation checker runs no matter if found expect class is compatible
or not.
2. Class always has at most one corresponding `expect` class (unlike for
functions, which may have several overrides), so we are sure that we
found the right member.

^KT-60668
^KT-60936
This commit is contained in:
Roman Efremov
2023-08-17 16:16:27 +02:00
committed by Space Team
parent f1ea6545eb
commit b57940a59b
13 changed files with 102 additions and 11 deletions
@@ -396,11 +396,13 @@ class ClassicExpectActualMatchingContext(
expectClass: RegularClassSymbolMarker,
actualClass: RegularClassSymbolMarker,
actualMember: DeclarationSymbolMarker,
checkClassScopesCompatibility: Boolean,
): Map<MemberDescriptor, ExpectActualCompatibility<*>> {
val compatibilityToExpects = ExpectedActualResolver.findExpectForActualClassMember(
actualMember as MemberDescriptor,
actualClass as ClassDescriptor,
expectClass as ClassDescriptor,
checkClassScopesCompatibility,
this,
)
return buildMap {
@@ -46,6 +46,7 @@ object ExpectedActualResolver {
AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility(
expected,
actual,
checkClassScopesCompatibility = true,
context
)
}
@@ -58,6 +59,7 @@ object ExpectedActualResolver {
actual: MemberDescriptor,
actualClass: ClassDescriptor,
expectClass: ClassDescriptor,
checkClassScopesCompatibility: Boolean,
context: ClassicExpectActualMatchingContext,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>> {
val candidates = with(context) {
@@ -76,6 +78,7 @@ object ExpectedActualResolver {
matchActualClassAgainstPotentialExpects(
actual,
candidates.filterIsInstance<ClassifierDescriptorWithTypeParameters>(),
checkClassScopesCompatibility,
context
)
}
@@ -110,7 +113,7 @@ object ExpectedActualResolver {
}
is ClassifierDescriptorWithTypeParameters -> {
val candidates = context.findClassifiersFromModule(actual.classId, actual.module, moduleFilter)
matchActualClassAgainstPotentialExpects(actual, candidates, context)
matchActualClassAgainstPotentialExpects(actual, candidates, checkClassScopesCompatibility = true, context)
}
else -> null
}
@@ -158,6 +161,7 @@ object ExpectedActualResolver {
private fun matchActualClassAgainstPotentialExpects(
actual: ClassifierDescriptorWithTypeParameters,
candidates: Collection<ClassifierDescriptorWithTypeParameters>,
checkClassScopesCompatibility: Boolean,
context: ClassicExpectActualMatchingContext,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<ClassifierDescriptorWithTypeParameters>> {
return candidates.filter { declaration ->
@@ -166,6 +170,7 @@ object ExpectedActualResolver {
AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility(
expected as ClassDescriptor,
actual,
checkClassScopesCompatibility,
context
)
}