OverloadResolver: Respect objc method parameter names

^KT-57588 In Progress
diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt
index fa1f75b..d919aab 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt
+++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/OverloadResolver.kt
@@ -23,8 +23,10 @@
 import org.jetbrains.kotlin.diagnostics.reportOnDeclaration
 import org.jetbrains.kotlin.idea.MainFunctionDetector
 import org.jetbrains.kotlin.incremental.components.NoLookupLocation
+import org.jetbrains.kotlin.name.FqName
 import org.jetbrains.kotlin.name.FqNameUnsafe
 import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.resolve.calls.util.isLowPriorityFromStdlibJre7Or8
 import org.jetbrains.kotlin.resolve.descriptorUtil.platform
 
 import org.jetbrains.kotlin.resolve.scopes.MemberScope
@@ -35,7 +37,7 @@
     private val overloadFilter: OverloadFilter,
     private val overloadChecker: OverloadChecker,
     languageVersionSettings: LanguageVersionSettings,
-    mainFunctionDetectorFactory: MainFunctionDetector.Factory
+    mainFunctionDetectorFactory: MainFunctionDetector.Factory,
 ) {
 
     private val mainFunctionDetector = mainFunctionDetectorFactory.createMainFunctionDetector(trace, languageVersionSettings)
@@ -64,7 +66,8 @@
                 constructorsByOuterClass.putValues(containingDeclaration, klass.constructors)
             } else if (!(containingDeclaration is FunctionDescriptor ||
                         containingDeclaration is PropertyDescriptor ||
-                        containingDeclaration is PackageFragmentDescriptor)) {
+                        containingDeclaration is PackageFragmentDescriptor)
+            ) {
                 throw IllegalStateException("Illegal class container: " + containingDeclaration)
             }
         }
@@ -89,7 +92,7 @@
 
     private fun groupModulePackageMembersByFqName(
         c: BodiesResolveContext,
-        overloadFilter: OverloadFilter
+        overloadFilter: OverloadFilter,
     ): MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot> {
         val packageMembersByName = MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>()
 
@@ -126,7 +129,7 @@
         packageMembersByName: MultiMap<FqNameUnsafe, DeclarationDescriptorNonRoot>,
         interestingDescriptors: Collection<DeclarationDescriptor>,
         overloadFilter: OverloadFilter,
-        getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
+        getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>,
     ) {
         val observedFQNs = hashSetOf<FqNameUnsafe>()
         for (descriptor in interestingDescriptors) {
@@ -144,7 +147,7 @@
     private inline fun getModulePackageMembersWithSameName(
         descriptor: DeclarationDescriptor,
         overloadFilter: OverloadFilter,
-        getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>
+        getMembersByName: (MemberScope, Name) -> Collection<DeclarationDescriptorNonRoot>,
     ): Collection<DeclarationDescriptorNonRoot> {
         val containingPackage = descriptor.containingDeclaration
         if (containingPackage !is PackageFragmentDescriptor) {
@@ -169,7 +172,7 @@
 
     private fun checkOverloadsInClass(
         classDescriptor: ClassDescriptorWithResolutionScopes,
-        nestedClassConstructors: Collection<FunctionDescriptor>
+        nestedClassConstructors: Collection<FunctionDescriptor>,
     ) {
         val functionsByName = MultiMap.create<Name, CallableMemberDescriptor>()
 
@@ -254,6 +257,7 @@
                 if (isTopLevelMainInDifferentFiles(member1, member2)) continue
                 if (isDefinitionsForDifferentPlatforms(member1, member2)) continue
                 if (isExpectDeclarationAndDefinition(member1, member2) || isExpectDeclarationAndDefinition(member2, member1)) continue
+                if (isObjcOverrideWithDifferentParameterNames(member1, member2)) continue
 
                 if (!overloadChecker.isOverloadable(member1, member2)) {
                     redeclarations.add(member1)
@@ -295,17 +299,35 @@
                 member1.platform != member2.platform
     }
 
+    private fun isObjcOverrideWithDifferentParameterNames(member1: DeclarationDescriptor, member2: DeclarationDescriptor): Boolean {
+        if (member1 !is FunctionDescriptor) return false
+        if (member2 !is FunctionDescriptor) return false
+
+        if (member1.overriddenDescriptors.none { overridden -> overridden.isObjC() }) return false
+        if (member2.overriddenDescriptors.none { overridden -> overridden.isObjC() }) return false
+
+        return member1.valueParameters.map { it.name } != member2.valueParameters.map { it.name }
+    }
+
     private fun reportRedeclarations(redeclarations: Collection<DeclarationDescriptorNonRoot>) {
         if (redeclarations.isEmpty()) return
 
         for (memberDescriptor in redeclarations) {
             when (memberDescriptor) {
                 is PropertyDescriptor,
-                is ClassifierDescriptor ->
-                    reportOnDeclaration(trace, memberDescriptor) { Errors.REDECLARATION.on(it, redeclarations) }
+                is ClassifierDescriptor,
+                -> reportOnDeclaration(trace, memberDescriptor) { Errors.REDECLARATION.on(it, redeclarations) }
                 is FunctionDescriptor ->
                     reportOnDeclaration(trace, memberDescriptor) { Errors.CONFLICTING_OVERLOADS.on(it, redeclarations) }
             }
         }
     }
+
+    private companion object {
+        val OBJC_CALLABLE_ANNOTATION_NAME = FqName("kotlin.commonizer.ObjCCallable")
+        val OBJC_METHOD_ANNOTATION_NAME = FqName("kotlinx.cinterop.ObjCMethod")
+
+        fun FunctionDescriptor.isObjC() = annotations.hasAnnotation(OBJC_CALLABLE_ANNOTATION_NAME) ||
+                annotations.hasAnnotation(OBJC_METHOD_ANNOTATION_NAME)
+    }
 }