Deprecate Obj-C 'alloc' and 'allocWithZone:' methods in Kotlin

Using these methods in Kotlin is usually a mistake.
This commit is contained in:
Svyatoslav Scherbina
2021-06-28 17:40:12 +03:00
committed by Space
parent e5aa7e1625
commit 2865d8bd45
2 changed files with 24 additions and 0 deletions
@@ -148,7 +148,22 @@ private class ObjCMethodStubBuilder(
fun isDefaultConstructor(): Boolean =
method.isInit && method.parameters.isEmpty()
private fun deprecateObjCAlloc() {
// Motivation: 'alloc' and 'allocWithZone:' Obj-C methods were never intended to be directly accessible
// in Kotlin.
// Using these methods in Kotlin is error-prone: init methods are not accessible,
// so a call to alloc method is likely not followed by a call to an init method,
// which is usually a mistake.
// Swift also doesn't allow calling Obj-C alloc methods.
// Removing them gracefully, via the deprecation cycle:
if (method.isAlloc()) {
annotations += AnnotationStub.Deprecated.deprecatedObjCAlloc
}
}
override fun build(): List<FunctionalStub> {
deprecateObjCAlloc()
val replacement = if (method.isInit) {
val parameters = method.getKotlinParameters(context, forConstructorOrFactory = true)
when (container) {
@@ -243,6 +258,9 @@ private fun deprecatedInit(className: String, initParameterNames: List<String>,
return AnnotationStub.Deprecated("Use $replacementKind instead", replaceWith, DeprecationLevel.ERROR)
}
private fun ObjCMethod.isAlloc(): Boolean =
this.isClass && (this.selector == "alloc" || this.selector == "allocWithZone:")
internal val ObjCMethod.kotlinName: String
get() {
val candidate = selector.split(":").first()
@@ -238,6 +238,12 @@ sealed class AnnotationStub(val classifier: Classifier) {
"",
DeprecationLevel.WARNING
)
val deprecatedObjCAlloc = Deprecated(
"Use constructor or factory method instead",
"",
DeprecationLevel.WARNING
)
}
}