[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