[frontend] refactoring, reuse org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeakCompatible

to avoid code duplication
This commit is contained in:
Ilya Kirillov
2023-09-06 10:56:45 +02:00
committed by Space Team
parent 030250d387
commit 190f7c4d30
3 changed files with 9 additions and 15 deletions
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatc
import org.jetbrains.kotlin.resolve.checkers.OptInNames import org.jetbrains.kotlin.resolve.checkers.OptInNames
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.* import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.*
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
@Suppress("DuplicatedCode") @Suppress("DuplicatedCode")
object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() { object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
@@ -205,7 +206,7 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
) { ) {
val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence() val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence()
.filter { (compatibility, _) -> .filter { (compatibility, _) ->
compatibility.isCompatibleOrWeakCompatible() compatibility.isCompatibleOrWeaklyIncompatible
} }
.map { (_, members) -> members } .map { (_, members) -> members }
.flatten() .flatten()
@@ -273,10 +274,6 @@ object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
return keys.all { it is Incompatible.StrongIncompatible } return keys.all { it is Incompatible.StrongIncompatible }
} }
private fun ExpectActualCompatibility<FirBasedSymbol<*>>.isCompatibleOrWeakCompatible(): Boolean {
return this is Compatible || this is Incompatible.WeakIncompatible
}
// we don't require `actual` modifier on // we don't require `actual` modifier on
// - annotation constructors, because annotation classes can only have one constructor // - annotation constructors, because annotation classes can only have one constructor
// - value class primary constructors, because value class must have primary constructor // - value class primary constructors, because value class must have primary constructor
@@ -13,10 +13,10 @@ import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.isCommon
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker.Companion.isCompatibleOrWeakCompatible
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.resolve.multiplatform.isCompatibleOrWeaklyIncompatible
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
object ExpectActualInTheSameModuleChecker : DeclarationChecker { object ExpectActualInTheSameModuleChecker : DeclarationChecker {
@@ -29,7 +29,7 @@ object ExpectActualInTheSameModuleChecker : DeclarationChecker {
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) return if (descriptor.containingDeclaration !is PackageFragmentDescriptor) return
val module = descriptor.module val module = descriptor.module
val actuals = ExpectedActualResolver.findActualForExpected(descriptor, module) val actuals = ExpectedActualResolver.findActualForExpected(descriptor, module)
?.filter { (compatibility, _) -> compatibility.isCompatibleOrWeakCompatible() } ?.filter { (compatibility, _) -> compatibility.isCompatibleOrWeaklyIncompatible }
?.flatMap { (_, members) -> members } ?.flatMap { (_, members) -> members }
?.takeIf(List<MemberDescriptor>::isNotEmpty) ?: return ?.takeIf(List<MemberDescriptor>::isNotEmpty) ?: return
@@ -125,7 +125,7 @@ class ExpectedActualDeclarationChecker(
context: DeclarationCheckerContext context: DeclarationCheckerContext
) { ) {
val actualMembers = actuals val actualMembers = actuals
.filter { (compatibility, _) -> compatibility.isCompatibleOrWeakCompatible() } .filter { (compatibility, _) -> compatibility.isCompatibleOrWeaklyIncompatible }
.flatMap { (_, members) -> members } .flatMap { (_, members) -> members }
.takeIf(List<MemberDescriptor>::isNotEmpty) .takeIf(List<MemberDescriptor>::isNotEmpty)
?: return ?: return
@@ -149,7 +149,7 @@ class ExpectedActualDeclarationChecker(
trace: BindingTrace, trace: BindingTrace,
) { ) {
val atLeastWeaklyCompatibleActuals = actuals val atLeastWeaklyCompatibleActuals = actuals
.filterKeys { compatibility -> compatibility.isCompatibleOrWeakCompatible() } .filterKeys { compatibility -> compatibility.isCompatibleOrWeaklyIncompatible }
.values.flatten() .values.flatten()
// Eagerly return here: We won't find a duplicate in any module path in this case // Eagerly return here: We won't find a duplicate in any module path in this case
@@ -217,7 +217,7 @@ class ExpectedActualDeclarationChecker(
// Here we have exactly one compatible actual and/or some weakly incompatible. In either case, we don't report anything on expect... // Here we have exactly one compatible actual and/or some weakly incompatible. In either case, we don't report anything on expect...
val actualMembers = actuals.asSequence() val actualMembers = actuals.asSequence()
.filter { it.key.isCompatibleOrWeakCompatible() }.flatMap { it.value.asSequence() } .filter { it.key.isCompatibleOrWeaklyIncompatible }.flatMap { it.value.asSequence() }
// ...except diagnostics regarding missing actual keyword, because in that case we won't start looking for the actual at all // ...except diagnostics regarding missing actual keyword, because in that case we won't start looking for the actual at all
if (checkActualModifier) { if (checkActualModifier) {
@@ -305,7 +305,7 @@ class ExpectedActualDeclarationChecker(
// For top-level declaration missing actual error reported in Actual checker // For top-level declaration missing actual error reported in Actual checker
if (checkActualModifier if (checkActualModifier
&& descriptor.containingDeclaration !is PackageFragmentDescriptor && descriptor.containingDeclaration !is PackageFragmentDescriptor
&& compatibility.any { it.key.isCompatibleOrWeakCompatible() } && compatibility.any { it.key.isCompatibleOrWeaklyIncompatible }
) { ) {
reportMissingActualModifier(descriptor, reportOn, trace) reportMissingActualModifier(descriptor, reportOn, trace)
} }
@@ -392,7 +392,7 @@ class ExpectedActualDeclarationChecker(
) { ) {
val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence() val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence()
.filter { (compatibility, _) -> .filter { (compatibility, _) ->
compatibility.isCompatibleOrWeakCompatible() compatibility.isCompatibleOrWeaklyIncompatible
} }
.map { (_, members) -> members } .map { (_, members) -> members }
.flatten() .flatten()
@@ -505,9 +505,6 @@ class ExpectedActualDeclarationChecker(
companion object { companion object {
fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean = fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
this.keys.all { it is Incompatible.StrongIncompatible } this.keys.all { it is Incompatible.StrongIncompatible }
internal fun ExpectActualCompatibility<MemberDescriptor>.isCompatibleOrWeakCompatible() =
this is Compatible || this is Incompatible.WeakIncompatible
} }
} }