[ObjCExport] Drop property and method names values limits Fix ^KT-77434 (cherry picked from commit fe540eadd92a9759416006c1ff6611cf4d0c5a3d)
diff --git a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/mangling/parseSwiftNameAttribute.kt b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/mangling/parseSwiftNameAttribute.kt index 0795f71..08960ff 100644 --- a/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/mangling/parseSwiftNameAttribute.kt +++ b/native/objcexport-header-generator/impl/analysis-api/src/org/jetbrains/kotlin/objcexport/mangling/parseSwiftNameAttribute.kt
@@ -1,26 +1,33 @@ package org.jetbrains.kotlin.objcexport.mangling + private val swiftNameRegex = """^swift_name\("([^"]+)"\)$""".toRegex() -private val methodNameAndParametersRegex = """^([a-zA-Z0-9]+)\((.*)\)$""".toRegex() -private val parametersRegex = Regex("[a-zA-Z0-9_]+:") internal fun parseSwiftPropertyNameAttribute(attribute: String): ObjCMemberDetails { - val swiftNameMatch = swiftNameRegex.find(attribute) - if (swiftNameMatch != null) { - val propertyName = swiftNameMatch.groupValues[1] - return ObjCMemberDetails(propertyName, emptyList()) - } else error("Invalid swift_name property attribute: $attribute") + val swiftNameMatch = swiftNameRegex.find(attribute) + if (swiftNameMatch != null) { + val propertyName = swiftNameMatch.groupValues[1] + return ObjCMemberDetails(propertyName, emptyList()) + } else error("Invalid swift_name property attribute: $attribute") } -internal fun parseSwiftMethodNameAttribute(attribute: String, isConstructor: Boolean = false): ObjCMemberDetails { +internal fun parseSwiftMethodNameAttribute( + attribute: String, + isConstructor: Boolean = false +): ObjCMemberDetails { val swiftNameMatch = swiftNameRegex.find(attribute) if (swiftNameMatch != null) { val swiftName = swiftNameMatch.groupValues[1] - val methodAndParametersMatch = methodNameAndParametersRegex.find(swiftName) - if (methodAndParametersMatch != null) { - val methodName = methodAndParametersMatch.groupValues[1] - val parameters = methodAndParametersMatch.groupValues[2] - return ObjCMemberDetails(methodName, splitParameters(parameters), isConstructor) + + val methodName = swiftName.extractMethodName() + val parameterNames = parseSwiftNameParameters(swiftName) + + if (!methodName.isNullOrEmpty()) { + return ObjCMemberDetails( + name = methodName, + parameters = parameterNames, + isConstructor = isConstructor + ) } else error("Invalid name and parameters of swift_name attribute: $attribute") } else error("Invalid swift_name method attribute: $attribute") } @@ -29,11 +36,33 @@ val name: String, val parameters: List<String>, val isConstructor: Boolean = false, - val postfix: String = "", + val postfix: String = "" ) -private fun splitParameters(parameters: String): List<String> { - return parametersRegex.findAll(parameters) - .map { it.value } - .toList() +/** + * foo(a:b:) -> [a:, b:] + */ +internal fun parseSwiftNameParameters(swiftNameValue: String): List<String> { + val functionPattern = Regex("""\w+\((.*?)\)""") + val match = functionPattern.matchEntire(swiftNameValue.trim()) + + return when { + match != null -> { + val params = match.groupValues[1] + if (params.isBlank()) emptyList() + else { + params.split(':') + .filter { it.isNotEmpty() } + .map { param -> "$param:" } + } + } + else -> emptyList() + } +} + +/** + * `foo(bar) -> foo + */ +internal fun String?.extractMethodName(): String? { + return this?.substringBefore('(') } \ No newline at end of file
diff --git a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/mangling/ParseSwiftNameAttributeTest.kt b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/mangling/ParseSwiftNameAttributeTest.kt index 80c1ae2..fc9e725 100644 --- a/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/mangling/ParseSwiftNameAttributeTest.kt +++ b/native/objcexport-header-generator/impl/analysis-api/test/org/jetbrains/kotlin/objcexport/tests/mangling/ParseSwiftNameAttributeTest.kt
@@ -1,9 +1,6 @@ package org.jetbrains.kotlin.objcexport.tests.mangling -import org.jetbrains.kotlin.objcexport.mangling.ObjCMemberDetails -import org.jetbrains.kotlin.objcexport.mangling.buildMangledSelectors -import org.jetbrains.kotlin.objcexport.mangling.mangleAttribute -import org.jetbrains.kotlin.objcexport.mangling.parseSwiftMethodNameAttribute +import org.jetbrains.kotlin.objcexport.mangling.* import org.junit.jupiter.api.Test import kotlin.test.assertEquals import kotlin.test.assertFails @@ -118,4 +115,40 @@ ).mangleAttribute() ) } + + @Test + fun `test - method name with mangling prefix`() { + + assertEquals( + ObjCMemberDetails("_pack", emptyList()), + parseSwiftMethodNameAttribute("swift_name(\"_pack()\")") + ) + + assertEquals( + ObjCMemberDetails("_foo", listOf("bar:")), + parseSwiftMethodNameAttribute("swift_name(\"_foo(bar)\")") + ) + } + + @Test + fun `test - dropping parameters with brackets`() { + assertEquals("foo", "foo()".extractMethodName()) + assertEquals("foo", "foo(a:)".extractMethodName()) + assertEquals("foo", "foo(a:b:)".extractMethodName()) + } + + @Test + fun `test - swift name parameters parsing`() { + assertEquals(emptyList(), parseSwiftNameParameters("foo()")) + assertEquals(listOf("a:"), parseSwiftNameParameters("foo(a:)")) + assertEquals(listOf("a:", "b:"), parseSwiftNameParameters("foo(a:b:)")) + } + + @Test + fun `test - invalid swift_name method format`() { + assertEquals(emptyList(), parseSwiftNameParameters("foo")) + assertEquals(emptyList(), parseSwiftNameParameters("")) + assertEquals(emptyList(), parseSwiftNameParameters("foo(")) + assertEquals(emptyList(), parseSwiftNameParameters("foo)")) + } } \ No newline at end of file