[Commonizer] Better handling of ObjcMethod and related annotations
They are important for overridability rules, so can't be just ignored. Some arguments are still different on different platforms, so commonized version is a bit strange. But the only important part is selector, which should be same on all platforms. ^KT-57588
This commit is contained in:
committed by
Space Team
parent
ffed0ecf1f
commit
0a07f16896
+43
-8
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.commonizer.core
|
||||
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirAnnotation
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirClassType
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirConstantValue
|
||||
import org.jetbrains.kotlin.commonizer.cir.CirEntityId
|
||||
import org.jetbrains.kotlin.commonizer.utils.COMMONIZER_OBJC_INTEROP_CALLABLE_ANNOTATION_ID
|
||||
import org.jetbrains.kotlin.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID
|
||||
@@ -20,16 +21,50 @@ object AnnotationsCommonizer : AssociativeCommonizer<List<CirAnnotation>> {
|
||||
val firstAnnotations = first.associateBy { it.type.classifierId }
|
||||
val secondAnnotations = second.associateBy { it.type.classifierId }
|
||||
|
||||
return setOfNotNull(
|
||||
commonizedObjcCallableAnnotation(first, second),
|
||||
commonizedDeprecatedAnnotation(firstAnnotations, secondAnnotations)
|
||||
).plus(commonizedSimpleAnnotations(firstAnnotations, secondAnnotations)).toList()
|
||||
return buildList {
|
||||
addAll(commonizedObjcCallableAnnotation(first, second))
|
||||
commonizedDeprecatedAnnotation(firstAnnotations, secondAnnotations)?.let { add(it) }
|
||||
addAll(commonizedSimpleAnnotations(firstAnnotations, secondAnnotations))
|
||||
}.distinct()
|
||||
}
|
||||
|
||||
private fun commonizedObjcCallableAnnotation(first: List<CirAnnotation>, second: List<CirAnnotation>): CirAnnotation? {
|
||||
return if (first.any { it.type.classifierId.isObjCInteropCallableAnnotation } &&
|
||||
second.any { it.type.classifierId.isObjCInteropCallableAnnotation }
|
||||
) objCCallableAnnotation else null
|
||||
private fun commonizedObjcCallableAnnotation(firstAnnotations: List<CirAnnotation>, secondAnnotations: List<CirAnnotation>): List<CirAnnotation> {
|
||||
val firstObjCCallable = firstAnnotations.filter { it.type.classifierId.isObjCInteropCallableAnnotation }
|
||||
val secondObjCCallable = secondAnnotations.filter { it.type.classifierId.isObjCInteropCallableAnnotation }
|
||||
return buildList {
|
||||
if (firstObjCCallable.isNotEmpty() && secondObjCCallable.isNotEmpty()) {
|
||||
add(objCCallableAnnotation)
|
||||
firstObjCCallable.forEach { first ->
|
||||
secondObjCCallable.forEach loop@{ second ->
|
||||
if (first.type.classifierId == second.type.classifierId) {
|
||||
val annotation = CirAnnotation.createInterned(
|
||||
CirClassType.createInterned(
|
||||
classId = first.type.classifierId,
|
||||
outerType = null, arguments = emptyList(), isMarkedNullable = false
|
||||
),
|
||||
buildMap {
|
||||
for ((key, value) in first.constantValueArguments) {
|
||||
if (second.constantValueArguments[key] == value) {
|
||||
put(key, value)
|
||||
continue
|
||||
}
|
||||
when (key.name) {
|
||||
"selector", "initSelector" -> return@loop
|
||||
"encoding" -> put(key, CirConstantValue.StringValue(""))
|
||||
"designated" -> put(key, CirConstantValue.BooleanValue(false))
|
||||
"isStret" -> {}
|
||||
else -> error("No default is known for $key")
|
||||
}
|
||||
}
|
||||
},
|
||||
emptyMap()
|
||||
)
|
||||
add(annotation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun commonizedSimpleAnnotations(first: Annotations, second: Annotations): List<CirAnnotation> {
|
||||
|
||||
Vendored
+10
-9
@@ -87,39 +87,40 @@ expect fun functionMismatchedParameterNames30(arg0: Int, vararg variadicArgument
|
||||
expect fun functionMismatchedParameterNames31(i: Int, s: String)
|
||||
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn34:s:", "", false)
|
||||
expect fun functionMismatchedParameterNames34(i: Int, s: String)
|
||||
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn37:arg1:", "", false)
|
||||
expect fun functionMismatchedParameterNames37(arg0: Int, arg1: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn38:s:", "", false)
|
||||
expect fun functionMismatchedParameterNames38(i: Int, s: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn39:s:", "", false)
|
||||
expect fun functionMismatchedParameterNames39(i: Int, s: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn40:s:", "", false)
|
||||
expect fun functionMismatchedParameterNames40(i: Int, s: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn41:arg1:", "", false)
|
||||
expect fun functionMismatchedParameterNames41(arg0: Int, arg1: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn42:arg1:", "", false)
|
||||
expect fun functionMismatchedParameterNames42(arg0: Int, arg1: String)
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("fmpn43:arg1:", "", false)
|
||||
expect fun functionMismatchedParameterNames43(arg0: Int, arg1: String)
|
||||
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("ofpn:s", "", false)
|
||||
expect fun overloadedFunctionByParameterNames(i: Int, s: String)
|
||||
|
||||
@kotlin.commonizer.ObjCCallable
|
||||
@kotlin.commonizer.ObjCCallable @kotlinx.cinterop.ObjCMethod("ofpn:xs", "", false)
|
||||
expect fun overloadedFunctionByParameterNames(xi: Int, xs: String)
|
||||
|
||||
expect inline fun inlineFunction1(lazyMessage: () -> String)
|
||||
|
||||
+1
-2
@@ -3,5 +3,4 @@ package kotlinx.cinterop
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class ObjCMethod() // fake annotation class without properties
|
||||
|
||||
annotation class ObjCMethod(val selector: String, val encoding: String, val isStret: Boolean)
|
||||
|
||||
Vendored
+13
-13
@@ -42,61 +42,61 @@ fun functionMismatchedParameterNames30(arg0: Int, vararg variadicArguments: Int)
|
||||
|
||||
fun functionMismatchedParameterNames31(i: Int, s: String) {}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn32:s:", "", false)
|
||||
fun functionMismatchedParameterNames32(i: Int, s: String) {
|
||||
}
|
||||
|
||||
fun functionMismatchedParameterNames33(i: Int, s: String) {}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn34:s:", "", false)
|
||||
fun functionMismatchedParameterNames34(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn35:s:", "", false)
|
||||
fun functionMismatchedParameterNames35(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn36:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames36(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn37:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames37(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn38:s:", "", false)
|
||||
fun functionMismatchedParameterNames38(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn39:s:", "", false)
|
||||
fun functionMismatchedParameterNames39(i: Int, s: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn40:s:", "", false)
|
||||
fun functionMismatchedParameterNames40(i: Int, s: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn41:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames41(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn42:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames42(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn43:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames43(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("ofpn:s:", "", false)
|
||||
fun overloadedFunctionByParameterNames(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("ofpn:xs:", "", false)
|
||||
fun overloadedFunctionByParameterNames(xi: Int, xs: String) {
|
||||
}
|
||||
|
||||
|
||||
Vendored
+13
-13
@@ -43,59 +43,59 @@ fun functionMismatchedParameterNames30(arg0: Int, vararg variadicArguments: Int)
|
||||
fun functionMismatchedParameterNames31(i: Int, s: String) {}
|
||||
fun functionMismatchedParameterNames32(i: Int, s: String) {}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn33:s:", "", false)
|
||||
fun functionMismatchedParameterNames33(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn34:s:", "", false)
|
||||
fun functionMismatchedParameterNames34(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn35:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames35(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn36:s:", "", false)
|
||||
fun functionMismatchedParameterNames36(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn37:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames37(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn38:s:", "", false)
|
||||
fun functionMismatchedParameterNames38(i: Int, s: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn39:s:", "", false)
|
||||
fun functionMismatchedParameterNames39(i: Int, s: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn40:s:", "", false)
|
||||
fun functionMismatchedParameterNames40(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn41:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames41(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn42:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames42(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
// hasStableParameterNames=false
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("fmpn43:arg1:", "", false)
|
||||
fun functionMismatchedParameterNames43(arg0: Int, arg1: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("ofpn:s:", "", false)
|
||||
fun overloadedFunctionByParameterNames(i: Int, s: String) {
|
||||
}
|
||||
|
||||
@kotlinx.cinterop.ObjCMethod
|
||||
@kotlinx.cinterop.ObjCMethod("ofpn:xs:", "", false)
|
||||
fun overloadedFunctionByParameterNames(xi: Int, xs: String) {
|
||||
}
|
||||
|
||||
|
||||
+23
-14
@@ -21,23 +21,27 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
simpleSingleSourceTarget(
|
||||
"a", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCMethod(0)
|
||||
@ObjCMethod("x", "xab", false)
|
||||
fun x() {}
|
||||
@ObjCMethod("wrongSelector1", "", false)
|
||||
fun y() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
simpleSingleSourceTarget(
|
||||
"b", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCMethod(1)
|
||||
@ObjCMethod("x", "xab", false)
|
||||
fun x() {}
|
||||
@ObjCMethod("wrongSelector2", "", false)
|
||||
fun y() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
simpleSingleSourceTarget(
|
||||
"c", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCMethod(2)
|
||||
@ObjCMethod("x", "xc", true)
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -45,7 +49,7 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
simpleSingleSourceTarget(
|
||||
"d", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCMethod(2)
|
||||
@ObjCMethod("x", "xd")
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -54,15 +58,19 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
result.assertCommonized(
|
||||
"(a, b)", """
|
||||
import kotlin.commonizer.*
|
||||
@ObjCCallable
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCCallable @ObjCMethod("x", "xab", false)
|
||||
expect fun x()
|
||||
@ObjCCallable
|
||||
expect fun y()
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
result.assertCommonized(
|
||||
"(c, d)", """
|
||||
import kotlin.commonizer.*
|
||||
@ObjCCallable
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCCallable @ObjCMethod("x", "")
|
||||
expect fun x()
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -70,7 +78,8 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
result.assertCommonized(
|
||||
"(a, b, c, d)", """
|
||||
import kotlin.commonizer.*
|
||||
@ObjCCallable
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCCallable @ObjCMethod("x", "")
|
||||
expect fun x()
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -119,7 +128,7 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
simpleSingleSourceTarget(
|
||||
"a", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCMethod(0)
|
||||
@ObjCMethod("x", "xa")
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -127,7 +136,7 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
simpleSingleSourceTarget(
|
||||
"b", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCConstructor(1)
|
||||
@ObjCConstructor("x", false)
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -135,7 +144,7 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
simpleSingleSourceTarget(
|
||||
"c", """
|
||||
import kotlinx.cinterop.*
|
||||
@ObjCFactory(2)
|
||||
@ObjCFactory("x", "xa")
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -183,7 +192,7 @@ class HierarchicalCInteropCallableAnnotationCommonizationTest : AbstractInlineSo
|
||||
"a", """
|
||||
import kotlinx.cinterop.*
|
||||
|
||||
@ObjCMethod(0)
|
||||
@ObjCMethod("x", "xa")
|
||||
fun x() {}
|
||||
""".trimIndent()
|
||||
)
|
||||
@@ -231,9 +240,9 @@ private fun InlineSourceBuilder.ModuleBuilder.objCAnnotations() {
|
||||
source(
|
||||
"""
|
||||
package kotlinx.cinterop
|
||||
annotation class ObjCMethod(val x: Int)
|
||||
annotation class ObjCConstructor(val x: Int)
|
||||
annotation class ObjCFactory(val x: Int)
|
||||
public annotation class ObjCMethod(val selector: String, val encoding: String, val isStret: Boolean = false)
|
||||
public annotation class ObjCConstructor(val initSelector: String, val designated: Boolean)
|
||||
public annotation class ObjCFactory(val selector: String, val encoding: String, val isStret: Boolean = false)
|
||||
""".trimIndent(),
|
||||
"kotlinx.kt"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user