[ObjCExport] Fix property setter
KT-64953: Required part for enum translation
This commit is contained in:
committed by
Space Team
parent
576851e514
commit
8f2fc3d1e2
+22
-15
@@ -1,25 +1,32 @@
|
||||
package org.jetbrains.kotlin.objcexport
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertyGetterSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportFunctionName
|
||||
|
||||
context(KtAnalysisSession, KtObjCExportSession)
|
||||
fun KtFunctionLikeSymbol.getObjCFunctionName(): ObjCExportFunctionName {
|
||||
val resolveObjCNameAnnotation = resolveObjCNameAnnotation()
|
||||
val resolvedObjCNameAnnotation = resolveObjCNameAnnotation()
|
||||
return ObjCExportFunctionName(
|
||||
swiftName = getSwiftName(resolvedObjCNameAnnotation),
|
||||
objCName = getObjCName(resolvedObjCNameAnnotation)
|
||||
)
|
||||
}
|
||||
|
||||
private fun KtFunctionLikeSymbol.getObjCName(resolvedNameAnnotation: KtResolvedObjCNameAnnotation?): String {
|
||||
return resolvedNameAnnotation?.objCName ?: translationName
|
||||
}
|
||||
|
||||
val name: String = when (this) {
|
||||
is KtFunctionSymbol -> this.name.asString()
|
||||
is KtConstructorSymbol -> "init"
|
||||
is KtPropertyGetterSymbol -> "get" //TODO: implement properly getter since it doesn't have [name]
|
||||
else -> "Undefined name for $this type"
|
||||
}
|
||||
private fun KtFunctionLikeSymbol.getSwiftName(resolvedNameAnnotation: KtResolvedObjCNameAnnotation?): String {
|
||||
return resolvedNameAnnotation?.swiftName ?: translationName
|
||||
}
|
||||
|
||||
return ObjCExportFunctionName(
|
||||
resolveObjCNameAnnotation?.swiftName ?: name, resolveObjCNameAnnotation?.objCName ?: name
|
||||
)
|
||||
}
|
||||
private val KtFunctionLikeSymbol.translationName: String
|
||||
get() = when (this) {
|
||||
is KtFunctionSymbol -> name.asString()
|
||||
is KtConstructorSymbol -> "init"
|
||||
is KtPropertyGetterSymbol -> ""
|
||||
is KtAnonymousFunctionSymbol -> ""
|
||||
is KtPropertySetterSymbol -> ""
|
||||
is KtSamConstructorSymbol -> ""
|
||||
}
|
||||
|
||||
+1
-1
@@ -14,5 +14,5 @@ internal fun KtType.translateToObjCFunctionType(typeBridge: BlockPointerBridge):
|
||||
parameterTypes = listOfNotNull(this.receiverType).plus(this.parameterTypes).map { parameterType ->
|
||||
parameterType.translateToObjCReferenceType()
|
||||
}
|
||||
)
|
||||
).withNullabilityOf(this)
|
||||
}
|
||||
|
||||
+11
-37
@@ -185,7 +185,7 @@ private fun <T : Any> getPredefined(method: KtFunctionLikeSymbol, predefinedForA
|
||||
context(KtAnalysisSession, KtObjCExportSession)
|
||||
fun KtFunctionLikeSymbol.getSelector(methodBridge: MethodBridge): String {
|
||||
|
||||
getPredefined(this, Predefined.anyMethodSelectors)?.let { return it }
|
||||
getPredefined(this, anyMethodSelectors)?.let { return it }
|
||||
|
||||
val parameters = methodBridge.valueParametersAssociated(this)
|
||||
|
||||
@@ -231,56 +231,28 @@ fun KtFunctionLikeSymbol.getSelector(methodBridge: MethodBridge): String {
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl.getMangledName]
|
||||
*/
|
||||
context(KtAnalysisSession, KtObjCExportSession)
|
||||
private fun KtFunctionLikeSymbol.getMangledName(forSwift: Boolean): String {
|
||||
|
||||
if (this.isConstructor) {
|
||||
return if (isArrayConstructor && !forSwift) "array" else "init"
|
||||
return if (this.isConstructor) {
|
||||
if (isArrayConstructor && !forSwift) "array" else "init"
|
||||
} else {
|
||||
getObjCFunctionName().name(forSwift).handleSpecialNames("do")
|
||||
}
|
||||
|
||||
val candidate = when (this) {
|
||||
is KtPropertyGetterSymbol -> {
|
||||
this.getObjCFunctionName().name(forSwift)
|
||||
}
|
||||
is KtPropertySetterSymbol -> {
|
||||
this.getObjCFunctionName().name(forSwift)
|
||||
//TODO: find replacement for [this.correspondingProperty]
|
||||
// "set${
|
||||
// this.correspondingProperty.getObjCName().asString(forSwift).replaceFirstChar(kotlin.Char::uppercaseChar)
|
||||
// }".toIdentifier()
|
||||
}
|
||||
else -> {
|
||||
this.getObjCFunctionName().name(forSwift)
|
||||
}
|
||||
}
|
||||
return candidate.mangleIfSpecialFamily("do")
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl.mangleIfSpecialFamily]
|
||||
*/
|
||||
private fun String.mangleIfSpecialFamily(prefix: String): String {
|
||||
private fun String.handleSpecialNames(prefix: String): String {
|
||||
val trimmed = this.dropWhile { it == '_' }
|
||||
for (family in listOf("alloc", "copy", "mutableCopy", "new", "init")) {
|
||||
if (trimmed.startsWithWords(family)) {
|
||||
// Then method can be detected as having special family by Objective-C compiler.
|
||||
// mangle the name:
|
||||
return prefix + this.replaceFirstChar(Char::uppercaseChar)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle clashes with NSObject methods etc.
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportNamerImpl.startsWithWords]
|
||||
*/
|
||||
private fun String.startsWithWords(words: String) = this.startsWith(words) &&
|
||||
(this.length == words.length || !this[words.length].isLowerCase())
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.backend.konan.objcexport.MethodBrideExtensionsKt.valueParametersAssociated]
|
||||
*/
|
||||
@@ -302,6 +274,8 @@ fun MethodBridge.valueParametersAssociated(
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.startsWithWords(words: String) = this.startsWith(words) &&
|
||||
(this.length == words.length || !this[words.length].isLowerCase())
|
||||
|
||||
/**
|
||||
* [org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportTranslatorImpl.mapReturnType]
|
||||
|
||||
+4
-3
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCIdType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCProperty
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.swiftNameAttribute
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getPropertyMethodBridge
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.isVisibleInObjC
|
||||
@@ -48,7 +47,9 @@ fun KtPropertySymbol.buildProperty(): ObjCProperty {
|
||||
setterName = null
|
||||
}
|
||||
|
||||
val getterName = null //TODO: Fix and use getter.getSelector(), it should return name when it's available
|
||||
|
||||
val getterSelector = getter?.getSelector(bridge)
|
||||
val getterName: String? = if (getterSelector != name && getterSelector?.isNotBlank() == true) getterSelector else null
|
||||
|
||||
val declarationAttributes = mutableListOf(getSwiftPrivateAttribute() ?: swiftNameAttribute(propertyName.swiftName))
|
||||
|
||||
@@ -61,7 +62,7 @@ fun KtPropertySymbol.buildProperty(): ObjCProperty {
|
||||
origin = getObjCExportStubOrigin(),
|
||||
type = type ?: ObjCIdType, //[ObjCIdType] temp fix, should be translated properly, see KT-65709
|
||||
propertyAttributes = attributes,
|
||||
setterName = setterName,
|
||||
setterName = if (setterName.isNullOrBlank()) null else setterName,
|
||||
getterName = getterName,
|
||||
declarationAttributes = declarationAttributes
|
||||
)
|
||||
|
||||
-24
@@ -7,7 +7,6 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtNonErrorClassType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType
|
||||
@@ -161,29 +160,6 @@ internal fun KtType.translateTypeArgumentsToObjC(): List<ObjCNonNullReferenceTyp
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun ObjCNonNullReferenceType.withNullabilityOf(kotlinType: KtType): ObjCReferenceType {
|
||||
return if (kotlinType.isBinaryRepresentationNullable()) {
|
||||
ObjCNullableReferenceType(this)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtType.isBinaryRepresentationNullable(): Boolean {
|
||||
/* Convention to match K1 implementation */
|
||||
if (this is KtErrorType) return false
|
||||
|
||||
if (fullyExpandedType.canBeNull) return true
|
||||
|
||||
getInlineTargetTypeOrNull()?.let { inlineTargetType ->
|
||||
if (inlineTargetType.canBeNull) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Types to be "hidden" during mapping, i.e., represented as `id`.
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package org.jetbrains.kotlin.objcexport
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtErrorType
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCNonNullReferenceType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCNullableReferenceType
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCReferenceType
|
||||
import org.jetbrains.kotlin.objcexport.analysisApiUtils.getInlineTargetTypeOrNull
|
||||
|
||||
/**
|
||||
* [ObjCNonNullReferenceType] must be converted into [ObjCNullableReferenceType] if type is nullable
|
||||
* So types could be marked with "_Nullable" in Objective-C
|
||||
*/
|
||||
context(KtAnalysisSession)
|
||||
internal fun ObjCNonNullReferenceType.withNullabilityOf(kotlinType: KtType): ObjCReferenceType {
|
||||
return if (kotlinType.isBinaryRepresentationNullable()) {
|
||||
ObjCNullableReferenceType(this)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
internal fun KtType.isBinaryRepresentationNullable(): Boolean {
|
||||
/* Convention to match K1 implementation */
|
||||
if (this is KtErrorType) return false
|
||||
|
||||
if (fullyExpandedType.canBeNull) return true
|
||||
|
||||
getInlineTargetTypeOrNull()?.let { inlineTargetType ->
|
||||
if (inlineTargetType.canBeNull) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user