2/2 Extract K1 KMP matcher in its own subsystem. Fix compilation errors

This commit is contained in:
Nikita Bobko
2023-10-04 16:55:04 +02:00
committed by teamcity
parent cc70f78027
commit 43c97077eb
16 changed files with 224 additions and 274 deletions
@@ -15,8 +15,8 @@ import org.jetbrains.kotlin.analysis.api.symbols.psiSafe
import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility
internal class KtFe10MultiplatformInfoProvider( internal class KtFe10MultiplatformInfoProvider(
override val analysisSession: KtFe10AnalysisSession, override val analysisSession: KtFe10AnalysisSession,
@@ -28,7 +28,7 @@ internal class KtFe10MultiplatformInfoProvider(
val expectedCompatibilityMap = val expectedCompatibilityMap =
ExpectedActualResolver.findExpectedForActual(memberDescriptor) ?: return emptyList() ExpectedActualResolver.findExpectedForActual(memberDescriptor) ?: return emptyList()
val expectsForActual = (expectedCompatibilityMap[ExpectActualCompatibility.Compatible] val expectsForActual = (expectedCompatibilityMap[K1ExpectActualCompatibility.Compatible]
?: expectedCompatibilityMap.values.flatten()) ?: expectedCompatibilityMap.values.flatten())
return expectsForActual.map { it.toKtSymbol(analysisContext) as KtDeclarationSymbol } return expectsForActual.map { it.toKtSymbol(analysisContext) as KtDeclarationSymbol }
} }
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.modalityModifier import org.jetbrains.kotlin.psi.psiUtil.modalityModifier
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility
object ClassicPositioningStrategies { object ClassicPositioningStrategies {
@JvmField @JvmField
@@ -30,14 +30,14 @@ object ClassicPositioningStrategies {
} }
// TODO: move to specific strategies // TODO: move to specific strategies
private val DiagnosticMarker.firstIncompatibility: ExpectActualCompatibility.Incompatible<MemberDescriptor>? private val DiagnosticMarker.firstIncompatibility: K1ExpectActualCompatibility.Incompatible<MemberDescriptor>?
get() { get() {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val map = when (factoryName) { val map = when (factoryName) {
Errors.NO_ACTUAL_FOR_EXPECT.name -> (this as DiagnosticWithParameters3Marker<*, *, *>).c Errors.NO_ACTUAL_FOR_EXPECT.name -> (this as DiagnosticWithParameters3Marker<*, *, *>).c
Errors.ACTUAL_WITHOUT_EXPECT.name -> (this as DiagnosticWithParameters2Marker<*, *>).b Errors.ACTUAL_WITHOUT_EXPECT.name -> (this as DiagnosticWithParameters2Marker<*, *>).b
else -> null else -> null
} as? Map<ExpectActualCompatibility.Incompatible<MemberDescriptor>, Collection<MemberDescriptor>> ?: return null } as? Map<K1ExpectActualCompatibility.Incompatible<MemberDescriptor>, Collection<MemberDescriptor>> ?: return null
return map.keys.firstOrNull() return map.keys.firstOrNull()
} }
@@ -49,9 +49,9 @@ object ClassicPositioningStrategies {
val callableDeclaration = element as? KtCallableDeclaration val callableDeclaration = element as? KtCallableDeclaration
val incompatibility = diagnostic.firstIncompatibility val incompatibility = diagnostic.firstIncompatibility
return when (incompatibility) { return when (incompatibility) {
null, is ExpectActualCompatibility.Incompatible.ClassScopes, null, is K1ExpectActualCompatibility.Incompatible.ClassScopes,
ExpectActualCompatibility.Incompatible.EnumEntries -> null K1ExpectActualCompatibility.Incompatible.EnumEntries -> null
ExpectActualCompatibility.Incompatible.ClassKind -> { K1ExpectActualCompatibility.Incompatible.ClassKind -> {
val startElement = val startElement =
element.modifierList?.getModifier(KtTokens.ENUM_KEYWORD) element.modifierList?.getModifier(KtTokens.ENUM_KEYWORD)
?: element.modifierList?.getModifier(KtTokens.ANNOTATION_KEYWORD) ?: element.modifierList?.getModifier(KtTokens.ANNOTATION_KEYWORD)
@@ -64,53 +64,53 @@ object ClassicPositioningStrategies {
endElement endElement
} }
} }
ExpectActualCompatibility.Incompatible.TypeParameterNames, K1ExpectActualCompatibility.Incompatible.TypeParameterNames,
ExpectActualCompatibility.Incompatible.FunctionTypeParameterCount, K1ExpectActualCompatibility.Incompatible.FunctionTypeParameterCount,
ExpectActualCompatibility.Incompatible.ClassTypeParameterCount, K1ExpectActualCompatibility.Incompatible.ClassTypeParameterCount,
ExpectActualCompatibility.Incompatible.FunctionTypeParameterUpperBounds, K1ExpectActualCompatibility.Incompatible.FunctionTypeParameterUpperBounds,
ExpectActualCompatibility.Incompatible.ClassTypeParameterUpperBounds, K1ExpectActualCompatibility.Incompatible.ClassTypeParameterUpperBounds,
ExpectActualCompatibility.Incompatible.TypeParameterVariance, K1ExpectActualCompatibility.Incompatible.TypeParameterVariance,
ExpectActualCompatibility.Incompatible.TypeParameterReified -> { K1ExpectActualCompatibility.Incompatible.TypeParameterReified -> {
(element as? KtTypeParameterListOwner)?.typeParameterList (element as? KtTypeParameterListOwner)?.typeParameterList
} }
ExpectActualCompatibility.Incompatible.CallableKind -> { K1ExpectActualCompatibility.Incompatible.CallableKind -> {
(callableDeclaration as? KtNamedFunction)?.funKeyword (callableDeclaration as? KtNamedFunction)?.funKeyword
?: (callableDeclaration as? KtProperty)?.valOrVarKeyword ?: (callableDeclaration as? KtProperty)?.valOrVarKeyword
} }
ExpectActualCompatibility.Incompatible.ParameterShape -> { K1ExpectActualCompatibility.Incompatible.ParameterShape -> {
callableDeclaration?.let { it.receiverTypeReference ?: it.valueParameterList } callableDeclaration?.let { it.receiverTypeReference ?: it.valueParameterList }
} }
ExpectActualCompatibility.Incompatible.ParameterCount, ExpectActualCompatibility.Incompatible.ParameterTypes, K1ExpectActualCompatibility.Incompatible.ParameterCount, K1ExpectActualCompatibility.Incompatible.ParameterTypes,
ExpectActualCompatibility.Incompatible.ParameterNames, ExpectActualCompatibility.Incompatible.ValueParameterVararg, K1ExpectActualCompatibility.Incompatible.ParameterNames, K1ExpectActualCompatibility.Incompatible.ValueParameterVararg,
ExpectActualCompatibility.Incompatible.ActualFunctionWithDefaultParameters, K1ExpectActualCompatibility.Incompatible.ActualFunctionWithDefaultParameters,
ExpectActualCompatibility.Incompatible.ValueParameterNoinline, K1ExpectActualCompatibility.Incompatible.ValueParameterNoinline,
ExpectActualCompatibility.Incompatible.ValueParameterCrossinline -> { K1ExpectActualCompatibility.Incompatible.ValueParameterCrossinline -> {
callableDeclaration?.valueParameterList callableDeclaration?.valueParameterList
} }
ExpectActualCompatibility.Incompatible.ReturnType -> { K1ExpectActualCompatibility.Incompatible.ReturnType -> {
callableDeclaration?.typeReference callableDeclaration?.typeReference
} }
ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent, K1ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent,
ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset, K1ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset,
ExpectActualCompatibility.Incompatible.PropertyLateinitModifier, K1ExpectActualCompatibility.Incompatible.PropertyLateinitModifier,
ExpectActualCompatibility.Incompatible.PropertyConstModifier, K1ExpectActualCompatibility.Incompatible.PropertyConstModifier,
ExpectActualCompatibility.Incompatible.ClassModifiers, K1ExpectActualCompatibility.Incompatible.ClassModifiers,
ExpectActualCompatibility.Incompatible.FunInterfaceModifier -> { K1ExpectActualCompatibility.Incompatible.FunInterfaceModifier -> {
element.modifierList element.modifierList
} }
ExpectActualCompatibility.Incompatible.PropertyKind -> { K1ExpectActualCompatibility.Incompatible.PropertyKind -> {
element.node.findChildByType(PositioningStrategies.propertyKindTokens)?.psi element.node.findChildByType(PositioningStrategies.propertyKindTokens)?.psi
} }
ExpectActualCompatibility.Incompatible.Supertypes -> { K1ExpectActualCompatibility.Incompatible.Supertypes -> {
(element as? KtClassOrObject)?.getSuperTypeList() (element as? KtClassOrObject)?.getSuperTypeList()
} }
ExpectActualCompatibility.Incompatible.Modality -> { K1ExpectActualCompatibility.Incompatible.Modality -> {
element.modalityModifier() element.modalityModifier()
} }
ExpectActualCompatibility.Incompatible.Visibility -> { K1ExpectActualCompatibility.Incompatible.Visibility -> {
element.visibilityModifier() element.visibilityModifier()
} }
ExpectActualCompatibility.Incompatible.PropertySetterVisibility -> { K1ExpectActualCompatibility.Incompatible.PropertySetterVisibility -> {
(element as? KtProperty)?.setter?.modifierList (element as? KtProperty)?.setter?.modifierList
} }
}?.let { markElement(it) } ?: ACTUAL_DECLARATION_NAME.mark(element) }?.let { markElement(it) } ?: ACTUAL_DECLARATION_NAME.mark(element)
@@ -35,8 +35,8 @@ import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
import org.jetbrains.kotlin.resolve.calls.util.BuilderLambdaLabelingInfo; import org.jetbrains.kotlin.resolve.calls.util.BuilderLambdaLabelingInfo;
import org.jetbrains.kotlin.resolve.deprecation.DescriptorBasedDeprecationInfo; import org.jetbrains.kotlin.resolve.deprecation.DescriptorBasedDeprecationInfo;
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType; import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType;
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible; import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.Incompatible;
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMemberDiff; import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualMemberDiff;
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData; import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
@@ -837,26 +837,26 @@ public interface Errors {
DiagnosticFactory1<KtNamedDeclaration, MemberDescriptor> EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); DiagnosticFactory1<KtNamedDeclaration, MemberDescriptor> EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory3<KtClassLikeDeclaration, ClassifierDescriptorWithTypeParameters, Set<ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>, ClassDescriptor> DiagnosticFactory3<KtClassLikeDeclaration, ClassifierDescriptorWithTypeParameters, Set<K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>, ClassDescriptor>
ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER_WARNING = ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_MEMBERS_AS_NON_FINAL_EXPECT_CLASSIFIER_WARNING =
DiagnosticFactory3.create(WARNING, DECLARATION_NAME); DiagnosticFactory3.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_RETURN_TYPE); RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_RETURN_TYPE);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, MODALITY_MODIFIER); MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, MODALITY_MODIFIER);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VISIBILITY_MODIFIER); VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VISIBILITY_MODIFIER);
DiagnosticFactory1<KtPropertyAccessor, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtPropertyAccessor, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
SETTER_VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VISIBILITY_MODIFIER); SETTER_VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VISIBILITY_MODIFIER);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
PARAMETER_NAME_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); PARAMETER_NAME_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
PROPERTY_KIND_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VAL_OR_VAR_NODE); PROPERTY_KIND_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, VAL_OR_VAR_NODE);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, LATEINIT_MODIFIER); LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, LATEINIT_MODIFIER);
DiagnosticFactory1<KtCallableDeclaration, ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> DiagnosticFactory1<KtCallableDeclaration, K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>
TYPE_PARAMETER_NAMES_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, TYPE_PARAMETERS_OR_DECLARATION_SIGNATURE); TYPE_PARAMETER_NAMES_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING = DiagnosticFactory1.create(WARNING, TYPE_PARAMETERS_OR_DECLARATION_SIGNATURE);
DiagnosticFactory3<KtClassLikeDeclaration, ClassifierDescriptorWithTypeParameters, List<Name>, ClassDescriptor> DiagnosticFactory3<KtClassLikeDeclaration, ClassifierDescriptorWithTypeParameters, List<Name>, ClassDescriptor>
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic; import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic;
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement; import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement;
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData; import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData;
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible; import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.Incompatible;
import org.jetbrains.kotlin.types.KotlinTypeKt; import org.jetbrains.kotlin.types.KotlinTypeKt;
import org.jetbrains.kotlin.util.OperatorNameConventions; import org.jetbrains.kotlin.util.OperatorNameConventions;
import org.jetbrains.kotlin.utils.addToStdlib.AddToStdlibKt; import org.jetbrains.kotlin.utils.addToStdlib.AddToStdlibKt;
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.Incompatible
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMemberDiff import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualMemberDiff
import java.text.MessageFormat import java.text.MessageFormat
class PlatformIncompatibilityDiagnosticRenderer( class PlatformIncompatibilityDiagnosticRenderer(
@@ -68,9 +68,9 @@ class IncompatibleExpectedActualClassScopesRenderer(
class ExpectActualScopeDiffsRenderer( class ExpectActualScopeDiffsRenderer(
private val mode: MultiplatformDiagnosticRenderingMode, private val mode: MultiplatformDiagnosticRenderingMode,
) : DiagnosticParameterRenderer<Set<ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>> { ) : DiagnosticParameterRenderer<Set<K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>> {
override fun render( override fun render(
obj: Set<ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>, obj: Set<K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>>,
renderingContext: RenderingContext, renderingContext: RenderingContext,
): String { ): String {
check(obj.isNotEmpty()) check(obj.isNotEmpty())
@@ -90,9 +90,9 @@ class ExpectActualScopeDiffsRenderer(
} }
} }
object ExpectActualScopeDiffRenderer : DiagnosticParameterRenderer<ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> { object ExpectActualScopeDiffRenderer : DiagnosticParameterRenderer<K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> {
override fun render( override fun render(
obj: ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>, obj: K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>,
renderingContext: RenderingContext, renderingContext: RenderingContext,
): String = MessageFormat.format( ): String = MessageFormat.format(
obj.kind.rawMessage, obj.kind.rawMessage,
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualCompatibilityChecker import org.jetbrains.kotlin.resolve.multiplatform.K1AbstractExpectActualCompatibilityChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
@@ -124,7 +124,7 @@ internal fun matchActualWithNonFinalExpect(
if (actual.modality == Modality.FINAL) return null if (actual.modality == Modality.FINAL) return null
val expect = ExpectedActualResolver.findExpectedForActual(descriptor) val expect = ExpectedActualResolver.findExpectedForActual(descriptor)
?.get(ExpectActualCompatibility.Compatible) ?.get(K1ExpectActualCompatibility.Compatible)
?.singleOrNull() as? ClassDescriptor // if actual has more than one expects then it will be reported by another checker ?.singleOrNull() as? ClassDescriptor // if actual has more than one expects then it will be reported by another checker
?: return null ?: return null
@@ -135,7 +135,7 @@ internal fun matchActualWithNonFinalExpect(
private fun calculateExpectActualScopeDiff( private fun calculateExpectActualScopeDiff(
expect: ClassDescriptor, expect: ClassDescriptor,
actual: ClassDescriptor, actual: ClassDescriptor,
): Set<ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> { ): Set<K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>> {
val matchingContext = ClassicExpectActualMatchingContext(actual.module) val matchingContext = ClassicExpectActualMatchingContext(actual.module)
// It's responsibility of AbstractExpectActualCompatibilityChecker to report that. Most probably this check is redundant, // It's responsibility of AbstractExpectActualCompatibilityChecker to report that. Most probably this check is redundant,
// because we can't reach this line if expect and actual don't match, but let's have it for safety // because we can't reach this line if expect and actual don't match, but let's have it for safety
@@ -155,11 +155,11 @@ private fun calculateExpectActualScopeDiff(
return actualClassCallables.flatMap { actualMember -> return actualClassCallables.flatMap { actualMember ->
val potentialExpects = nameAndKindToExpectCallables[actualMember.name to actualMember.functionVsPropertyKind] val potentialExpects = nameAndKindToExpectCallables[actualMember.name to actualMember.functionVsPropertyKind]
if (potentialExpects.isNullOrEmpty()) { if (potentialExpects.isNullOrEmpty()) {
listOf(ExpectActualMemberDiff.Kind.NonPrivateCallableAdded) listOf(K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded)
} else { } else {
potentialExpects potentialExpects
.map { expectMember -> .map { expectMember ->
AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( K1AbstractExpectActualCompatibilityChecker.getCallablesCompatibility(
expectMember, expectMember,
actualMember, actualMember,
classTypeSubstitutor, classTypeSubstitutor,
@@ -168,22 +168,22 @@ private fun calculateExpectActualScopeDiff(
matchingContext matchingContext
) )
} }
.takeIf { kinds -> kinds.all { it != ExpectActualCompatibility.Compatible } } .takeIf { kinds -> kinds.all { it != K1ExpectActualCompatibility.Compatible } }
.orEmpty() .orEmpty()
.map { .map {
when (it) { when (it) {
is ExpectActualCompatibility.Compatible -> error("Compatible was filtered out by takeIf") is K1ExpectActualCompatibility.Compatible -> error("Compatible was filtered out by takeIf")
is ExpectActualCompatibility.Incompatible -> it.toMemberDiffKind() is K1ExpectActualCompatibility.Incompatible -> it.toMemberDiffKind()
// If toMemberDiffKind returns null then some Kotlin invariants described in toMemberDiffKind no longer hold. // If toMemberDiffKind returns null then some Kotlin invariants described in toMemberDiffKind no longer hold.
// We can't throw exception here because it would crash the compilation. // We can't throw exception here because it would crash the compilation.
// Those broken invariants just needs to be reported by other checkers. // Those broken invariants just needs to be reported by other checkers.
// But it's better to report some error (ExpectActualMemberDiff.Kind.NonPrivateCallableAdded in our case) to // But it's better to report some error (ExpectActualMemberDiff.Kind.NonPrivateCallableAdded in our case) to
// make sure that we don't have missed compilation errors if the invariants change // make sure that we don't have missed compilation errors if the invariants change
?: ExpectActualMemberDiff.Kind.NonPrivateCallableAdded ?: K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
} }
} }
} }
.map { kind -> ExpectActualMemberDiff(kind, actualMember, expect) } .map { kind -> K1ExpectActualMemberDiff(kind, actualMember, expect) }
}.toSet() }.toSet()
} }
@@ -206,26 +206,26 @@ private val CallableMemberDescriptor.functionVsPropertyKind: Kind
private val CallableMemberDescriptor.psiIfReal: KtCallableDeclaration? private val CallableMemberDescriptor.psiIfReal: KtCallableDeclaration?
get() = takeIf { it.kind.isReal }?.source?.let { it as? KotlinSourceElement }?.psi as? KtCallableDeclaration get() = takeIf { it.kind.isReal }?.source?.let { it as? KotlinSourceElement }?.psi as? KtCallableDeclaration
private fun BindingTrace.reportIfPossible(diff: ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>) { private fun BindingTrace.reportIfPossible(diff: K1ExpectActualMemberDiff<CallableMemberDescriptor, ClassDescriptor>) {
val psi = diff.actualMember.psiIfReal ?: return val psi = diff.actualMember.psiIfReal ?: return
val diagnostic = when (diff.kind) { val diagnostic = when (diff.kind) {
ExpectActualMemberDiff.Kind.NonPrivateCallableAdded -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded ->
Errors.NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.NON_ACTUAL_MEMBER_DECLARED_IN_EXPECT_NON_FINAL_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride -> K1ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride ->
Errors.RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.RETURN_TYPE_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.ModalityChangedInOverride -> K1ExpectActualMemberDiff.Kind.ModalityChangedInOverride ->
Errors.MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.MODALITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.VisibilityChangedInOverride -> K1ExpectActualMemberDiff.Kind.VisibilityChangedInOverride ->
Errors.VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride -> K1ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride ->
Errors.SETTER_VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on((psi as? KtProperty)?.setter ?: return, diff) Errors.SETTER_VISIBILITY_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on((psi as? KtProperty)?.setter ?: return, diff)
ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride -> K1ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride ->
Errors.PARAMETER_NAME_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.PARAMETER_NAME_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride -> K1ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride ->
Errors.PROPERTY_KIND_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.PROPERTY_KIND_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.LateinitChangedInOverride -> K1ExpectActualMemberDiff.Kind.LateinitChangedInOverride ->
Errors.LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.LATEINIT_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride -> K1ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride ->
Errors.TYPE_PARAMETER_NAMES_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff) Errors.TYPE_PARAMETER_NAMES_CHANGED_IN_NON_FINAL_EXPECT_CLASSIFIER_ACTUALIZATION_WARNING.on(psi, diff)
} }
report(diagnostic) report(diagnostic)
@@ -29,13 +29,13 @@ import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualAnnotationMatchChecker import org.jetbrains.kotlin.resolve.multiplatform.K1AbstractExpectActualAnnotationMatchChecker
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
import org.jetbrains.kotlin.resolve.descriptorUtil.isPrimaryConstructorOfInlineClass import org.jetbrains.kotlin.resolve.descriptorUtil.isPrimaryConstructorOfInlineClass
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.multiplatform.* import org.jetbrains.kotlin.resolve.multiplatform.*
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.* import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.resolve.source.PsiSourceFile import org.jetbrains.kotlin.resolve.source.PsiSourceFile
@@ -286,7 +286,7 @@ class ExpectedActualDeclarationChecker(
} }
private fun MemberDescriptor.hasNoActualWithDiagnostic( private fun MemberDescriptor.hasNoActualWithDiagnostic(
compatibility: Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>> compatibility: Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>
): Boolean { ): Boolean {
return compatibility.values.flatMapTo(hashSetOf()) { it }.all { actual -> return compatibility.values.flatMapTo(hashSetOf()) { it }.all { actual ->
val expectedOnes = ExpectedActualResolver.findExpectedForActual(actual, onlyFromThisModule(module)) val expectedOnes = ExpectedActualResolver.findExpectedForActual(actual, onlyFromThisModule(module))
@@ -406,7 +406,7 @@ class ExpectedActualDeclarationChecker(
} }
private fun checkAmbiguousExpects( private fun checkAmbiguousExpects(
compatibility: Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>, compatibility: Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>,
trace: BindingTrace, trace: BindingTrace,
reportOn: KtNamedDeclaration, reportOn: KtNamedDeclaration,
descriptor: MemberDescriptor descriptor: MemberDescriptor
@@ -514,7 +514,7 @@ class ExpectedActualDeclarationChecker(
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) return if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiplatformRestrictions)) return
val matchingContext = ClassicExpectActualMatchingContext(actualDescriptor.module) val matchingContext = ClassicExpectActualMatchingContext(actualDescriptor.module)
val incompatibility = val incompatibility =
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectDescriptor, actualDescriptor, matchingContext) ?: return K1AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectDescriptor, actualDescriptor, matchingContext) ?: return
val actualAnnotationTargetSourceElement = (incompatibility.actualAnnotationTargetElement as ClassicSourceElement).element val actualAnnotationTargetSourceElement = (incompatibility.actualAnnotationTargetElement as ClassicSourceElement).element
context.trace.report( context.trace.report(
Errors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on( Errors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on(
@@ -528,9 +528,9 @@ class ExpectedActualDeclarationChecker(
} }
companion object { companion object {
fun Map<out ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean = fun Map<out K1ExpectActualCompatibility<MemberDescriptor>, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
this.keys.all { it is Incompatible.StrongIncompatible } this.keys.all { it is Incompatible.StrongIncompatible }
} }
} }
private typealias ActualsMap = Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>> private typealias ActualsMap = Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>
@@ -15,11 +15,9 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualMatchingContext.AnnotationCallInfo
import org.jetbrains.kotlin.resolve.checkers.OptInNames import org.jetbrains.kotlin.resolve.checkers.OptInNames
import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualMatchingContext.AnnotationCallInfo
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
@@ -44,7 +42,7 @@ class ClassicExpectActualMatchingContext(
* Otherwise, it won't be possible to suppress the compilation error in user code * Otherwise, it won't be possible to suppress the compilation error in user code
*/ */
override val shouldCheckAbsenceOfDefaultParamsInActual: Boolean = false override val shouldCheckAbsenceOfDefaultParamsInActual: Boolean = false
) : ExpectActualMatchingContext<MemberDescriptor>, ) : K1ExpectActualMatchingContext<MemberDescriptor>,
TypeSystemContext by ClassicTypeSystemContextForCS(platformModule.builtIns, KotlinTypeRefiner.Default) { TypeSystemContext by ClassicTypeSystemContextForCS(platformModule.builtIns, KotlinTypeRefiner.Default) {
override val shouldCheckReturnTypesOfCallables: Boolean override val shouldCheckReturnTypesOfCallables: Boolean
get() = true get() = true
@@ -363,7 +361,7 @@ class ClassicExpectActualMatchingContext(
override fun areAnnotationArgumentsEqual( override fun areAnnotationArgumentsEqual(
expectAnnotation: AnnotationCallInfo, expectAnnotation: AnnotationCallInfo,
actualAnnotation: AnnotationCallInfo, actualAnnotation: AnnotationCallInfo,
collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, collectionArgumentsCompatibilityCheckStrategy: K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy,
): Boolean { ): Boolean {
fun AnnotationCallInfo.getDescriptor(): AnnotationDescriptor = (this as AnnotationCallInfoImpl).annotationDescriptor fun AnnotationCallInfo.getDescriptor(): AnnotationDescriptor = (this as AnnotationCallInfoImpl).annotationDescriptor
@@ -428,7 +426,7 @@ class ClassicExpectActualMatchingContext(
actualClass: RegularClassSymbolMarker, actualClass: RegularClassSymbolMarker,
actualMember: DeclarationSymbolMarker, actualMember: DeclarationSymbolMarker,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
): Map<MemberDescriptor, ExpectActualCompatibility<*>> { ): Map<MemberDescriptor, K1ExpectActualCompatibility<*>> {
val compatibilityToExpects = ExpectedActualResolver.findExpectForActualClassMember( val compatibilityToExpects = ExpectedActualResolver.findExpectForActualClassMember(
actualMember as MemberDescriptor, actualMember as MemberDescriptor,
actualClass as ClassDescriptor, actualClass as ClassDescriptor,
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.resolve.multiplatform package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.calls.mpp.AbstractExpectActualCompatibilityChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.resolve.descriptorUtil.classId
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Compatible import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.Compatible
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.utils.addToStdlib.runIf import org.jetbrains.kotlin.utils.addToStdlib.runIf
@@ -18,7 +17,7 @@ object ExpectedActualResolver {
expected: MemberDescriptor, expected: MemberDescriptor,
platformModule: ModuleDescriptor, platformModule: ModuleDescriptor,
moduleVisibilityFilter: ModuleFilter = allModulesProvidingActualsFor(expected.module, platformModule), moduleVisibilityFilter: ModuleFilter = allModulesProvidingActualsFor(expected.module, platformModule),
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? { ): Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
val context = ClassicExpectActualMatchingContext(platformModule) val context = ClassicExpectActualMatchingContext(platformModule)
return when (expected) { return when (expected) {
is CallableMemberDescriptor -> { is CallableMemberDescriptor -> {
@@ -29,7 +28,7 @@ object ExpectedActualResolver {
// TODO: support non-source definitions (e.g. from Java) // TODO: support non-source definitions (e.g. from Java)
actual.couldHaveASource actual.couldHaveASource
}.groupBy { actual -> }.groupBy { actual ->
AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( K1AbstractExpectActualCompatibilityChecker.getCallablesCompatibility(
expected, expected,
actual, actual,
parentSubstitutor = null, parentSubstitutor = null,
@@ -43,7 +42,7 @@ object ExpectedActualResolver {
context.findClassifiersFromModule(expected.classId, platformModule, moduleVisibilityFilter).filter { actual -> context.findClassifiersFromModule(expected.classId, platformModule, moduleVisibilityFilter).filter { actual ->
expected != actual && !actual.isExpect && actual.couldHaveASource expected != actual && !actual.isExpect && actual.couldHaveASource
}.groupBy { actual -> }.groupBy { actual ->
AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility( K1AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility(
expected, expected,
actual, actual,
checkClassScopesCompatibility = true, checkClassScopesCompatibility = true,
@@ -61,7 +60,7 @@ object ExpectedActualResolver {
expectClass: ClassDescriptor, expectClass: ClassDescriptor,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
context: ClassicExpectActualMatchingContext, context: ClassicExpectActualMatchingContext,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>> { ): Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>> {
val candidates = with(context) { val candidates = with(context) {
expectClass.getMembersForExpectClass(actual.name) expectClass.getMembersForExpectClass(actual.name)
} }
@@ -90,7 +89,7 @@ object ExpectedActualResolver {
actual: MemberDescriptor, actual: MemberDescriptor,
moduleFilter: (ModuleDescriptor) -> Boolean = allModulesProvidingExpectsFor(actual.module), moduleFilter: (ModuleDescriptor) -> Boolean = allModulesProvidingExpectsFor(actual.module),
shouldCheckAbsenceOfDefaultParamsInActual: Boolean = false, shouldCheckAbsenceOfDefaultParamsInActual: Boolean = false,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? { ): Map<K1ExpectActualCompatibility<MemberDescriptor>, List<MemberDescriptor>>? {
val context = ClassicExpectActualMatchingContext(actual.module, shouldCheckAbsenceOfDefaultParamsInActual) val context = ClassicExpectActualMatchingContext(actual.module, shouldCheckAbsenceOfDefaultParamsInActual)
return when (actual) { return when (actual) {
is CallableMemberDescriptor -> { is CallableMemberDescriptor -> {
@@ -124,7 +123,7 @@ object ExpectedActualResolver {
candidates: Collection<CallableMemberDescriptor>, candidates: Collection<CallableMemberDescriptor>,
container: DeclarationDescriptor, container: DeclarationDescriptor,
context: ClassicExpectActualMatchingContext, context: ClassicExpectActualMatchingContext,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<CallableMemberDescriptor>> { ): Map<K1ExpectActualCompatibility<MemberDescriptor>, List<CallableMemberDescriptor>> {
return candidates.filter { declaration -> return candidates.filter { declaration ->
actual != declaration && declaration.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && declaration.isExpect actual != declaration && declaration.kind != CallableMemberDescriptor.Kind.FAKE_OVERRIDE && declaration.isExpect
}.groupBy { declaration -> }.groupBy { declaration ->
@@ -147,7 +146,7 @@ object ExpectedActualResolver {
} }
else -> null else -> null
} }
AbstractExpectActualCompatibilityChecker.getCallablesCompatibility( K1AbstractExpectActualCompatibilityChecker.getCallablesCompatibility(
expectDeclaration = declaration, expectDeclaration = declaration,
actualDeclaration = actual, actualDeclaration = actual,
parentSubstitutor = substitutor, parentSubstitutor = substitutor,
@@ -163,11 +162,11 @@ object ExpectedActualResolver {
candidates: Collection<ClassifierDescriptorWithTypeParameters>, candidates: Collection<ClassifierDescriptorWithTypeParameters>,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
context: ClassicExpectActualMatchingContext, context: ClassicExpectActualMatchingContext,
): Map<ExpectActualCompatibility<MemberDescriptor>, List<ClassifierDescriptorWithTypeParameters>> { ): Map<K1ExpectActualCompatibility<MemberDescriptor>, List<ClassifierDescriptorWithTypeParameters>> {
return candidates.filter { declaration -> return candidates.filter { declaration ->
actual != declaration && declaration is ClassDescriptor && declaration.isExpect actual != declaration && declaration is ClassDescriptor && declaration.isExpect
}.groupBy { expected -> }.groupBy { expected ->
AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility( K1AbstractExpectActualCompatibilityChecker.getClassifiersCompatibility(
expected as ClassDescriptor, expected as ClassDescriptor,
actual, actual,
checkClassScopesCompatibility, checkClassScopesCompatibility,
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.resolve.calls.mpp package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.mpp.* import org.jetbrains.kotlin.mpp.*
@@ -11,10 +11,9 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.name.StandardClassIds
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.ExpectActualAnnotationsIncompatibilityType as IncompatibilityType import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType as IncompatibilityType
object AbstractExpectActualAnnotationMatchChecker { object K1AbstractExpectActualAnnotationMatchChecker {
private val SKIPPED_CLASS_IDS = setOf( private val SKIPPED_CLASS_IDS = setOf(
StandardClassIds.Annotations.Deprecated, StandardClassIds.Annotations.Deprecated,
StandardClassIds.Annotations.DeprecatedSinceKotlin, StandardClassIds.Annotations.DeprecatedSinceKotlin,
@@ -45,19 +44,18 @@ object AbstractExpectActualAnnotationMatchChecker {
* Needed for the implementation of IDE intention. * Needed for the implementation of IDE intention.
*/ */
val actualAnnotationTargetElement: SourceElementMarker, val actualAnnotationTargetElement: SourceElementMarker,
val type: IncompatibilityType<ExpectActualMatchingContext.AnnotationCallInfo>, val type: IncompatibilityType<K1ExpectActualMatchingContext.AnnotationCallInfo>,
) )
fun areAnnotationsCompatible( fun areAnnotationsCompatible(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker, actualSymbol: DeclarationSymbolMarker,
context: ExpectActualMatchingContext<*>, context: K1ExpectActualMatchingContext<*>,
): Incompatibility? = with(context) { ): Incompatibility? = with(context) {
areAnnotationsCompatible(expectSymbol, actualSymbol) areAnnotationsCompatible(expectSymbol, actualSymbol)
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areAnnotationsCompatible(
private fun areAnnotationsCompatible(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker, actualSymbol: DeclarationSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -72,8 +70,7 @@ object AbstractExpectActualAnnotationMatchChecker {
} }
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCallableAnnotationsCompatible(
private fun areCallableAnnotationsCompatible(
expectSymbol: CallableSymbolMarker, expectSymbol: CallableSymbolMarker,
actualSymbol: CallableSymbolMarker, actualSymbol: CallableSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -87,8 +84,7 @@ object AbstractExpectActualAnnotationMatchChecker {
return null return null
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.arePropertyGetterAndSetterAnnotationsCompatible(
private fun arePropertyGetterAndSetterAnnotationsCompatible(
expectSymbol: PropertySymbolMarker, expectSymbol: PropertySymbolMarker,
actualSymbol: PropertySymbolMarker, actualSymbol: PropertySymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -106,8 +102,7 @@ object AbstractExpectActualAnnotationMatchChecker {
return null return null
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areClassAnnotationsCompatible(
private fun areClassAnnotationsCompatible(
expectSymbol: RegularClassSymbolMarker, expectSymbol: RegularClassSymbolMarker,
actualSymbol: ClassLikeSymbolMarker, actualSymbol: ClassLikeSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -129,8 +124,7 @@ object AbstractExpectActualAnnotationMatchChecker {
return null return null
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.commonForClassAndCallableChecks(
private fun commonForClassAndCallableChecks(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker, actualSymbol: DeclarationSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -140,8 +134,7 @@ object AbstractExpectActualAnnotationMatchChecker {
return null return null
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areAnnotationsOnValueParametersCompatible(
private fun areAnnotationsOnValueParametersCompatible(
expectSymbol: CallableSymbolMarker, expectSymbol: CallableSymbolMarker,
actualSymbol: CallableSymbolMarker, actualSymbol: CallableSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -158,8 +151,7 @@ object AbstractExpectActualAnnotationMatchChecker {
} }
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areAnnotationsOnTypeParametersCompatible(
private fun areAnnotationsOnTypeParametersCompatible(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker, actualSymbol: DeclarationSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -183,8 +175,7 @@ object AbstractExpectActualAnnotationMatchChecker {
} }
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areAnnotationsSetOnDeclarationsCompatible(
private fun areAnnotationsSetOnDeclarationsCompatible(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbol: DeclarationSymbolMarker, actualSymbol: DeclarationSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -227,16 +218,15 @@ object AbstractExpectActualAnnotationMatchChecker {
} }
private fun getAnnotationCollectionArgumentsCompatibilityChecker(annotationClassId: ClassId): private fun getAnnotationCollectionArgumentsCompatibilityChecker(annotationClassId: ClassId):
ExpectActualCollectionArgumentsCompatibilityCheckStrategy { K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy {
return if (annotationClassId == StandardClassIds.Annotations.Target) { return if (annotationClassId == StandardClassIds.Annotations.Target) {
ExpectActualCollectionArgumentsCompatibilityCheckStrategy.ExpectIsSubsetOfActual K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy.ExpectIsSubsetOfActual
} else { } else {
ExpectActualCollectionArgumentsCompatibilityCheckStrategy.Default K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy.Default
} }
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.checkAnnotationsInClassMemberScope(
private fun checkAnnotationsInClassMemberScope(
expectClass: RegularClassSymbolMarker, expectClass: RegularClassSymbolMarker,
actualClass: RegularClassSymbolMarker, actualClass: RegularClassSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -252,7 +242,7 @@ object AbstractExpectActualAnnotationMatchChecker {
// so we are sure that we found the right member. // so we are sure that we found the right member.
checkClassScopesCompatibility = false, checkClassScopesCompatibility = false,
) )
val expectMember = expectToCompatibilityMap.filter { it.value == ExpectActualCompatibility.Compatible }.keys.singleOrNull() val expectMember = expectToCompatibilityMap.filter { it.value == K1ExpectActualCompatibility.Compatible }.keys.singleOrNull()
// Check also incompatible members if only one is found // Check also incompatible members if only one is found
?: expectToCompatibilityMap.keys.singleOrNull() ?: expectToCompatibilityMap.keys.singleOrNull()
?: continue ?: continue
@@ -261,8 +251,7 @@ object AbstractExpectActualAnnotationMatchChecker {
return null return null
} }
context (ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.checkAnnotationsOnEnumEntries(
private fun checkAnnotationsOnEnumEntries(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
): Incompatibility? { ): Incompatibility? {
@@ -3,7 +3,9 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.resolve.calls.mpp @file:Suppress("DuplicatedCode") // Yes, it's duplicated. But it doesn't matter, K1 version will just die eventually
package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -12,8 +14,7 @@ import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.mpp.* import org.jetbrains.kotlin.mpp.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility import org.jetbrains.kotlin.resolve.multiplatform.K1ExpectActualCompatibility.Incompatible
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
@@ -22,18 +23,18 @@ import org.jetbrains.kotlin.utils.addToStdlib.enumSetOf
import org.jetbrains.kotlin.utils.keysToMap import org.jetbrains.kotlin.utils.keysToMap
import java.util.* import java.util.*
object AbstractExpectActualCompatibilityChecker { object K1AbstractExpectActualCompatibilityChecker {
fun <T : DeclarationSymbolMarker> getClassifiersCompatibility( fun <T : DeclarationSymbolMarker> getClassifiersCompatibility(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassLikeSymbol: ClassLikeSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
context: ExpectActualMatchingContext<T>, context: K1ExpectActualMatchingContext<T>,
): ExpectActualCompatibility<T> { ): K1ExpectActualCompatibility<T> {
val result = with(context) { val result = with(context) {
getClassifiersCompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor = null, checkClassScopesCompatibility) getClassifiersCompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor = null, checkClassScopesCompatibility)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return result as ExpectActualCompatibility<T> return result as K1ExpectActualCompatibility<T>
} }
fun <T : DeclarationSymbolMarker> getCallablesCompatibility( fun <T : DeclarationSymbolMarker> getCallablesCompatibility(
@@ -42,53 +43,33 @@ object AbstractExpectActualCompatibilityChecker {
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
expectContainingClass: RegularClassSymbolMarker?, expectContainingClass: RegularClassSymbolMarker?,
actualContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?,
context: ExpectActualMatchingContext<T>, context: K1ExpectActualMatchingContext<T>,
): ExpectActualCompatibility<T> { ): K1ExpectActualCompatibility<T> {
val result = with(context) { val result = with(context) {
getCallablesCompatibility(expectDeclaration, actualDeclaration, parentSubstitutor, expectContainingClass, actualContainingClass) getCallablesCompatibility(expectDeclaration, actualDeclaration, parentSubstitutor, expectContainingClass, actualContainingClass)
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return result as ExpectActualCompatibility<T> return result as K1ExpectActualCompatibility<T>
} }
fun <T : DeclarationSymbolMarker> matchSingleExpectTopLevelDeclarationAgainstPotentialActuals(
expectDeclaration: DeclarationSymbolMarker,
actualDeclarations: List<DeclarationSymbolMarker>,
context: ExpectActualMatchingContext<T>,
) {
with(context) {
matchSingleExpectAgainstPotentialActuals(
expectDeclaration,
actualDeclarations,
substitutor = null,
expectClassSymbol = null,
actualClassSymbol = null,
unfulfilled = null,
checkClassScopesCompatibility = true,
)
}
}
context(ExpectActualMatchingContext<*>)
@Suppress("warnings") @Suppress("warnings")
private fun getClassifiersCompatibility( private fun K1ExpectActualMatchingContext<*>.getClassifiersCompatibility(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassLikeSymbol: ClassLikeSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker,
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
checkClassScopes: Boolean, checkClassScopes: Boolean,
): ExpectActualCompatibility<*> = getClassifiersIncompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor, checkClassScopes) ): K1ExpectActualCompatibility<*> = getClassifiersIncompatibility(expectClassSymbol, actualClassLikeSymbol, parentSubstitutor, checkClassScopes)
?: ExpectActualCompatibility.Compatible ?: K1ExpectActualCompatibility.Compatible
context(ExpectActualMatchingContext<*>)
@Suppress("warnings") @Suppress("warnings")
private fun getClassifiersIncompatibility( private fun K1ExpectActualMatchingContext<*>.getClassifiersIncompatibility(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassLikeSymbol: ClassLikeSymbolMarker, actualClassLikeSymbol: ClassLikeSymbolMarker,
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
): ExpectActualCompatibility.Incompatible.WeakIncompatible<*>? { ): K1ExpectActualCompatibility.Incompatible.WeakIncompatible<*>? {
// Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name // Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name
require(expectClassSymbol.name == actualClassLikeSymbol.name) { require(expectClassSymbol.getName(this) == actualClassLikeSymbol.getName(this)) {
"This function should be invoked only for declarations with the same name: $expectClassSymbol, $actualClassLikeSymbol" "This function should be invoked only for declarations with the same name: $expectClassSymbol, $actualClassLikeSymbol"
} }
@@ -147,8 +128,7 @@ object AbstractExpectActualCompatibilityChecker {
return null return null
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleSupertypes(
private fun areCompatibleSupertypes(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
@@ -159,8 +139,7 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleSupertypesOneByOne(
private fun areCompatibleSupertypesOneByOne(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
@@ -177,8 +156,7 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleSupertypesTransitive(
private fun areCompatibleSupertypesTransitive(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
@@ -193,20 +171,19 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getClassScopesIncompatibility(
private fun getClassScopesIncompatibility(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
): Incompatible.WeakIncompatible<*>? { ): Incompatible.WeakIncompatible<*>? {
val unfulfilled = arrayListOf<Pair<DeclarationSymbolMarker, Map<Incompatible<*>, List<DeclarationSymbolMarker?>>>>() val unfulfilled = arrayListOf<Pair<DeclarationSymbolMarker, Map<Incompatible<*>, List<DeclarationSymbolMarker?>>>>()
val actualMembersByName = actualClassSymbol.collectAllMembers(isActualDeclaration = true).groupBy { it.name } val actualMembersByName = actualClassSymbol.collectAllMembers(isActualDeclaration = true).groupBy { it.getName(this) }
outer@ for (expectMember in expectClassSymbol.collectAllMembers(isActualDeclaration = false)) { outer@ for (expectMember in expectClassSymbol.collectAllMembers(isActualDeclaration = false)) {
if (expectMember is CallableSymbolMarker && expectMember.shouldSkipMatching(expectClassSymbol)) continue if (expectMember is CallableSymbolMarker && expectMember.shouldSkipMatching(expectClassSymbol)) continue
val actualMembers = actualMembersByName[expectMember.name]?.filter { actualMember -> val actualMembers = actualMembersByName[expectMember.getName(this)]?.filter { actualMember ->
expectMember is CallableSymbolMarker && actualMember is CallableSymbolMarker || expectMember is CallableSymbolMarker && actualMember is CallableSymbolMarker ||
expectMember is RegularClassSymbolMarker && actualMember is RegularClassSymbolMarker expectMember is RegularClassSymbolMarker && actualMember is RegularClassSymbolMarker
}.orEmpty() }.orEmpty()
@@ -236,8 +213,7 @@ object AbstractExpectActualCompatibilityChecker {
return Incompatible.ClassScopes(unfulfilled) return Incompatible.ClassScopes(unfulfilled)
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.matchSingleExpectAgainstPotentialActuals(
private fun matchSingleExpectAgainstPotentialActuals(
expectMember: DeclarationSymbolMarker, expectMember: DeclarationSymbolMarker,
actualMembers: List<DeclarationSymbolMarker>, actualMembers: List<DeclarationSymbolMarker>,
substitutor: TypeSubstitutorMarker?, substitutor: TypeSubstitutorMarker?,
@@ -272,7 +248,7 @@ object AbstractExpectActualCompatibilityChecker {
val incompatibilityMap = mutableMapOf<Incompatible<*>, MutableList<DeclarationSymbolMarker>>() val incompatibilityMap = mutableMapOf<Incompatible<*>, MutableList<DeclarationSymbolMarker>>()
for ((actualMember, compatibility) in mapping) { for ((actualMember, compatibility) in mapping) {
when (compatibility) { when (compatibility) {
ExpectActualCompatibility.Compatible -> { K1ExpectActualCompatibility.Compatible -> {
onMatchedMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol) onMatchedMembers(expectMember, actualMember, expectClassSymbol, actualClassSymbol)
return return
} }
@@ -285,14 +261,13 @@ object AbstractExpectActualCompatibilityChecker {
onMismatchedMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol) onMismatchedMembersFromClassScope(expectMember, incompatibilityMap, expectClassSymbol, actualClassSymbol)
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getCallablesCompatibility(
private fun getCallablesCompatibility(
expectDeclaration: CallableSymbolMarker, expectDeclaration: CallableSymbolMarker,
actualDeclaration: CallableSymbolMarker, actualDeclaration: CallableSymbolMarker,
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
expectContainingClass: RegularClassSymbolMarker?, expectContainingClass: RegularClassSymbolMarker?,
actualContainingClass: RegularClassSymbolMarker?, actualContainingClass: RegularClassSymbolMarker?,
): ExpectActualCompatibility<*> { ): K1ExpectActualCompatibility<*> {
require( require(
(expectDeclaration is ConstructorSymbolMarker && actualDeclaration is ConstructorSymbolMarker) || (expectDeclaration is ConstructorSymbolMarker && actualDeclaration is ConstructorSymbolMarker) ||
expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName
@@ -310,17 +285,16 @@ object AbstractExpectActualCompatibilityChecker {
expectDeclaration is ConstructorSymbolMarker && expectDeclaration is ConstructorSymbolMarker &&
actualDeclaration is ConstructorSymbolMarker actualDeclaration is ConstructorSymbolMarker
) { ) {
return ExpectActualCompatibility.Compatible return K1ExpectActualCompatibility.Compatible
} }
// We must prioritize to return STRONG incompatible over WEAK incompatible (because STRONG incompatibility allows to search for overloads) // We must prioritize to return STRONG incompatible over WEAK incompatible (because STRONG incompatibility allows to search for overloads)
return getCallablesStrongIncompatibility(expectDeclaration, actualDeclaration, parentSubstitutor) return getCallablesStrongIncompatibility(expectDeclaration, actualDeclaration, parentSubstitutor)
?: getCallablesWeakIncompatibility(expectDeclaration, actualDeclaration, expectContainingClass, actualContainingClass) ?: getCallablesWeakIncompatibility(expectDeclaration, actualDeclaration, expectContainingClass, actualContainingClass)
?: ExpectActualCompatibility.Compatible ?: K1ExpectActualCompatibility.Compatible
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getCallablesStrongIncompatibility(
private fun getCallablesStrongIncompatibility(
expectDeclaration: CallableSymbolMarker, expectDeclaration: CallableSymbolMarker,
actualDeclaration: CallableSymbolMarker, actualDeclaration: CallableSymbolMarker,
parentSubstitutor: TypeSubstitutorMarker?, parentSubstitutor: TypeSubstitutorMarker?,
@@ -355,8 +329,8 @@ object AbstractExpectActualCompatibilityChecker {
if ( if (
!areCompatibleTypeLists( !areCompatibleTypeLists(
expectedValueParameters.toTypeList(substitutor), expectedValueParameters.toTypeList(substitutor, this),
actualValueParameters.toTypeList(createEmptySubstitutor()) actualValueParameters.toTypeList(createEmptySubstitutor(), this)
) || ) ||
!areCompatibleExpectActualTypes( !areCompatibleExpectActualTypes(
expectedReceiverType?.let { substitutor.safeSubstitute(it) }, expectedReceiverType?.let { substitutor.safeSubstitute(it) },
@@ -379,8 +353,7 @@ object AbstractExpectActualCompatibilityChecker {
return null return null
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getCallablesWeakIncompatibility(
private fun getCallablesWeakIncompatibility(
expectDeclaration: CallableSymbolMarker, expectDeclaration: CallableSymbolMarker,
actualDeclaration: CallableSymbolMarker, actualDeclaration: CallableSymbolMarker,
expectContainingClass: RegularClassSymbolMarker?, expectContainingClass: RegularClassSymbolMarker?,
@@ -391,11 +364,11 @@ object AbstractExpectActualCompatibilityChecker {
val expectedValueParameters = expectDeclaration.valueParameters val expectedValueParameters = expectDeclaration.valueParameters
val actualValueParameters = actualDeclaration.valueParameters val actualValueParameters = actualDeclaration.valueParameters
if (actualDeclaration.hasStableParameterNames && !equalsBy(expectedValueParameters, actualValueParameters) { it.name }) { if (actualDeclaration.hasStableParameterNames && !equalsBy(expectedValueParameters, actualValueParameters) { it.getName(this) }) {
return Incompatible.ParameterNames return Incompatible.ParameterNames
} }
if (!equalsBy(expectedTypeParameters, actualTypeParameters) { it.name }) { if (!equalsBy(expectedTypeParameters, actualTypeParameters) { it.getName(this) }) {
return Incompatible.TypeParameterNames return Incompatible.TypeParameterNames
} }
@@ -465,8 +438,7 @@ object AbstractExpectActualCompatibilityChecker {
return null return null
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.valueParametersCountCompatible(
private fun valueParametersCountCompatible(
expectDeclaration: CallableSymbolMarker, expectDeclaration: CallableSymbolMarker,
actualDeclaration: CallableSymbolMarker, actualDeclaration: CallableSymbolMarker,
expectValueParameters: List<ValueParameterSymbolMarker>, expectValueParameters: List<ValueParameterSymbolMarker>,
@@ -481,8 +453,7 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleTypeLists(
private fun areCompatibleTypeLists(
expectedTypes: List<KotlinTypeMarker?>, expectedTypes: List<KotlinTypeMarker?>,
actualTypes: List<KotlinTypeMarker?>, actualTypes: List<KotlinTypeMarker?>,
): Boolean { ): Boolean {
@@ -494,14 +465,13 @@ object AbstractExpectActualCompatibilityChecker {
return true return true
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleClassKinds(
private fun areCompatibleClassKinds(
expectClass: RegularClassSymbolMarker, expectClass: RegularClassSymbolMarker,
actualClass: RegularClassSymbolMarker, actualClass: RegularClassSymbolMarker,
): Boolean { ): Boolean {
if (expectClass.classKind == actualClass.classKind) return true if (expectClass.classKind == actualClass.classKind) return true
if (expectClass.classKind == ClassKind.CLASS && expectClass.isFinal && expectClass.isCtorless) { if (expectClass.classKind == ClassKind.CLASS && expectClass.isFinal(this@areCompatibleClassKinds) && expectClass.isCtorless(this@areCompatibleClassKinds)) {
if (actualClass.classKind == ClassKind.OBJECT) return true if (actualClass.classKind == ClassKind.OBJECT) return true
} }
@@ -555,8 +525,7 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleClassVisibilities(
private fun areCompatibleClassVisibilities(
expectClassSymbol: RegularClassSymbolMarker, expectClassSymbol: RegularClassSymbolMarker,
actualClassSymbol: RegularClassSymbolMarker, actualClassSymbol: RegularClassSymbolMarker,
): Boolean { ): Boolean {
@@ -568,8 +537,7 @@ object AbstractExpectActualCompatibilityChecker {
return result != null && result > 0 return result != null && result > 0
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.areCompatibleTypeParameterUpperBounds(
private fun areCompatibleTypeParameterUpperBounds(
expectTypeParameterSymbols: List<TypeParameterSymbolMarker>, expectTypeParameterSymbols: List<TypeParameterSymbolMarker>,
actualTypeParameterSymbols: List<TypeParameterSymbolMarker>, actualTypeParameterSymbols: List<TypeParameterSymbolMarker>,
substitutor: TypeSubstitutorMarker, substitutor: TypeSubstitutorMarker,
@@ -588,8 +556,7 @@ object AbstractExpectActualCompatibilityChecker {
return true return true
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getTypeParametersVarianceOrReifiedIncompatibility(
private fun getTypeParametersVarianceOrReifiedIncompatibility(
expectTypeParameterSymbols: List<TypeParameterSymbolMarker>, expectTypeParameterSymbols: List<TypeParameterSymbolMarker>,
actualTypeParameterSymbols: List<TypeParameterSymbolMarker>, actualTypeParameterSymbols: List<TypeParameterSymbolMarker>,
): Incompatible.WeakIncompatible<*>? { ): Incompatible.WeakIncompatible<*>? {
@@ -609,8 +576,7 @@ object AbstractExpectActualCompatibilityChecker {
return null return null
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getFunctionsIncompatibility(
private fun getFunctionsIncompatibility(
expectFunction: CallableSymbolMarker, expectFunction: CallableSymbolMarker,
actualFunction: CallableSymbolMarker, actualFunction: CallableSymbolMarker,
): Incompatible.WeakIncompatible<*>? { ): Incompatible.WeakIncompatible<*>? {
@@ -629,8 +595,7 @@ object AbstractExpectActualCompatibilityChecker {
return null return null
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.getPropertiesIncompatibility(
private fun getPropertiesIncompatibility(
expected: PropertySymbolMarker, expected: PropertySymbolMarker,
actual: PropertySymbolMarker, actual: PropertySymbolMarker,
): Incompatible.WeakIncompatible<*>? { ): Incompatible.WeakIncompatible<*>? {
@@ -643,8 +608,7 @@ object AbstractExpectActualCompatibilityChecker {
} }
} }
context(ExpectActualMatchingContext<*>) private fun K1ExpectActualMatchingContext<*>.arePropertySettersWithCompatibleVisibilities(
private fun arePropertySettersWithCompatibleVisibilities(
expected: PropertySymbolMarker, expected: PropertySymbolMarker,
actual: PropertySymbolMarker, actual: PropertySymbolMarker,
): Boolean { ): Boolean {
@@ -655,9 +619,11 @@ object AbstractExpectActualCompatibilityChecker {
// ---------------------------------------- Utils ---------------------------------------- // ---------------------------------------- Utils ----------------------------------------
context(ExpectActualMatchingContext<*>) private fun List<ValueParameterSymbolMarker>.toTypeList(
private fun List<ValueParameterSymbolMarker>.toTypeList(substitutor: TypeSubstitutorMarker): List<KotlinTypeMarker> { substitutor: TypeSubstitutorMarker,
return this.map { substitutor.safeSubstitute(it.returnType) } context: K1ExpectActualMatchingContext<*>,
): List<KotlinTypeMarker> = with(context) {
return map { substitutor.safeSubstitute(it.returnType) }
} }
private inline fun <T, K> equalsBy(first: List<T>, second: List<T>, selector: (T) -> K): Boolean { private inline fun <T, K> equalsBy(first: List<T>, second: List<T>, selector: (T) -> K): Boolean {
@@ -671,9 +637,8 @@ object AbstractExpectActualCompatibilityChecker {
private inline fun <T, K> equalBy(first: T, second: T, selector: (T) -> K): Boolean = private inline fun <T, K> equalBy(first: T, second: T, selector: (T) -> K): Boolean =
selector(first) == selector(second) selector(first) == selector(second)
context(ExpectActualMatchingContext<*>) private fun DeclarationSymbolMarker.getName(context: K1ExpectActualMatchingContext<*>): Name = with(context) {
private val DeclarationSymbolMarker.name: Name when (this@getName) {
get() = when (this) {
is ConstructorSymbolMarker -> SpecialNames.INIT is ConstructorSymbolMarker -> SpecialNames.INIT
is ValueParameterSymbolMarker -> parameterName is ValueParameterSymbolMarker -> parameterName
is CallableSymbolMarker -> callableId.callableName is CallableSymbolMarker -> callableId.callableName
@@ -682,12 +647,13 @@ object AbstractExpectActualCompatibilityChecker {
is TypeParameterSymbolMarker -> parameterName is TypeParameterSymbolMarker -> parameterName
else -> error("Unsupported declaration: $this") else -> error("Unsupported declaration: $this")
} }
}
context(ExpectActualMatchingContext<*>) private fun RegularClassSymbolMarker.isCtorless(context: K1ExpectActualMatchingContext<*>): Boolean = with(context) {
private val RegularClassSymbolMarker.isCtorless: Boolean getMembersForExpectClass(SpecialNames.INIT).isEmpty()
get() = getMembersForExpectClass(SpecialNames.INIT).isEmpty() }
context(ExpectActualMatchingContext<*>) private fun RegularClassSymbolMarker.isFinal(context: K1ExpectActualMatchingContext<*>): Boolean = with(context) {
private val RegularClassSymbolMarker.isFinal: Boolean modality == Modality.FINAL
get() = modality == Modality.FINAL }
} }
@@ -3,17 +3,17 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.resolve.calls.mpp package org.jetbrains.kotlin.resolve.multiplatform
sealed class ExpectActualCollectionArgumentsCompatibilityCheckStrategy { sealed class K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy {
abstract fun <T> areCompatible( abstract fun <T> areCompatible(
expectArg: Collection<T>, expectArg: Collection<T>,
actualArg: Collection<T>, actualArg: Collection<T>,
elementsEqual: (T, T) -> Boolean, elementsEqual: (T, T) -> Boolean,
): Boolean ): Boolean
data object Default : ExpectActualCollectionArgumentsCompatibilityCheckStrategy() { data object Default : K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy() {
override fun <T> areCompatible( override fun <T> areCompatible(
expectArg: Collection<T>, expectArg: Collection<T>,
actualArg: Collection<T>, actualArg: Collection<T>,
@@ -23,7 +23,7 @@ sealed class ExpectActualCollectionArgumentsCompatibilityCheckStrategy {
} }
} }
internal data object ExpectIsSubsetOfActual : ExpectActualCollectionArgumentsCompatibilityCheckStrategy() { internal data object ExpectIsSubsetOfActual : K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy() {
override fun <T> areCompatible( override fun <T> areCompatible(
expectArg: Collection<T>, expectArg: Collection<T>,
actualArg: Collection<T>, actualArg: Collection<T>,
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.resolve.multiplatform
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
sealed class ExpectActualCompatibility<out D> { sealed class K1ExpectActualCompatibility<out D> {
// Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer // Note that the reason is used in the diagnostic output, see PlatformIncompatibilityDiagnosticRenderer
sealed class Incompatible<out D>(val reason: String?) : ExpectActualCompatibility<D>() { sealed class Incompatible<out D>(val reason: String?) : K1ExpectActualCompatibility<D>() {
sealed class WeakIncompatible<out D>(reason: String?) : Incompatible<D>(reason) sealed class WeakIncompatible<out D>(reason: String?) : Incompatible<D>(reason)
@@ -96,20 +96,20 @@ sealed class ExpectActualCompatibility<out D> {
) )
} }
object Compatible : ExpectActualCompatibility<Nothing>() object Compatible : K1ExpectActualCompatibility<Nothing>()
} }
val ExpectActualCompatibility<*>.isCompatibleOrWeaklyIncompatible: Boolean val K1ExpectActualCompatibility<*>.isCompatibleOrWeaklyIncompatible: Boolean
get() = this is ExpectActualCompatibility.Compatible get() = this is K1ExpectActualCompatibility.Compatible
|| this is ExpectActualCompatibility.Incompatible.WeakIncompatible || this is K1ExpectActualCompatibility.Incompatible.WeakIncompatible
val ExpectActualCompatibility<*>.compatible: Boolean val K1ExpectActualCompatibility<*>.compatible: Boolean
get() = this == ExpectActualCompatibility.Compatible get() = this == K1ExpectActualCompatibility.Compatible
@OptIn(ExperimentalContracts::class) @OptIn(ExperimentalContracts::class)
fun ExpectActualCompatibility<*>.isIncompatible(): Boolean { fun K1ExpectActualCompatibility<*>.isIncompatible(): Boolean {
contract { contract {
returns(true) implies (this@isIncompatible is ExpectActualCompatibility.Incompatible<*>) returns(true) implies (this@isIncompatible is K1ExpectActualCompatibility.Incompatible<*>)
} }
return !compatible return !compatible
} }
@@ -3,7 +3,7 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.resolve.calls.mpp package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
@@ -12,13 +12,12 @@ import org.jetbrains.kotlin.mpp.*
import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemContext import org.jetbrains.kotlin.types.model.TypeSystemContext
interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemContext { interface K1ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemContext {
val shouldCheckReturnTypesOfCallables: Boolean val shouldCheckReturnTypesOfCallables: Boolean
/* /*
@@ -170,7 +169,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
fun onMismatchedMembersFromClassScope( fun onMismatchedMembersFromClassScope(
expectSymbol: DeclarationSymbolMarker, expectSymbol: DeclarationSymbolMarker,
actualSymbolsByIncompatibility: Map<ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>, actualSymbolsByIncompatibility: Map<K1ExpectActualCompatibility.Incompatible<*>, List<DeclarationSymbolMarker>>,
containingExpectClassSymbol: RegularClassSymbolMarker?, containingExpectClassSymbol: RegularClassSymbolMarker?,
containingActualClassSymbol: RegularClassSymbolMarker?, containingActualClassSymbol: RegularClassSymbolMarker?,
) {} ) {}
@@ -180,7 +179,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
fun areAnnotationArgumentsEqual( fun areAnnotationArgumentsEqual(
expectAnnotation: AnnotationCallInfo, expectAnnotation: AnnotationCallInfo,
actualAnnotation: AnnotationCallInfo, actualAnnotation: AnnotationCallInfo,
collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, collectionArgumentsCompatibilityCheckStrategy: K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy,
): Boolean ): Boolean
val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean val DeclarationSymbolMarker.hasSourceAnnotationsErased: Boolean
@@ -213,7 +212,7 @@ interface ExpectActualMatchingContext<T : DeclarationSymbolMarker> : TypeSystemC
actualClass: RegularClassSymbolMarker, actualClass: RegularClassSymbolMarker,
actualMember: DeclarationSymbolMarker, actualMember: DeclarationSymbolMarker,
checkClassScopesCompatibility: Boolean, checkClassScopesCompatibility: Boolean,
): Map<out DeclarationSymbolMarker, ExpectActualCompatibility<*>> ): Map<out DeclarationSymbolMarker, K1ExpectActualCompatibility<*>>
fun DeclarationSymbolMarker.getSourceElement(): SourceElementMarker fun DeclarationSymbolMarker.getSourceElement(): SourceElementMarker
} }
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.resolve.multiplatform package org.jetbrains.kotlin.resolve.multiplatform
// This class will be later used by K2. That's why it's placed in compiler.common module // This class will be later used by K2. That's why it's placed in compiler.common module
data class ExpectActualMemberDiff<out M, out C>(val kind: Kind, val actualMember: M, val expectClass: C) { data class K1ExpectActualMemberDiff<out M, out C>(val kind: Kind, val actualMember: M, val expectClass: C) {
/** /**
* Diff kinds that are legal for fake-overrides in final `expect class`, but illegal for non-final `expect class` * Diff kinds that are legal for fake-overrides in final `expect class`, but illegal for non-final `expect class`
* *
@@ -52,36 +52,36 @@ data class ExpectActualMemberDiff<out M, out C>(val kind: Kind, val actualMember
} }
} }
fun ExpectActualCompatibility.Incompatible<*>.toMemberDiffKind(): ExpectActualMemberDiff.Kind? = when (this) { fun K1ExpectActualCompatibility.Incompatible<*>.toMemberDiffKind(): K1ExpectActualMemberDiff.Kind? = when (this) {
ExpectActualCompatibility.Incompatible.CallableKind -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.CallableKind -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ParameterCount -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.ParameterCount -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ParameterShape -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.ParameterShape -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ParameterTypes -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.ParameterTypes -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ReturnType -> ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride K1ExpectActualCompatibility.Incompatible.ReturnType -> K1ExpectActualMemberDiff.Kind.ReturnTypeChangedInOverride
ExpectActualCompatibility.Incompatible.FunctionTypeParameterCount -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.FunctionTypeParameterCount -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ClassTypeParameterCount -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.ClassTypeParameterCount -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.FunctionTypeParameterUpperBounds -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.FunctionTypeParameterUpperBounds -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.ClassTypeParameterUpperBounds -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.ClassTypeParameterUpperBounds -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.ActualFunctionWithDefaultParameters -> null // It's not possible to add default parameters in override K1ExpectActualCompatibility.Incompatible.ActualFunctionWithDefaultParameters -> null // It's not possible to add default parameters in override
ExpectActualCompatibility.Incompatible.ClassKind -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.ClassKind -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.ClassModifiers -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.ClassModifiers -> error("Not applicable because K1ExpectActualMemberDiff is about members")
is ExpectActualCompatibility.Incompatible.ClassScopes -> error("Not applicable because ExpectActualMemberDiff is about members") is K1ExpectActualCompatibility.Incompatible.ClassScopes -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.EnumEntries -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.EnumEntries -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.FunInterfaceModifier -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.FunInterfaceModifier -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent -> null // It's not possible to override with different function modifier (suspend) K1ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent -> null // It's not possible to override with different function modifier (suspend)
ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset -> null // It's not possible to override with different function modifier (infix, inline, operator) K1ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset -> null // It's not possible to override with different function modifier (infix, inline, operator)
ExpectActualCompatibility.Incompatible.Modality -> ExpectActualMemberDiff.Kind.ModalityChangedInOverride K1ExpectActualCompatibility.Incompatible.Modality -> K1ExpectActualMemberDiff.Kind.ModalityChangedInOverride
ExpectActualCompatibility.Incompatible.ParameterNames -> ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride K1ExpectActualCompatibility.Incompatible.ParameterNames -> K1ExpectActualMemberDiff.Kind.ParameterNameChangedInOverride
ExpectActualCompatibility.Incompatible.PropertyConstModifier -> null // const fun can't be overridden K1ExpectActualCompatibility.Incompatible.PropertyConstModifier -> null // const fun can't be overridden
ExpectActualCompatibility.Incompatible.PropertyKind -> ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride K1ExpectActualCompatibility.Incompatible.PropertyKind -> K1ExpectActualMemberDiff.Kind.PropertyKindChangedInOverride
ExpectActualCompatibility.Incompatible.PropertyLateinitModifier -> ExpectActualMemberDiff.Kind.LateinitChangedInOverride K1ExpectActualCompatibility.Incompatible.PropertyLateinitModifier -> K1ExpectActualMemberDiff.Kind.LateinitChangedInOverride
ExpectActualCompatibility.Incompatible.PropertySetterVisibility -> ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride K1ExpectActualCompatibility.Incompatible.PropertySetterVisibility -> K1ExpectActualMemberDiff.Kind.SetterVisibilityChangedInOverride
ExpectActualCompatibility.Incompatible.Supertypes -> error("Not applicable because ExpectActualMemberDiff is about members") K1ExpectActualCompatibility.Incompatible.Supertypes -> error("Not applicable because K1ExpectActualMemberDiff is about members")
ExpectActualCompatibility.Incompatible.TypeParameterNames -> ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride K1ExpectActualCompatibility.Incompatible.TypeParameterNames -> K1ExpectActualMemberDiff.Kind.TypeParameterNamesChangedInOverride
ExpectActualCompatibility.Incompatible.TypeParameterReified -> null // inline fun can't be overridden K1ExpectActualCompatibility.Incompatible.TypeParameterReified -> null // inline fun can't be overridden
ExpectActualCompatibility.Incompatible.TypeParameterVariance -> null // Members are not allowed to have variance K1ExpectActualCompatibility.Incompatible.TypeParameterVariance -> null // Members are not allowed to have variance
ExpectActualCompatibility.Incompatible.ValueParameterCrossinline -> null // inline fun can't be overridden K1ExpectActualCompatibility.Incompatible.ValueParameterCrossinline -> null // inline fun can't be overridden
ExpectActualCompatibility.Incompatible.ValueParameterNoinline -> null // inline fun can't be overridden K1ExpectActualCompatibility.Incompatible.ValueParameterNoinline -> null // inline fun can't be overridden
ExpectActualCompatibility.Incompatible.ValueParameterVararg -> ExpectActualMemberDiff.Kind.NonPrivateCallableAdded K1ExpectActualCompatibility.Incompatible.ValueParameterVararg -> K1ExpectActualMemberDiff.Kind.NonPrivateCallableAdded
ExpectActualCompatibility.Incompatible.Visibility -> ExpectActualMemberDiff.Kind.VisibilityChangedInOverride K1ExpectActualCompatibility.Incompatible.Visibility -> K1ExpectActualMemberDiff.Kind.VisibilityChangedInOverride
} }
@@ -6,14 +6,13 @@
package org.jetbrains.kotlin.resolve.multiplatform package org.jetbrains.kotlin.resolve.multiplatform
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.calls.mpp.ExpectActualCollectionArgumentsCompatibilityCheckStrategy
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue import org.jetbrains.kotlin.resolve.constants.KClassValue
internal fun ClassicExpectActualMatchingContext.areExpressionConstValuesEqual( internal fun ClassicExpectActualMatchingContext.areExpressionConstValuesEqual(
expectValue: Any?, expectValue: Any?,
actualValue: Any?, actualValue: Any?,
collectionArgumentsCompatibilityCheckStrategy: ExpectActualCollectionArgumentsCompatibilityCheckStrategy, collectionArgumentsCompatibilityCheckStrategy: K1ExpectActualCollectionArgumentsCompatibilityCheckStrategy,
): Boolean { ): Boolean {
return when { return when {
expectValue is AnnotationDescriptor && actualValue is AnnotationDescriptor -> { expectValue is AnnotationDescriptor && actualValue is AnnotationDescriptor -> {