[K/N] De-duplicate code for mangling objc interop function names
Extract the duplicated functionality to the `ObjCFunctionNameMangleComputer` class.
This commit is contained in:
committed by
teamcity
parent
0fd4f10f6c
commit
e3b5dc509c
@@ -9,6 +9,7 @@ dependencies {
|
|||||||
implementation(project(":compiler:fir:resolve"))
|
implementation(project(":compiler:fir:resolve"))
|
||||||
implementation(project(":compiler:fir:fir2ir"))
|
implementation(project(":compiler:fir:fir2ir"))
|
||||||
implementation(project(":compiler:ir.serialization.common"))
|
implementation(project(":compiler:ir.serialization.common"))
|
||||||
|
implementation(project(":compiler:ir.serialization.native"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+36
-63
@@ -6,14 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.fir.backend.native
|
package org.jetbrains.kotlin.fir.backend.native
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.*
|
import org.jetbrains.kotlin.backend.common.serialization.mangle.*
|
||||||
|
import org.jetbrains.kotlin.backend.konan.serialization.ANNOTATIONS_TO_TREAT_AS_EXPORTED
|
||||||
|
import org.jetbrains.kotlin.backend.konan.serialization.ObjCFunctionNameMangleComputer
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.backend.FirMangler
|
|
||||||
import org.jetbrains.kotlin.fir.backend.FirExportCheckerVisitor
|
import org.jetbrains.kotlin.fir.backend.FirExportCheckerVisitor
|
||||||
import org.jetbrains.kotlin.fir.backend.FirMangleComputer
|
import org.jetbrains.kotlin.fir.backend.FirMangleComputer
|
||||||
|
import org.jetbrains.kotlin.fir.backend.FirMangler
|
||||||
import org.jetbrains.kotlin.fir.backend.native.interop.*
|
import org.jetbrains.kotlin.fir.backend.native.interop.*
|
||||||
import org.jetbrains.kotlin.fir.backend.native.interop.hasObjCFactoryAnnotation
|
|
||||||
import org.jetbrains.kotlin.fir.backend.native.interop.hasObjCMethodAnnotation
|
|
||||||
import org.jetbrains.kotlin.fir.backend.native.interop.isObjCClassMethod
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
import org.jetbrains.kotlin.fir.isSubstitutionOrIntersectionOverride
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
@@ -21,7 +20,8 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
import org.jetbrains.kotlin.fir.types.coneType
|
||||||
import org.jetbrains.kotlin.fir.types.toSymbol
|
import org.jetbrains.kotlin.fir.types.toSymbol
|
||||||
import org.jetbrains.kotlin.name.NativeRuntimeNames
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.native.interop.ObjCMethodInfo
|
||||||
|
|
||||||
class FirNativeKotlinMangler : FirMangler() {
|
class FirNativeKotlinMangler : FirMangler() {
|
||||||
override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): KotlinMangleComputer<FirDeclaration> {
|
override fun getMangleComputer(mode: MangleMode, compatibleMode: Boolean): KotlinMangleComputer<FirDeclaration> {
|
||||||
@@ -41,31 +41,37 @@ class FirNativeExportCheckerVisitor : FirExportCheckerVisitor() {
|
|||||||
override fun FirDeclaration.isPlatformSpecificExported(): Boolean {
|
override fun FirDeclaration.isPlatformSpecificExported(): Boolean {
|
||||||
if (this is FirCallableDeclaration && isSubstitutionOrIntersectionOverride)
|
if (this is FirCallableDeclaration && isSubstitutionOrIntersectionOverride)
|
||||||
return false
|
return false
|
||||||
|
return ANNOTATIONS_TO_TREAT_AS_EXPORTED.any { hasAnnotation(it, moduleData.session) }
|
||||||
if (annotations.hasAnnotation(NativeRuntimeNames.Annotations.symbolNameClassId, moduleData.session)) {
|
|
||||||
// Treat any `@SymbolName` declaration as exported.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotations.hasAnnotation(NativeRuntimeNames.Annotations.gcUnsafeCallClassId, moduleData.session)) {
|
|
||||||
// Treat any `@GCUnsafeCall` declaration as exported.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotations.hasAnnotation(NativeRuntimeNames.Annotations.exportForCppRuntimeClassId, moduleData.session)) {
|
|
||||||
// Treat any `@ExportForCppRuntime` declaration as exported.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotations.hasAnnotation(NativeRuntimeNames.Annotations.cNameClassId, moduleData.session)) {
|
|
||||||
// Treat `@CName` declaration as exported.
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (annotations.hasAnnotation(NativeRuntimeNames.Annotations.exportForCompilerClassId, moduleData.session)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FirObjCFunctionNameMangleComputer(
|
||||||
|
private val function: FirFunction
|
||||||
|
) : ObjCFunctionNameMangleComputer<FirValueParameter>() {
|
||||||
|
|
||||||
|
private val session = function.moduleData.session
|
||||||
|
|
||||||
|
override fun getObjCMethodInfo(): ObjCMethodInfo? {
|
||||||
|
val scopeSession = ScopeSession()
|
||||||
|
return function.getInitMethodIfObjCConstructor(session, scopeSession)
|
||||||
|
?.getObjCMethodInfoFromOverriddenFunctions(session, scopeSession)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExtensionReceiverClassName(): Name? = function.receiverParameter?.getTypeName(session)?.let(Name::identifier)
|
||||||
|
|
||||||
|
override fun isObjCConstructor(): Boolean = function is FirConstructor && function.isObjCConstructor(session)
|
||||||
|
|
||||||
|
override fun isPropertyAccessor(): Boolean = function is FirPropertyAccessor
|
||||||
|
|
||||||
|
override fun hasObjCMethodAnnotation(): Boolean = function.hasObjCMethodAnnotation(session)
|
||||||
|
|
||||||
|
override fun hasObjCFactoryAnnotation(): Boolean = function.hasObjCFactoryAnnotation(session)
|
||||||
|
|
||||||
|
override fun isObjCClassMethod(): Boolean = function.isObjCClassMethod(session)
|
||||||
|
|
||||||
|
override fun getValueParameterName(valueParameter: FirValueParameter): Name = valueParameter.name
|
||||||
|
}
|
||||||
|
|
||||||
class FirNativeKotlinMangleComputer(
|
class FirNativeKotlinMangleComputer(
|
||||||
builder: StringBuilder,
|
builder: StringBuilder,
|
||||||
mode: MangleMode,
|
mode: MangleMode,
|
||||||
@@ -73,42 +79,9 @@ class FirNativeKotlinMangleComputer(
|
|||||||
override fun copy(newMode: MangleMode): FirNativeKotlinMangleComputer =
|
override fun copy(newMode: MangleMode): FirNativeKotlinMangleComputer =
|
||||||
FirNativeKotlinMangleComputer(builder, newMode)
|
FirNativeKotlinMangleComputer(builder, newMode)
|
||||||
|
|
||||||
/**
|
override fun makePlatformSpecificFunctionNameMangleComputer(
|
||||||
* mimics FunctionDescriptor.platformSpecificFunctionName()
|
function: FirFunction
|
||||||
*/
|
): PlatformSpecificFunctionNameMangleComputer<FirValueParameter> = FirObjCFunctionNameMangleComputer(function)
|
||||||
override fun FirFunction.platformSpecificFunctionName(): String? {
|
|
||||||
val session = moduleData.session
|
|
||||||
val scopeSession = ScopeSession()
|
|
||||||
getInitMethodIfObjCConstructor(session, scopeSession)
|
|
||||||
?.getObjCMethodInfoFromOverriddenFunctions(session, scopeSession)
|
|
||||||
?.let {
|
|
||||||
return buildString {
|
|
||||||
receiverParameter?.let {
|
|
||||||
append(it.getTypeName(session))
|
|
||||||
append(MangleConstant.FQN_SEPARATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
append(MangleConstant.OBJC_MARK)
|
|
||||||
append(it.selector)
|
|
||||||
if ((this@platformSpecificFunctionName is FirConstructor) && isObjCConstructor(session)) {
|
|
||||||
append(MangleConstant.OBJC_CONSTRUCTOR_MARK)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this@platformSpecificFunctionName is FirPropertyAccessor) {
|
|
||||||
append(MangleConstant.OBJC_PROPERTY_ACCESSOR_MARK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun FirFunction.specialValueParamPrefix(param: FirValueParameter): String {
|
|
||||||
val session = moduleData.session
|
|
||||||
return if (this.hasObjCMethodAnnotation(session) || this.hasObjCFactoryAnnotation(session) || this.isObjCClassMethod(session))
|
|
||||||
"${param.name}:"
|
|
||||||
else
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirReceiverParameter.getTypeName(session: FirSession): String {
|
private fun FirReceiverParameter.getTypeName(session: FirSession): String {
|
||||||
|
|||||||
+8
-5
@@ -42,12 +42,12 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
|
|||||||
|
|
||||||
protected val typeParameterContainers = ArrayList<TypeParameterContainer>(4)
|
protected val typeParameterContainers = ArrayList<TypeParameterContainer>(4)
|
||||||
|
|
||||||
protected open fun FunctionDeclaration.platformSpecificFunctionName(): String? = null
|
protected open fun makePlatformSpecificFunctionNameMangleComputer(
|
||||||
|
function: FunctionDeclaration
|
||||||
|
): PlatformSpecificFunctionNameMangleComputer<ValueParameter> = PlatformSpecificFunctionNameMangleComputer.Default
|
||||||
|
|
||||||
protected open fun FunctionDeclaration.platformSpecificSuffix(): String? = null
|
protected open fun FunctionDeclaration.platformSpecificSuffix(): String? = null
|
||||||
|
|
||||||
protected open fun FunctionDeclaration.specialValueParamPrefix(param: ValueParameter): String = ""
|
|
||||||
|
|
||||||
protected open fun addReturnType(): Boolean = false
|
protected open fun addReturnType(): Boolean = false
|
||||||
|
|
||||||
protected open fun addReturnTypeSpecialCase(function: FunctionDeclaration): Boolean = false
|
protected open fun addReturnTypeSpecialCase(function: FunctionDeclaration): Boolean = false
|
||||||
@@ -145,7 +145,7 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
|
|||||||
|
|
||||||
builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX)
|
builder.appendName(MangleConstant.FUNCTION_NAME_PREFIX)
|
||||||
|
|
||||||
platformSpecificFunctionName()?.let {
|
makePlatformSpecificFunctionNameMangleComputer(this).computePlatformSpecificFunctionName()?.let {
|
||||||
builder.append(it)
|
builder.append(it)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -180,7 +180,10 @@ abstract class BaseKotlinMangleComputer<Declaration, Type, TypeParameter, ValueP
|
|||||||
}
|
}
|
||||||
|
|
||||||
getValueParameters(this).collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
getValueParameters(this).collectForMangler(builder, MangleConstant.VALUE_PARAMETERS) {
|
||||||
appendSignature(specialValueParamPrefix(it))
|
appendSignature(
|
||||||
|
makePlatformSpecificFunctionNameMangleComputer(this@mangleSignature)
|
||||||
|
.computePlatformSpecificValueParameterPrefix(it)
|
||||||
|
)
|
||||||
mangleValueParameter(this, it, session)
|
mangleValueParameter(this, it, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.common.serialization.mangle
|
||||||
|
|
||||||
|
interface PlatformSpecificFunctionNameMangleComputer<in ValueParameter : Any> {
|
||||||
|
|
||||||
|
fun computePlatformSpecificFunctionName(): String?
|
||||||
|
|
||||||
|
fun computePlatformSpecificValueParameterPrefix(valueParameter: ValueParameter): String
|
||||||
|
|
||||||
|
object Default : PlatformSpecificFunctionNameMangleComputer<Any> {
|
||||||
|
|
||||||
|
override fun computePlatformSpecificFunctionName(): String? = null
|
||||||
|
|
||||||
|
override fun computePlatformSpecificValueParameterPrefix(valueParameter: Any): String = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
-65
@@ -17,13 +17,11 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.ir.IrMangleCompu
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.objcinterop.*
|
|
||||||
import org.jetbrains.kotlin.ir.types.getClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
import org.jetbrains.kotlin.name.NativeRuntimeNames
|
import org.jetbrains.kotlin.name.NativeRuntimeNames
|
||||||
import org.jetbrains.kotlin.name.NativeStandardInteropNames
|
import org.jetbrains.kotlin.name.NativeStandardInteropNames
|
||||||
|
|
||||||
private val annotationsToTreatAsExported = listOf(
|
val ANNOTATIONS_TO_TREAT_AS_EXPORTED = listOf(
|
||||||
NativeRuntimeNames.Annotations.symbolNameClassId,
|
NativeRuntimeNames.Annotations.symbolNameClassId,
|
||||||
NativeRuntimeNames.Annotations.gcUnsafeCallClassId,
|
NativeRuntimeNames.Annotations.gcUnsafeCallClassId,
|
||||||
NativeRuntimeNames.Annotations.exportForCppRuntimeClassId,
|
NativeRuntimeNames.Annotations.exportForCppRuntimeClassId,
|
||||||
@@ -31,9 +29,6 @@ private val annotationsToTreatAsExported = listOf(
|
|||||||
NativeRuntimeNames.Annotations.exportForCompilerClassId,
|
NativeRuntimeNames.Annotations.exportForCompilerClassId,
|
||||||
)
|
)
|
||||||
|
|
||||||
private val IrConstructor.isObjCConstructor: Boolean
|
|
||||||
get() = hasAnnotation(NativeStandardInteropNames.objCConstructorClassId)
|
|
||||||
|
|
||||||
abstract class AbstractKonanIrMangler(
|
abstract class AbstractKonanIrMangler(
|
||||||
private val withReturnType: Boolean,
|
private val withReturnType: Boolean,
|
||||||
private val allowOutOfScopeTypeParameters: Boolean = false
|
private val allowOutOfScopeTypeParameters: Boolean = false
|
||||||
@@ -46,7 +41,7 @@ abstract class AbstractKonanIrMangler(
|
|||||||
override fun IrDeclaration.isPlatformSpecificExport(): Boolean {
|
override fun IrDeclaration.isPlatformSpecificExport(): Boolean {
|
||||||
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
if (this is IrSimpleFunction) if (isFakeOverride) return false
|
||||||
|
|
||||||
return annotationsToTreatAsExported.any(this::hasAnnotation)
|
return ANNOTATIONS_TO_TREAT_AS_EXPORTED.any(this::hasAnnotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class KonanIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) {
|
private inner class KonanIrExportChecker(compatibleMode: Boolean) : IrExportCheckerVisitor(compatibleMode) {
|
||||||
@@ -65,43 +60,13 @@ abstract class AbstractKonanIrMangler(
|
|||||||
|
|
||||||
override fun addReturnType(): Boolean = withReturnType
|
override fun addReturnType(): Boolean = withReturnType
|
||||||
|
|
||||||
override fun IrFunction.platformSpecificFunctionName(): String? {
|
override fun makePlatformSpecificFunctionNameMangleComputer(function: IrFunction) = IrObjCFunctionNameMangleComputer(function)
|
||||||
(if (this is IrConstructor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo()
|
|
||||||
?.let {
|
|
||||||
return buildString {
|
|
||||||
if (extensionReceiverParameter != null) {
|
|
||||||
append(extensionReceiverParameter!!.type.getClass()!!.name)
|
|
||||||
append(MangleConstant.FQN_SEPARATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
append(MangleConstant.OBJC_MARK)
|
|
||||||
append(it.selector)
|
|
||||||
if (this@platformSpecificFunctionName is IrConstructor && this@platformSpecificFunctionName.isObjCConstructor) {
|
|
||||||
append(MangleConstant.OBJC_CONSTRUCTOR_MARK)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((this@platformSpecificFunctionName as? IrSimpleFunction)?.correspondingPropertySymbol != null) {
|
|
||||||
append(MangleConstant.OBJC_PROPERTY_ACCESSOR_MARK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun IrFunction.platformSpecificFunctionMarks(): List<String> = when (origin) {
|
override fun IrFunction.platformSpecificFunctionMarks(): List<String> = when (origin) {
|
||||||
IrDeclarationOrigin.LOWERED_SUSPEND_FUNCTION -> listOfSuspendFunctionMark
|
IrDeclarationOrigin.LOWERED_SUSPEND_FUNCTION -> listOfSuspendFunctionMark
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun IrFunction.specialValueParamPrefix(param: IrValueParameter): String {
|
|
||||||
// TODO: there are clashes originating from ObjectiveC interop.
|
|
||||||
// kotlinx.cinterop.ObjCClassOf<T>.create(format: kotlin.String): T defined in platform.Foundation in file Foundation.kt
|
|
||||||
// and
|
|
||||||
// kotlinx.cinterop.ObjCClassOf<T>.create(string: kotlin.String): T defined in platform.Foundation in file Foundation.kt
|
|
||||||
|
|
||||||
return if (this.hasObjCMethodAnnotation || this.hasObjCFactoryAnnotation || this.isObjCClassMethod()) "${param.name}:" else ""
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val listOfSuspendFunctionMark = listOf(MangleConstant.SUSPEND_FUNCTION_MARK)
|
val listOfSuspendFunctionMark = listOf(MangleConstant.SUSPEND_FUNCTION_MARK)
|
||||||
}
|
}
|
||||||
@@ -124,7 +89,7 @@ abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl
|
|||||||
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false
|
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return annotationsToTreatAsExported.any { annotations.hasAnnotation(it.asSingleFqName()) }
|
return ANNOTATIONS_TO_TREAT_AS_EXPORTED.any { annotations.hasAnnotation(it.asSingleFqName()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -132,32 +97,8 @@ abstract class AbstractKonanDescriptorMangler : DescriptorBasedKotlinManglerImpl
|
|||||||
private class KonanDescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : DescriptorMangleComputer(builder, mode) {
|
private class KonanDescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : DescriptorMangleComputer(builder, mode) {
|
||||||
override fun copy(newMode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(builder, newMode)
|
override fun copy(newMode: MangleMode): DescriptorMangleComputer = KonanDescriptorMangleComputer(builder, newMode)
|
||||||
|
|
||||||
override fun FunctionDescriptor.platformSpecificFunctionName(): String? {
|
override fun makePlatformSpecificFunctionNameMangleComputer(function: FunctionDescriptor) =
|
||||||
(if (this is ConstructorDescriptor && this.isObjCConstructor) this.getObjCInitMethod() else this)?.getObjCMethodInfo()
|
DescriptorObjCFunctionNameMangleComputer(function)
|
||||||
?.let {
|
|
||||||
return buildString {
|
|
||||||
if (extensionReceiverParameter != null) {
|
|
||||||
append(extensionReceiverParameter!!.type.constructor.declarationDescriptor!!.name)
|
|
||||||
append(MangleConstant.FQN_SEPARATOR)
|
|
||||||
}
|
|
||||||
|
|
||||||
append(MangleConstant.OBJC_MARK)
|
|
||||||
append(it.selector)
|
|
||||||
if (this@platformSpecificFunctionName is ConstructorDescriptor && this@platformSpecificFunctionName.isObjCConstructor) {
|
|
||||||
append(MangleConstant.OBJC_CONSTRUCTOR_MARK)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this@platformSpecificFunctionName is PropertyAccessorDescriptor) {
|
|
||||||
append(MangleConstant.OBJC_PROPERTY_ACCESSOR_MARK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun FunctionDescriptor.specialValueParamPrefix(param: ValueParameterDescriptor): String {
|
|
||||||
return if (this.hasObjCMethodAnnotation || this.hasObjCFactoryAnnotation || this.isObjCClassMethod()) "${param.name}:" else ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.konan.serialization
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleConstant
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.mangle.PlatformSpecificFunctionNameMangleComputer
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
|
import org.jetbrains.kotlin.ir.objcinterop.*
|
||||||
|
import org.jetbrains.kotlin.ir.types.getClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.name.NativeStandardInteropNames
|
||||||
|
import org.jetbrains.kotlin.native.interop.ObjCMethodInfo
|
||||||
|
|
||||||
|
abstract class ObjCFunctionNameMangleComputer<ValueParameter : Any> : PlatformSpecificFunctionNameMangleComputer<ValueParameter> {
|
||||||
|
|
||||||
|
abstract fun getObjCMethodInfo(): ObjCMethodInfo?
|
||||||
|
|
||||||
|
abstract fun getExtensionReceiverClassName(): Name?
|
||||||
|
|
||||||
|
abstract fun isObjCConstructor(): Boolean
|
||||||
|
|
||||||
|
abstract fun isPropertyAccessor(): Boolean
|
||||||
|
|
||||||
|
abstract fun hasObjCMethodAnnotation(): Boolean
|
||||||
|
|
||||||
|
abstract fun hasObjCFactoryAnnotation(): Boolean
|
||||||
|
|
||||||
|
abstract fun isObjCClassMethod(): Boolean
|
||||||
|
|
||||||
|
abstract fun getValueParameterName(valueParameter: ValueParameter): Name
|
||||||
|
|
||||||
|
final override fun computePlatformSpecificFunctionName(): String? {
|
||||||
|
val objcMethodInfo = getObjCMethodInfo() ?: return null
|
||||||
|
return buildString {
|
||||||
|
getExtensionReceiverClassName()?.let {
|
||||||
|
append(it)
|
||||||
|
append(MangleConstant.FQN_SEPARATOR)
|
||||||
|
}
|
||||||
|
append(MangleConstant.OBJC_MARK)
|
||||||
|
append(objcMethodInfo.selector)
|
||||||
|
if (isObjCConstructor()) {
|
||||||
|
append(MangleConstant.OBJC_CONSTRUCTOR_MARK)
|
||||||
|
}
|
||||||
|
if (isPropertyAccessor()) {
|
||||||
|
append(MangleConstant.OBJC_PROPERTY_ACCESSOR_MARK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun computePlatformSpecificValueParameterPrefix(valueParameter: ValueParameter): String =
|
||||||
|
if (hasObjCMethodAnnotation() || hasObjCFactoryAnnotation() || isObjCClassMethod()) {
|
||||||
|
"${getValueParameterName(valueParameter)}:"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ObsoleteDescriptorBasedAPI
|
||||||
|
class DescriptorObjCFunctionNameMangleComputer(
|
||||||
|
private val function: FunctionDescriptor
|
||||||
|
) : ObjCFunctionNameMangleComputer<ValueParameterDescriptor>() {
|
||||||
|
|
||||||
|
override fun getObjCMethodInfo(): ObjCMethodInfo? =
|
||||||
|
(if (function is ConstructorDescriptor && function.isObjCConstructor) function.getObjCInitMethod() else function)
|
||||||
|
?.getObjCMethodInfo()
|
||||||
|
|
||||||
|
override fun getExtensionReceiverClassName(): Name? =
|
||||||
|
function.extensionReceiverParameter?.run { type.constructor.declarationDescriptor!!.name }
|
||||||
|
|
||||||
|
override fun isObjCConstructor(): Boolean =
|
||||||
|
function is ConstructorDescriptor && function.isObjCConstructor
|
||||||
|
|
||||||
|
override fun isPropertyAccessor(): Boolean =
|
||||||
|
function is PropertyAccessorDescriptor
|
||||||
|
|
||||||
|
override fun hasObjCMethodAnnotation(): Boolean = function.annotations.hasAnnotation(objCMethodFqName)
|
||||||
|
|
||||||
|
override fun hasObjCFactoryAnnotation(): Boolean = function.annotations.hasAnnotation(objCFactoryFqName)
|
||||||
|
|
||||||
|
override fun isObjCClassMethod(): Boolean = function.containingDeclaration.let { it is ClassDescriptor && it.isObjCClass() }
|
||||||
|
|
||||||
|
override fun getValueParameterName(valueParameter: ValueParameterDescriptor): Name = valueParameter.name
|
||||||
|
}
|
||||||
|
|
||||||
|
class IrObjCFunctionNameMangleComputer(private val function: IrFunction) : ObjCFunctionNameMangleComputer<IrValueParameter>() {
|
||||||
|
override fun getObjCMethodInfo(): ObjCMethodInfo? =
|
||||||
|
(if (function is IrConstructor && function.isObjCConstructor) function.getObjCInitMethod() else function)?.getObjCMethodInfo()
|
||||||
|
|
||||||
|
override fun getExtensionReceiverClassName(): Name? =
|
||||||
|
function.extensionReceiverParameter?.run { type.getClass()!!.name }
|
||||||
|
|
||||||
|
override fun isObjCConstructor(): Boolean =
|
||||||
|
function is IrConstructor && function.isObjCConstructor
|
||||||
|
|
||||||
|
override fun isPropertyAccessor(): Boolean =
|
||||||
|
(function as? IrSimpleFunction)?.correspondingPropertySymbol != null
|
||||||
|
|
||||||
|
override fun hasObjCMethodAnnotation(): Boolean = function.hasAnnotation(NativeStandardInteropNames.objCMethodClassId)
|
||||||
|
|
||||||
|
override fun hasObjCFactoryAnnotation(): Boolean = function.hasAnnotation(NativeStandardInteropNames.objCFactoryClassId)
|
||||||
|
|
||||||
|
override fun isObjCClassMethod(): Boolean = function.isObjCClassMethod()
|
||||||
|
|
||||||
|
override fun getValueParameterName(valueParameter: IrValueParameter): Name = valueParameter.name
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user